BeRTOS
hmac.c
Go to the documentation of this file.
00001 
00038 #include "hmac.h"
00039 #include <sec/util.h>
00040 #include <string.h>
00041 
00042 
00043 static void hmac_set_key(Mac *m, const void *key, size_t key_len)
00044 {
00045     HmacContext *ctx = (HmacContext *)m;
00046 
00047     memset(ctx->key, 0, ctx->m.key_len);
00048     if (key_len <= ctx->m.key_len)
00049         memcpy(ctx->key, key, key_len);
00050     else
00051     {
00052         hash_begin(ctx->h);
00053         hash_update(ctx->h, key, key_len);
00054         memcpy(ctx->key, hash_final(ctx->h), hash_digest_len(ctx->h));
00055     }
00056 
00057     xor_block_const(ctx->key, ctx->key, 0x5C, ctx->m.key_len);
00058 }
00059 
00060 static void hmac_begin(Mac *m)
00061 {
00062     HmacContext *ctx = (HmacContext *)m;
00063     int klen = ctx->m.key_len;
00064 
00065     xor_block_const(ctx->key, ctx->key, 0x36^0x5C, klen);
00066     hash_begin(ctx->h);
00067     hash_update(ctx->h, ctx->key, klen);
00068 }
00069 
00070 static void hmac_update(Mac *m, const void *data, size_t len)
00071 {
00072     HmacContext *ctx = (HmacContext *)m;
00073     hash_update(ctx->h, data, len);
00074 }
00075 
00076 static uint8_t *hmac_final(Mac *m)
00077 {
00078     HmacContext *ctx = (HmacContext *)m;
00079     int hlen = hash_digest_len(ctx->h);
00080 
00081     uint8_t temp[hlen];
00082     memcpy(temp, hash_final(ctx->h), hlen);
00083 
00084     xor_block_const(ctx->key, ctx->key, 0x5C^0x36, ctx->m.key_len);
00085     hash_begin(ctx->h);
00086     hash_update(ctx->h, ctx->key, ctx->m.key_len);
00087     hash_update(ctx->h, temp, hlen);
00088 
00089     PURGE(temp);
00090     return hash_final(ctx->h);
00091 }
00092 
00093 /*********************************************************************/
00094 
00095 void hmac_init(HmacContext *ctx, Hash *h)
00096 {
00097     ctx->h = h;
00098     ctx->m.key_len = hash_block_len(h);
00099     ctx->m.digest_len = hash_digest_len(h);
00100     ctx->m.set_key = hmac_set_key;
00101     ctx->m.begin = hmac_begin;
00102     ctx->m.update = hmac_update;
00103     ctx->m.final = hmac_final;
00104     ASSERT(sizeof(ctx->key) >= ctx->m.key_len);
00105 }