No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / hcrypto / hmac.c
blobb8156e38d447bc572e8719cfff88c0a417efc468
1 #include <sys/types.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <hmac.h>
7 void
8 HMAC_CTX_init(HMAC_CTX *ctx)
10 memset(ctx, 0, sizeof(*ctx));
13 void
14 HMAC_CTX_cleanup(HMAC_CTX *ctx)
16 if (ctx->buf) {
17 memset(ctx->buf, 0, ctx->key_length);
18 free(ctx->buf);
19 ctx->buf = NULL;
21 if (ctx->opad) {
22 memset(ctx->ipad, 0, ctx->key_length);
23 free(ctx->opad);
24 ctx->opad = NULL;
26 if (ctx->ipad) {
27 memset(ctx->ipad, 0, ctx->key_length);
28 free(ctx->ipad);
29 ctx->ipad = NULL;
31 if (ctx->ctx) {
32 EVP_MD_CTX_destroy(ctx->ctx);
33 ctx->ctx = NULL;
37 size_t
38 HMAC_size(const HMAC_CTX *ctx)
40 return EVP_MD_size(ctx->md);
43 void
44 HMAC_Init_ex(HMAC_CTX *ctx,
45 const void *key,
46 size_t keylen,
47 const EVP_MD *md,
48 ENGINE *engine)
50 unsigned char *p;
51 size_t i;
53 if (ctx->md != md) {
54 ctx->md = md;
55 if (ctx->buf) {
56 memset(ctx->buf, 0, ctx->key_length);
57 free (ctx->buf);
59 ctx->key_length = EVP_MD_size(ctx->md);
60 ctx->buf = malloc(ctx->key_length);
62 #if 0
63 ctx->engine = engine;
64 #endif
66 if (keylen > EVP_MD_block_size(ctx->md)) {
67 EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine);
68 key = ctx->buf;
69 keylen = EVP_MD_size(ctx->md);
72 if (ctx->opad) {
73 memset(ctx->opad, 0, ctx->key_length);
74 free(ctx->opad);
76 if (ctx->ipad) {
77 memset(ctx->ipad, 0, ctx->key_length);
78 free(ctx->ipad);
81 ctx->opad = malloc(EVP_MD_block_size(ctx->md));
82 ctx->ipad = malloc(EVP_MD_block_size(ctx->md));
83 memset(ctx->ipad, 0x36, EVP_MD_block_size(ctx->md));
84 memset(ctx->opad, 0x5c, EVP_MD_block_size(ctx->md));
86 for (i = 0, p = ctx->ipad; i < keylen; i++)
87 p[i] ^= ((const unsigned char *)key)[i];
88 for (i = 0, p = ctx->opad; i < keylen; i++)
89 p[i] ^= ((const unsigned char *)key)[i];
91 ctx->ctx = EVP_MD_CTX_create();
93 EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
94 EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
97 void
98 HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
100 EVP_DigestUpdate(ctx->ctx, data, len);
103 void
104 HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
106 EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
108 EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
109 EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
110 EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
111 EVP_DigestFinal_ex(ctx->ctx, md, len);
114 void *
115 HMAC(const EVP_MD *md,
116 const void *key, size_t key_size,
117 const void *data, size_t data_size,
118 void *hash, unsigned int *hash_len)
120 HMAC_CTX ctx;
122 HMAC_CTX_init(&ctx);
123 HMAC_Init_ex(&ctx, key, key_size, md, NULL);
124 HMAC_Update(&ctx, data, data_size);
125 HMAC_Final(&ctx, hash, hash_len);
126 HMAC_CTX_cleanup(&ctx);
127 return hash;