static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, unsigned char *seed, int seed_len, unsigned char *out, int olen) { int chunk,n; unsigned int j; HMAC_CTX ctx; HMAC_CTX ctx_tmp; unsigned char A1[EVP_MAX_MD_SIZE]; unsigned int A1_len; chunk=EVP_MD_size(md); HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx_tmp); HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); HMAC_Update(&ctx,seed,seed_len); HMAC_Final(&ctx,A1,&A1_len); n=0; for (;;) { HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */ HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */ HMAC_Update(&ctx,A1,A1_len); HMAC_Update(&ctx_tmp,A1,A1_len); HMAC_Update(&ctx,seed,seed_len); if (olen > chunk) { HMAC_Final(&ctx,out,&j); out+=j; olen-=j; HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */ } else /* last one */ { HMAC_Final(&ctx,A1,&A1_len); memcpy(out,A1,olen); break; } } HMAC_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&ctx_tmp); OPENSSL_cleanse(A1,sizeof(A1)); }
static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { HMAC_PKEY_CTX *hctx = ctx->data; HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT); EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); mctx->update = int_update; return 1; }
static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { HMAC_PKEY_CTX *hctx = ctx->data; HMAC_CTX_set_flags(hctx->ctx, EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT)); EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); EVP_MD_CTX_set_update_fn(mctx, int_update); return 1; }
/** Calculate HMAC using OpenSSL's MD5 implementation * * @param digest Caller digest to be filled in. * @param in Pointer to data stream. * @param inlen length of data stream. * @param key Pointer to authentication key. * @param key_len Length of authentication key. * */ void fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen, uint8_t const *key, size_t key_len) { HMAC_CTX *ctx; if (unlikely(!md5_hmac_ctx)) { ctx = HMAC_CTX_new(); if (unlikely(!ctx)) return; fr_thread_local_set_destructor(md5_hmac_ctx, _hmac_md5_ctx_free_on_exit, ctx); } else { ctx = md5_hmac_ctx; } #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW /* Since MD5 is not allowed by FIPS, explicitly allow it. */ HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); #endif /* EVP_MD_CTX_FLAG_NON_FIPS_ALLOW */ HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL); HMAC_Update(ctx, in, inlen); HMAC_Final(ctx, digest, NULL); HMAC_CTX_reset(ctx); }
USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */ #include "eap_tls.h" #include <openssl/hmac.h> /* * TLS PRF from RFC 2246 */ static void P_hash(EVP_MD const *evp_md, unsigned char const *secret, unsigned int secret_len, unsigned char const *seed, unsigned int seed_len, unsigned char *out, unsigned int out_len) { HMAC_CTX ctx_a, ctx_out; unsigned char a[HMAC_MAX_MD_CBLOCK]; unsigned int size; HMAC_CTX_init(&ctx_a); HMAC_CTX_init(&ctx_out); #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW HMAC_CTX_set_flags(&ctx_a, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); HMAC_CTX_set_flags(&ctx_out, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); #endif HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL); HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL); size = HMAC_size(&ctx_out); /* Calculate A(1) */ HMAC_Update(&ctx_a, seed, seed_len); HMAC_Final(&ctx_a, a, NULL); while (1) { /* Calculate next part of output */ HMAC_Update(&ctx_out, a, size); HMAC_Update(&ctx_out, seed, seed_len); /* Check if last part */ if (out_len < size) { HMAC_Final(&ctx_out, a, NULL); memcpy(out, a, out_len); break; } /* Place digest in output buffer */ HMAC_Final(&ctx_out, out, NULL); HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL); out += size; out_len -= size; /* Calculate next A(i) */ HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL); HMAC_Update(&ctx_a, a, size); HMAC_Final(&ctx_a, a, NULL); } HMAC_CTX_cleanup(&ctx_a); HMAC_CTX_cleanup(&ctx_out); memset(a, 0, sizeof(a)); }