56 |
* Both SHA1 and MD5 algorithms are used. |
* Both SHA1 and MD5 algorithms are used. |
57 |
*/ |
*/ |
58 |
void |
void |
59 |
sec_hash_48(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2, uint8 salt) |
sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt) |
60 |
{ |
{ |
61 |
uint8 shasig[20]; |
uint8 shasig[20]; |
62 |
uint8 pad[4]; |
uint8 pad[4]; |
87 |
* only using a single round of MD5. |
* only using a single round of MD5. |
88 |
*/ |
*/ |
89 |
void |
void |
90 |
sec_hash_16(uint8 *out, uint8 *in, uint8 *salt1, uint8 *salt2) |
sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2) |
91 |
{ |
{ |
92 |
MD5_CTX md5; |
MD5_CTX md5; |
93 |
|
|
100 |
|
|
101 |
/* Reduce key entropy from 64 to 40 bits */ |
/* Reduce key entropy from 64 to 40 bits */ |
102 |
static void |
static void |
103 |
sec_make_40bit(uint8 *key) |
sec_make_40bit(uint8 * key) |
104 |
{ |
{ |
105 |
key[0] = 0xd1; |
key[0] = 0xd1; |
106 |
key[1] = 0x26; |
key[1] = 0x26; |
109 |
|
|
110 |
/* Generate a session key and RC4 keys, given client and server randoms */ |
/* Generate a session key and RC4 keys, given client and server randoms */ |
111 |
static void |
static void |
112 |
sec_generate_keys(uint8 *client_key, uint8 *server_key, int rc4_key_size) |
sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size) |
113 |
{ |
{ |
114 |
uint8 session_key[48]; |
uint8 session_key[48]; |
115 |
uint8 temp_hash[48]; |
uint8 temp_hash[48]; |
171 |
|
|
172 |
/* Output a uint32 into a buffer (little-endian) */ |
/* Output a uint32 into a buffer (little-endian) */ |
173 |
void |
void |
174 |
buf_out_uint32(uint8 *buffer, uint32 value) |
buf_out_uint32(uint8 * buffer, uint32 value) |
175 |
{ |
{ |
176 |
buffer[0] = (value) & 0xff; |
buffer[0] = (value) & 0xff; |
177 |
buffer[1] = (value >> 8) & 0xff; |
buffer[1] = (value >> 8) & 0xff; |
181 |
|
|
182 |
/* Generate a signature hash, using a combination of SHA1 and MD5 */ |
/* Generate a signature hash, using a combination of SHA1 and MD5 */ |
183 |
void |
void |
184 |
sec_sign(uint8 *signature, int siglen, uint8 *session_key, int keylen, |
sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, |
185 |
uint8 *data, int datalen) |
uint8 * data, int datalen) |
186 |
{ |
{ |
187 |
uint8 shasig[20]; |
uint8 shasig[20]; |
188 |
uint8 md5sig[16]; |
uint8 md5sig[16]; |
210 |
|
|
211 |
/* Update an encryption key - similar to the signing process */ |
/* Update an encryption key - similar to the signing process */ |
212 |
static void |
static void |
213 |
sec_update(uint8 *key, uint8 *update_key) |
sec_update(uint8 * key, uint8 * update_key) |
214 |
{ |
{ |
215 |
uint8 shasig[20]; |
uint8 shasig[20]; |
216 |
SHA_CTX sha; |
SHA_CTX sha; |
238 |
|
|
239 |
/* Encrypt data using RC4 */ |
/* Encrypt data using RC4 */ |
240 |
static void |
static void |
241 |
sec_encrypt(uint8 *data, int length) |
sec_encrypt(uint8 * data, int length) |
242 |
{ |
{ |
243 |
static int use_count; |
static int use_count; |
244 |
|
|
255 |
|
|
256 |
/* Decrypt data using RC4 */ |
/* Decrypt data using RC4 */ |
257 |
static void |
static void |
258 |
sec_decrypt(uint8 *data, int length) |
sec_decrypt(uint8 * data, int length) |
259 |
{ |
{ |
260 |
static int use_count; |
static int use_count; |
261 |
|
|
271 |
} |
} |
272 |
|
|
273 |
static void |
static void |
274 |
reverse(uint8 *p, int len) |
reverse(uint8 * p, int len) |
275 |
{ |
{ |
276 |
int i, j; |
int i, j; |
277 |
uint8 temp; |
uint8 temp; |
278 |
|
|
279 |
for (i = 0, j = len-1; i < j; i++, j--) |
for (i = 0, j = len - 1; i < j; i++, j--) |
280 |
{ |
{ |
281 |
temp = p[i]; |
temp = p[i]; |
282 |
p[i] = p[j]; |
p[i] = p[j]; |
286 |
|
|
287 |
/* Perform an RSA public key encryption operation */ |
/* Perform an RSA public key encryption operation */ |
288 |
static void |
static void |
289 |
sec_rsa_encrypt(uint8 *out, uint8 *in, int len, |
sec_rsa_encrypt(uint8 * out, uint8 * in, int len, |
290 |
uint8 *modulus, uint8 *exponent) |
uint8 * modulus, uint8 * exponent) |
291 |
{ |
{ |
292 |
BN_CTX ctx; |
BN_CTX ctx; |
293 |
BIGNUM mod, exp, x, y; |
BIGNUM mod, exp, x, y; |
312 |
outlen = BN_bn2bin(&y, out); |
outlen = BN_bn2bin(&y, out); |
313 |
reverse(out, outlen); |
reverse(out, outlen); |
314 |
if (outlen < SEC_MODULUS_SIZE) |
if (outlen < SEC_MODULUS_SIZE) |
315 |
memset(out+outlen, 0, SEC_MODULUS_SIZE-outlen); |
memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen); |
316 |
|
|
317 |
BN_free(&y); |
BN_free(&y); |
318 |
BN_clear_free(&x); |
BN_clear_free(&x); |
358 |
hexdump(s->p + 8, datalen); |
hexdump(s->p + 8, datalen); |
359 |
#endif |
#endif |
360 |
|
|
361 |
sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, datalen); |
sec_sign(s->p, 8, sec_sign_key, rc4_key_len, s->p + 8, |
362 |
|
datalen); |
363 |
sec_encrypt(s->p + 8, datalen); |
sec_encrypt(s->p + 8, datalen); |
364 |
} |
} |
365 |
|
|
439 |
|
|
440 |
/* Parse a public key structure */ |
/* Parse a public key structure */ |
441 |
static BOOL |
static BOOL |
442 |
sec_parse_public_key(STREAM s, uint8 **modulus, uint8 **exponent) |
sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent) |
443 |
{ |
{ |
444 |
uint32 magic, modulus_len; |
uint32 magic, modulus_len; |
445 |
|
|
467 |
|
|
468 |
/* Parse a crypto information structure */ |
/* Parse a crypto information structure */ |
469 |
static BOOL |
static BOOL |
470 |
sec_parse_crypt_info(STREAM s, uint32 *rc4_key_size, |
sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size, |
471 |
uint8 **server_random, uint8 **modulus, uint8 **exponent) |
uint8 ** server_random, uint8 ** modulus, |
472 |
|
uint8 ** exponent) |
473 |
{ |
{ |
474 |
uint32 crypt_level, random_len, rsa_info_len; |
uint32 crypt_level, random_len, rsa_info_len; |
475 |
uint16 tag, length; |
uint16 tag, length; |