-void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
- const EVP_MD *md)
- {
- int i,j,reset=0;
- unsigned char pad[HMAC_MAX_MD_CBLOCK];
-
- if (md != NULL)
- {
- reset=1;
- ctx->md=md;
- }
- else
- md=ctx->md;
-
- if (key != NULL)
- {
- reset=1;
- j=EVP_MD_block_size(md);
- if (j < len)
- {
- EVP_DigestInit(&ctx->md_ctx,md);
- EVP_DigestUpdate(&ctx->md_ctx,key,len);
- EVP_DigestFinal(&(ctx->md_ctx),ctx->key,
- &ctx->key_length);
- }
- else
- {
- memcpy(ctx->key,key,len);
- memset(&(ctx->key[len]),0,sizeof(ctx->key)-len);
- ctx->key_length=len;
- }
- }
-
- if (reset)
- {
- for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
- pad[i]=0x36^ctx->key[i];
- EVP_DigestInit(&ctx->i_ctx,md);
- EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md));
-
- for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
- pad[i]=0x5c^ctx->key[i];
- EVP_DigestInit(&ctx->o_ctx,md);
- EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md));
- }
-
- memcpy(&ctx->md_ctx,&ctx->i_ctx,sizeof(ctx->i_ctx));
- }
-
-void HMAC_Update(HMAC_CTX *ctx, unsigned char *data, int len)
- {
- EVP_DigestUpdate(&(ctx->md_ctx),data,len);
- }
-
-void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
- {
- int j;
- unsigned int i;
- unsigned char buf[EVP_MAX_MD_SIZE];
-
- j=EVP_MD_block_size(ctx->md);
-
- EVP_DigestFinal(&(ctx->md_ctx),buf,&i);
- memcpy(&(ctx->md_ctx),&(ctx->o_ctx),sizeof(ctx->o_ctx));
- EVP_DigestUpdate(&(ctx->md_ctx),buf,i);
- EVP_DigestFinal(&(ctx->md_ctx),md,len);
- }
-
-void HMAC_cleanup(HMAC_CTX *ctx)
- {
- memset(ctx,0,sizeof(HMAC_CTX));
- }
+#ifndef OPENSSL_NO_DEPRECATED
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
+{
+ if (key && md)
+ HMAC_CTX_reset(ctx);
+ return HMAC_Init_ex(ctx, key, len, md, NULL);
+}
+#endif
+
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+{
+ if (!ctx->md)
+ return 0;
+ return EVP_DigestUpdate(ctx->md_ctx, data, len);
+}
+
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+{
+ unsigned int i;
+ unsigned char buf[EVP_MAX_MD_SIZE];
+
+ if (!ctx->md)
+ goto err;
+
+ if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i))
+ goto err;
+ if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx))
+ goto err;
+ if (!EVP_DigestUpdate(ctx->md_ctx, buf, i))
+ goto err;
+ if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len))
+ goto err;
+ return 1;
+ err:
+ return 0;
+}
+
+size_t HMAC_size(HMAC_CTX *ctx)
+{
+ return EVP_MD_size((ctx)->md);
+}
+
+HMAC_CTX *HMAC_CTX_new(void)
+{
+ HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_zalloc(sizeof(HMAC_CTX));
+ if (ctx)
+ if (!HMAC_CTX_reset(ctx)) {
+ HMAC_CTX_free(ctx);
+ ctx = NULL;
+ }
+ return ctx;
+}
+
+static void hmac_ctx_cleanup(HMAC_CTX *ctx)
+{
+ EVP_MD_CTX_reset(ctx->i_ctx);
+ EVP_MD_CTX_reset(ctx->o_ctx);
+ EVP_MD_CTX_reset(ctx->md_ctx);
+ ctx->md = NULL;
+ ctx->key_length = 0;
+ memset(ctx->key, 0, sizeof(HMAC_MAX_MD_CBLOCK));
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+ if (ctx != NULL) {
+ hmac_ctx_cleanup(ctx);
+ EVP_MD_CTX_free(ctx->i_ctx);
+ EVP_MD_CTX_free(ctx->o_ctx);
+ EVP_MD_CTX_free(ctx->md_ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+int HMAC_CTX_reset(HMAC_CTX *ctx)
+{
+ hmac_ctx_cleanup(ctx);
+ if (ctx->i_ctx == NULL)
+ ctx->i_ctx = EVP_MD_CTX_new();
+ if (ctx->i_ctx == NULL)
+ goto err;
+ if (ctx->o_ctx == NULL)
+ ctx->o_ctx = EVP_MD_CTX_new();
+ if (ctx->o_ctx == NULL)
+ goto err;
+ if (ctx->md_ctx == NULL)
+ ctx->md_ctx = EVP_MD_CTX_new();
+ if (ctx->md_ctx == NULL)
+ goto err;
+ ctx->md = NULL;
+ return 1;
+ err:
+ hmac_ctx_cleanup(ctx);
+ return 0;
+}
+
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
+{
+ if (!HMAC_CTX_reset(dctx))
+ goto err;
+ if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx))
+ goto err;
+ if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx))
+ goto err;
+ if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx))
+ goto err;
+ memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
+ dctx->key_length = sctx->key_length;
+ dctx->md = sctx->md;
+ return 1;
+ err:
+ hmac_ctx_cleanup(dctx);
+ return 0;
+}