lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright (c) Tim Hockin, Cobalt Networks Inc. and others |
| 3 | * |
| 4 | * crypto routines used by multiple c files |
| 5 | */ |
| 6 | #include <stdio.h> |
| 7 | #include <ctype.h> |
| 8 | #include <stdlib.h> |
| 9 | #include <unistd.h> |
| 10 | #include <string.h> |
| 11 | #include "extra_crypto.h" |
| 12 | #include "pppd.h" |
| 13 | #include "md4.h" |
| 14 | #ifndef USE_CRYPT |
| 15 | #include <des.h> |
| 16 | #endif |
| 17 | |
| 18 | /* quick wrapper for easy md4 */ |
| 19 | void |
| 20 | md4(unsigned char *from, int from_len, unsigned char *to) |
| 21 | { |
| 22 | MD4_CTX Context; |
| 23 | |
| 24 | #ifndef __NetBSD__ |
| 25 | from_len <<= 3; /* bytes->bits */ |
| 26 | #endif |
| 27 | |
| 28 | MD4Init(&Context); |
| 29 | MD4Update(&Context, from, from_len); |
| 30 | MD4Final(to, &Context); |
| 31 | } |
| 32 | |
| 33 | |
| 34 | /* Microsoft LANMAN Password hashing */ |
| 35 | static u_char *MSStdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ |
| 36 | |
| 37 | void |
| 38 | LmPasswordHash(char *password, int len, char *hash) |
| 39 | { |
| 40 | int i; |
| 41 | u_char up_pass[MAX_NT_PASSWORD]; /* max is actually 14 */ |
| 42 | |
| 43 | /* LANMan password is case insensitive */ |
| 44 | BZERO(up_pass, sizeof(up_pass)); |
| 45 | for (i = 0; i < len; i++) |
| 46 | up_pass[i] = (u_char)toupper(up_pass[i]); |
| 47 | DesEncrypt(MSStdText, up_pass + 0, hash + 0); |
| 48 | DesEncrypt(MSStdText, up_pass + 7, hash + 8); |
| 49 | } |
| 50 | |
| 51 | void |
| 52 | NtPasswordHash(char *secret, int secret_len, unsigned char *hash) |
| 53 | { |
| 54 | int i; |
| 55 | u_char unicodePassword[MAX_NT_PASSWORD * 2]; |
| 56 | |
| 57 | /* Initialize the Unicode version of the secret (== password). */ |
| 58 | /* This implicitly supports 8-bit ISO8859/1 characters. */ |
| 59 | BZERO(unicodePassword, sizeof(unicodePassword)); |
| 60 | for (i = 0; i < secret_len; i++) |
| 61 | unicodePassword[i * 2] = (u_char)secret[i]; |
| 62 | |
| 63 | /* Unicode is 2 bytes per char */ |
| 64 | md4(unicodePassword, secret_len * 2, hash); |
| 65 | } |
| 66 | |
| 67 | |
| 68 | static u_char Get7Bits(unsigned char *input, int startBit) |
| 69 | { |
| 70 | register unsigned int word; |
| 71 | |
| 72 | word = (unsigned)input[startBit / 8] << 8; |
| 73 | word |= (unsigned)input[startBit / 8 + 1]; |
| 74 | |
| 75 | word >>= 15 - (startBit % 8 + 7); |
| 76 | |
| 77 | return word & 0xFE; |
| 78 | } |
| 79 | |
| 80 | |
| 81 | static void MakeKey(unsigned char *key, unsigned char *des_key) |
| 82 | { |
| 83 | des_key[0] = Get7Bits(key, 0); |
| 84 | des_key[1] = Get7Bits(key, 7); |
| 85 | des_key[2] = Get7Bits(key, 14); |
| 86 | des_key[3] = Get7Bits(key, 21); |
| 87 | des_key[4] = Get7Bits(key, 28); |
| 88 | des_key[5] = Get7Bits(key, 35); |
| 89 | des_key[6] = Get7Bits(key, 42); |
| 90 | des_key[7] = Get7Bits(key, 49); |
| 91 | |
| 92 | #ifndef USE_CRYPT |
| 93 | des_set_odd_parity((des_cblock *)des_key); |
| 94 | #endif |
| 95 | } |
| 96 | |
| 97 | |
| 98 | #ifdef USE_CRYPT |
| 99 | /* in == 8-byte string (expanded version of the 56-bit key) |
| 100 | * out == 64-byte string where each byte is either 1 or 0 |
| 101 | * Note that the low-order "bit" is always ignored by by setkey() |
| 102 | */ |
| 103 | static void Expand(unsigned char *in, unsigned char *out) |
| 104 | { |
| 105 | int j, c; |
| 106 | int i; |
| 107 | |
| 108 | for(i = 0; i < 64; in++){ |
| 109 | c = *in; |
| 110 | for(j = 7; j >= 0; j--) |
| 111 | *out++ = (c >> j) & 01; |
| 112 | i += 8; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | /* The inverse of Expand |
| 117 | */ |
| 118 | static void Collapse(unsigned char *in, unsigned char *out) |
| 119 | { |
| 120 | int j; |
| 121 | int i; |
| 122 | unsigned int c; |
| 123 | |
| 124 | for (i = 0; i < 64; i += 8, out++) { |
| 125 | c = 0; |
| 126 | for (j = 7; j >= 0; j--, in++) |
| 127 | c |= *in << j; |
| 128 | *out = c & 0xff; |
| 129 | } |
| 130 | } |
| 131 | void |
| 132 | DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher) |
| 133 | { |
| 134 | u_char des_key[8]; |
| 135 | u_char crypt_key[66]; |
| 136 | u_char des_input[66]; |
| 137 | |
| 138 | MakeKey(key, des_key); |
| 139 | |
| 140 | Expand(des_key, crypt_key); |
| 141 | setkey(crypt_key); |
| 142 | |
| 143 | Expand(clear, des_input); |
| 144 | encrypt(des_input, 0); |
| 145 | Collapse(des_input, cipher); |
| 146 | } |
| 147 | #else /* don't USE_CRYPT */ |
| 148 | void |
| 149 | DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher) |
| 150 | { |
| 151 | des_cblock des_key; |
| 152 | des_key_schedule key_schedule; |
| 153 | |
| 154 | MakeKey(key, des_key); |
| 155 | |
| 156 | des_set_key(&des_key, key_schedule); |
| 157 | |
| 158 | des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); |
| 159 | } |
| 160 | #endif /* USE_CRYPT */ |
| 161 | |
| 162 | |