]> git.cryptolib.org Git - arm-crypto-lib.git/blob - hfal/hfal-hmac.c
6f5fbf9bc7c32ae546b9f4fce960ffca70a2d43e
[arm-crypto-lib.git] / hfal / hfal-hmac.c
1 /* hfal-hmac.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "hashfunction_descriptor.h"
21 #include "hfal-basic.h"
22 #include "hfal-hmac.h"
23 #include <stdlib.h>
24 #include <string.h>
25
26 #define IPAD 0x36
27 #define OPAD 0x5C
28
29 uint8_t hfal_hmac_init(const hfdesc_t* hash_descriptor, 
30                        hfhmacgen_ctx_t* ctx, 
31                                            const void* key, uint16_t keylength_b){
32         uint16_t  bs = hfal_hash_getBlocksize(hash_descriptor);
33         uint8_t buffer[bs/8];
34         uint8_t i;
35         hf_init_fpt init;
36         hf_nextBlock_fpt nextBlock;
37         memset(buffer, 0, bs/8);
38         ctx->desc   = hash_descriptor;
39         ctx->ctx    = malloc(hash_descriptor->ctxsize_B);
40         ctx->finctx = malloc(hash_descriptor->ctxsize_B);
41         if(ctx->ctx==NULL && ctx->finctx==NULL)
42                 return 3;
43         if(ctx->finctx==NULL){
44                 free(ctx->ctx);
45                 return 2;
46         }
47         if(ctx->ctx==NULL){
48                 free(ctx->finctx);
49                 return 1;
50         }               
51         if(keylength_b>bs){
52                 hfal_hash_mem(hash_descriptor, buffer, key, keylength_b);
53         } else {
54                 memcpy(buffer, key, (keylength_b+7)/8);
55         }
56         for(i=0; i<bs/8; ++i){
57                 buffer[i] ^= IPAD;
58         }
59         init = hash_descriptor->init;
60         nextBlock = hash_descriptor->nextBlock;
61         init(ctx->ctx);
62         init(ctx->finctx);
63         nextBlock(ctx->ctx, buffer);
64         for(i=0; i<bs/8; ++i){
65                 buffer[i] ^= IPAD^OPAD;
66         }
67         nextBlock(ctx->finctx, buffer);
68         memset(buffer, 0, bs/8);
69         return 0;
70 }
71
72 uint8_t hfal_hmac_ctxcopy(hfhmacgen_ctx_t* dest, hfhmacgen_ctx_t* src){
73         dest->desc = src->desc;
74         dest->ctx = malloc(dest->desc->ctxsize_B);
75         if(dest->ctx == NULL){
76                 return 1;
77         }
78         memcpy(dest->ctx, src->ctx, dest->desc->ctxsize_B);
79         dest->finctx = malloc(dest->desc->ctxsize_B);
80         if(dest->finctx == NULL){
81                 return 1;
82         }
83         memcpy(dest->finctx, src->finctx, dest->desc->ctxsize_B);
84         return 0;
85 }
86
87 void hfal_hmac_nextBlock(hfhmacgen_ctx_t* ctx, const void* block){
88         ctx->desc->nextBlock(ctx->ctx, block);
89 }
90
91 void hfal_hmac_lastBlock(hfhmacgen_ctx_t* ctx, const void* block, uint16_t length_b){
92         hf_lastBlock_fpt lastBlock;
93         hf_ctx2hash_fpt  ctx2hash;
94         uint16_t hs = ctx->desc->hashsize_b;
95         uint8_t buffer[(hs+7)/8];
96         lastBlock = ctx->desc->lastBlock;
97         ctx2hash = ctx->desc->ctx2hash;
98         lastBlock(ctx->ctx, block, length_b);
99         ctx2hash(buffer, ctx->ctx);
100         lastBlock(ctx->finctx, buffer, hs);
101 }
102
103 void hfal_hmac_ctx2mac(void* dest, hfhmacgen_ctx_t* ctx){
104         hf_ctx2hash_fpt  ctx2hash;
105         ctx2hash = ctx->desc->ctx2hash;
106         ctx2hash(dest, ctx->finctx);
107 }
108
109 void hfal_hmac_free(hfhmacgen_ctx_t* ctx){
110         hf_free_fpt free_fpt;
111         free_fpt = ctx->desc->free;
112         if(free_fpt){
113                 free_fpt(ctx->ctx);
114                 free_fpt(ctx->finctx);
115         }
116         free(ctx->ctx);
117         free(ctx->finctx);
118 }
119
120 void hfal_hmac_mem(const hfdesc_t* hash_descriptor, const void* key, uint16_t keylength_b, void* dest, const void* msg, uint32_t length_b){
121         hfhmacgen_ctx_t ctx;
122         uint16_t  bs = hfal_hash_getBlocksize(hash_descriptor);
123         hfal_hmac_init(hash_descriptor, &ctx, key, keylength_b);
124         while(length_b>bs){
125                 hfal_hmac_nextBlock(&ctx, msg);
126                 msg = (uint8_t*)msg + bs/8;
127                 length_b-=bs;
128         }
129         hfal_hmac_lastBlock(&ctx, msg, length_b);
130         hfal_hmac_ctx2mac(dest, &ctx);
131         hfal_hmac_free(&ctx);
132 }
133
134 uint16_t hfal_hmac_getBlocksize(const hfdesc_t* hash_descriptor){
135         return hfal_hash_getBlocksize(hash_descriptor);
136 }
137
138 uint16_t hfal_hmac_getMACsize(const hfdesc_t* hash_descriptor){
139         return hfal_hash_getHashsize(hash_descriptor);
140 }
141
142