BeRTOS
|
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 }