/* * Key material generation */ int tls1_prf( unsigned char *secret, size_t slen, char *label, unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ) { size_t nb, hs; size_t i, j, k; unsigned char *S1, *S2; unsigned char tmp[128]; unsigned char h_i[20]; if( sizeof( tmp ) < 20 + strlen( label ) + rlen ) return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); hs = ( slen + 1 ) / 2; S1 = secret; S2 = secret + slen - hs; nb = strlen( label ); memcpy( tmp + 20, label, nb ); memcpy( tmp + 20 + nb, random, rlen ); nb += rlen; /* * First compute P_md5(secret,label+random)[0..dlen] */ md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp ); for( i = 0; i < dlen; i += 16 ) { md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i ); md5_hmac( S1, hs, 4 + tmp, 16, 4 + tmp ); k = ( i + 16 > dlen ) ? dlen % 16 : 16; for( j = 0; j < k; j++ ) dstbuf[i + j] = h_i[j]; } /* * XOR out with P_sha1(secret,label+random)[0..dlen] */ sha1_hmac( S2, hs, tmp + 20, nb, tmp ); for( i = 0; i < dlen; i += 20 ) { sha1_hmac( S2, hs, tmp, 20 + nb, h_i ); sha1_hmac( S2, hs, tmp, 20, tmp ); k = ( i + 20 > dlen ) ? dlen % 20 : 20; for( j = 0; j < k; j++ ) dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); } memset( tmp, 0, sizeof( tmp ) ); memset( h_i, 0, sizeof( h_i ) ); return( 0 ); }
static size_t md5_hmac_sig(const char *token, size_t token_size, char *sig) { md5_hmac((const unsigned char *)secret, sizeof(secret) - 1, (const unsigned char *)token, token_size, (unsigned char *)sig); return 16; }
static void md5_hex_hmac(char *hexdigest, const unsigned char* text, int text_len, const unsigned char* key, int key_len) { unsigned char digest[16]; int i; md5_hmac(digest, text, text_len, key, key_len); for (i = 0; i < 16; i++) sprintf(hexdigest + 2 * i, "%02x", digest[i]); }
void get_signature(const char *datetime, const char *salt, const char * api_secret, char *output) { unsigned char signature[16]; char data_unsigned[64]; char * hash_data; hash_data = (char*)malloc(strlen(datetime)+strlen(salt)+1); /*hash ¿¹¿Üó¸®*/ sprintf(data_unsigned, "%s%s", datetime, salt); md5_hmac((unsigned char*)api_secret, strlen(api_secret), (unsigned char*)data_unsigned, strlen(data_unsigned), signature); for (int i = 0; i < sizeof(signature); i++) { sprintf(&output[i*2], "%02x", signature[i]); } }
static int ssl_decrypt_buf(ssl_context * ssl) { size_t i, padlen; uint8_t tmp[20]; SSL_DEBUG_MSG(2, ("=> decrypt buf")); if (ssl->in_msglen < ssl->minlen) { SSL_DEBUG_MSG(1, ("in_msglen (%d) < minlen (%d)", ssl->in_msglen, ssl->minlen)); return (TROPICSSL_ERR_SSL_INVALID_MAC); } if (ssl->ivlen == 0) { #if defined(TROPICSSL_ARC4) padlen = 0; arc4_crypt((arc4_context *) ssl->ctx_dec, ssl->in_msg, ssl->in_msglen); #else return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE); #endif } else { /* * Decrypt and check the padding */ if (ssl->in_msglen % ssl->ivlen != 0) { SSL_DEBUG_MSG(1, ("msglen (%d) %% ivlen (%d) != 0", ssl->in_msglen, ssl->ivlen)); return (TROPICSSL_ERR_SSL_INVALID_MAC); } switch (ssl->ivlen) { #if defined(TROPICSSL_DES) case 8: des3_crypt_cbc((des3_context *) ssl->ctx_dec, DES_DECRYPT, ssl->in_msglen, ssl->iv_dec, ssl->in_msg, ssl->in_msg); break; #endif case 16: #if defined(TROPICSSL_AES) if (ssl->session->cipher == TLS_RSA_WITH_AES_128_CBC_SHA || ssl->session->cipher == TLS_RSA_WITH_AES_256_CBC_SHA || ssl->session->cipher == TLS_DHE_RSA_WITH_AES_256_CBC_SHA) { aes_crypt_cbc((aes_context *) ssl->ctx_dec, AES_DECRYPT, ssl->in_msglen, ssl->iv_dec, ssl->in_msg, ssl->in_msg); break; } #endif #if defined(TROPICSSL_CAMELLIA) if (ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA || ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA || ssl->session->cipher == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA) { camellia_crypt_cbc((camellia_context *) ssl->ctx_dec, CAMELLIA_DECRYPT, ssl->in_msglen, ssl->iv_dec, ssl->in_msg, ssl->in_msg); break; } #endif default: return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE); } padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; if (ssl->minor_ver == SSL_MINOR_VERSION_0) { if (padlen > ssl->ivlen) { SSL_DEBUG_MSG(1, ("bad padding length: is %d, " "should be no more than %d", padlen, ssl->ivlen)); padlen = 0; } } else { /* * TLSv1: always check the padding */ for (i = 1; i <= padlen; i++) { if (ssl->in_msg[ssl->in_msglen - i] != padlen - 1) { SSL_DEBUG_MSG(1, ("bad padding byte: should be " "%02x, but is %02x", padlen - 1, ssl-> in_msg[ssl->in_msglen - i])); padlen = 0; } } } } SSL_DEBUG_BUF(4, "raw buffer after decryption", ssl->in_msg, ssl->in_msglen); /* * Always compute the MAC (RFC4346, CBCTIME). */ ssl->in_msglen -= (ssl->maclen + padlen); ssl->in_hdr[3] = (uint8_t)(ssl->in_msglen >> 8); ssl->in_hdr[4] = (uint8_t)(ssl->in_msglen); memcpy(tmp, ssl->in_msg + ssl->in_msglen, 20); if (ssl->minor_ver == SSL_MINOR_VERSION_0) { if (ssl->maclen == 16) ssl_mac_md5(ssl->mac_dec, ssl->in_msg, ssl->in_msglen, ssl->in_ctr, ssl->in_msgtype); else ssl_mac_sha1(ssl->mac_dec, ssl->in_msg, ssl->in_msglen, ssl->in_ctr, ssl->in_msgtype); } else { if (ssl->maclen == 16) md5_hmac(ssl->mac_dec, 16, ssl->in_ctr, ssl->in_msglen + 13, ssl->in_msg + ssl->in_msglen); else sha1_hmac(ssl->mac_dec, 20, ssl->in_ctr, ssl->in_msglen + 13, ssl->in_msg + ssl->in_msglen); } SSL_DEBUG_BUF(4, "message mac", tmp, ssl->maclen); SSL_DEBUG_BUF(4, "computed mac", ssl->in_msg + ssl->in_msglen, ssl->maclen); if (memcmp(tmp, ssl->in_msg + ssl->in_msglen, ssl->maclen) != 0) { SSL_DEBUG_MSG(1, ("message mac does not match")); return (TROPICSSL_ERR_SSL_INVALID_MAC); } /* * Finally check the padding length; bad padding * will produce the same error as an invalid MAC. */ if (ssl->ivlen != 0 && padlen == 0) return (TROPICSSL_ERR_SSL_INVALID_MAC); if (ssl->in_msglen == 0) { ssl->nb_zero++; /* * Three or more empty messages may be a DoS attack * (excessive CPU consumption). */ if (ssl->nb_zero > 3) { SSL_DEBUG_MSG(1, ("received four consecutive empty " "messages, possible DoS attack")); return (TROPICSSL_ERR_SSL_INVALID_MAC); } } else ssl->nb_zero = 0; for (i = 7; i >= 0; i--) if (++ssl->in_ctr[i] != 0) break; SSL_DEBUG_MSG(2, ("<= decrypt buf")); return (0); }
/* * Encryption/decryption functions */ static int ssl_encrypt_buf(ssl_context * ssl) { size_t i, padlen; SSL_DEBUG_MSG(2, ("=> encrypt buf")); /* * Add MAC then encrypt */ if (ssl->minor_ver == SSL_MINOR_VERSION_0) { if (ssl->maclen == 16) ssl_mac_md5(ssl->mac_enc, ssl->out_msg, ssl->out_msglen, ssl->out_ctr, ssl->out_msgtype); if (ssl->maclen == 20) ssl_mac_sha1(ssl->mac_enc, ssl->out_msg, ssl->out_msglen, ssl->out_ctr, ssl->out_msgtype); } else { if (ssl->maclen == 16) md5_hmac(ssl->mac_enc, 16, ssl->out_ctr, ssl->out_msglen + 13, ssl->out_msg + ssl->out_msglen); if (ssl->maclen == 20) sha1_hmac(ssl->mac_enc, 20, ssl->out_ctr, ssl->out_msglen + 13, ssl->out_msg + ssl->out_msglen); } SSL_DEBUG_BUF(4, "computed mac", ssl->out_msg + ssl->out_msglen, ssl->maclen); ssl->out_msglen += ssl->maclen; for (i = 7; i >= 0; i--) if (++ssl->out_ctr[i] != 0) break; if (ssl->ivlen == 0) { #if defined(TROPICSSL_ARC4) padlen = 0; SSL_DEBUG_MSG(3, ("before encrypt: msglen = %d, " "including %d bytes of padding", ssl->out_msglen, 0)); SSL_DEBUG_BUF(4, "before encrypt: output payload", ssl->out_msg, ssl->out_msglen); arc4_crypt((arc4_context *) ssl->ctx_enc, ssl->out_msg, ssl->out_msglen); #else return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE); #endif } else { padlen = ssl->ivlen - (ssl->out_msglen + 1) % ssl->ivlen; if (padlen == ssl->ivlen) padlen = 0; for (i = 0; i <= padlen; i++) ssl->out_msg[ssl->out_msglen + i] = (uint8_t)padlen; ssl->out_msglen += padlen + 1; SSL_DEBUG_MSG(3, ("before encrypt: msglen = %d, " "including %d bytes of padding", ssl->out_msglen, padlen + 1)); SSL_DEBUG_BUF(4, "before encrypt: output payload", ssl->out_msg, ssl->out_msglen); switch (ssl->ivlen) { case 8: #if defined(TROPICSSL_DES) des3_crypt_cbc((des3_context *) ssl->ctx_enc, DES_ENCRYPT, ssl->out_msglen, ssl->iv_enc, ssl->out_msg, ssl->out_msg); break; #endif case 16: #if defined(TROPICSSL_AES) if (ssl->session->cipher == TLS_RSA_WITH_AES_128_CBC_SHA || ssl->session->cipher == TLS_RSA_WITH_AES_256_CBC_SHA || ssl->session->cipher == TLS_DHE_RSA_WITH_AES_256_CBC_SHA) { aes_crypt_cbc((aes_context *) ssl->ctx_enc, AES_ENCRYPT, ssl->out_msglen, ssl->iv_enc, ssl->out_msg, ssl->out_msg); break; } #endif #if defined(TROPICSSL_CAMELLIA) if (ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA || ssl->session->cipher == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA || ssl->session->cipher == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA) { camellia_crypt_cbc((camellia_context *) ssl->ctx_enc, CAMELLIA_ENCRYPT, ssl->out_msglen, ssl->iv_enc, ssl->out_msg, ssl->out_msg); break; } #endif default: return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE); } } SSL_DEBUG_MSG(2, ("<= encrypt buf")); return (0); }
uint Md5Hmac::GetDigest(void* digest16,const void* data,uint len,const void* key,uint klen){ md5_hmac((byte*)key,klen,(byte*)data,len,(byte*)digest16); return 16; }
void MD5::compute(const unsigned char* key, int keylen, const unsigned char* input, int ilen, unsigned char output[] ) { md5_hmac(key,keylen,input,ilen,output); }