c3d2ba403a1ceb06e094381b6929e23684352027
[sfrench/samba-autobuild/.git] / source4 / lib / crypto / hmacsha1.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Interface header:    HMAC SHA-1 code
4    Copyright (C) Stefan Metzmacher
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*
22  taken direct from rfc2202 implementation and modified for suitable use
23  */
24
25 #include "includes.h"
26 #include "lib/crypto/crypto.h"
27
28 /***********************************************************************
29  the rfc 2104/2202 version of hmac_sha1 initialisation.
30 ***********************************************************************/
31 _PUBLIC_ void hmac_sha1_init(const uint8_t *key, size_t key_len, struct HMACSHA1Context *ctx)
32 {
33         int i;
34         uint8_t tk[SHA1HashSize];
35
36         /* if key is longer than 64 bytes reset it to key=MD5(key) */
37         if (key_len > 64)
38         {
39                 struct SHA1Context tctx;
40
41                 SHA1Init(&tctx);
42                 SHA1Update(&tctx, key, key_len);
43                 SHA1Final(tk, &tctx);
44
45                 key = tk;
46                 key_len = SHA1HashSize;
47         }
48
49         /* start out by storing key in pads */
50         ZERO_STRUCT(ctx->k_ipad);
51         ZERO_STRUCT(ctx->k_opad);
52         memcpy( ctx->k_ipad, key, key_len);
53         memcpy( ctx->k_opad, key, key_len);
54
55         /* XOR key with ipad and opad values */
56         for (i=0; i<64; i++)
57         {
58                 ctx->k_ipad[i] ^= 0x36;
59                 ctx->k_opad[i] ^= 0x5c;
60         }
61
62         SHA1Init(&ctx->ctx);
63         SHA1Update(&ctx->ctx, ctx->k_ipad, 64);  
64 }
65
66 /***********************************************************************
67  update hmac_sha1 "inner" buffer
68 ***********************************************************************/
69 _PUBLIC_ void hmac_sha1_update(const uint8_t *data, size_t data_len, struct HMACSHA1Context *ctx)
70 {
71         SHA1Update(&ctx->ctx, data, data_len); /* then text of datagram */
72 }
73
74 /***********************************************************************
75  finish off hmac_sha1 "inner" buffer and generate outer one.
76 ***********************************************************************/
77 _PUBLIC_ void hmac_sha1_final(uint8_t digest[SHA1HashSize], struct HMACSHA1Context *ctx)
78 {
79         struct SHA1Context ctx_o;
80
81         SHA1Final(digest, &ctx->ctx);
82
83         SHA1Init(&ctx_o);
84         SHA1Update(&ctx_o, ctx->k_opad, 64);
85         SHA1Update(&ctx_o, digest, SHA1HashSize);
86         SHA1Final(digest, &ctx_o);
87 }