]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libsec/port/hmac.c
libsec: generalize pbkdf2_hmac_sha1() to pbkdf2_x() passing the hmac as an argument
[plan9front.git] / sys / src / libsec / port / hmac.c
1 #include "os.h"
2 #include <libsec.h>
3
4 /* rfc2104 */
5 DigestState*
6 hmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
7         DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen)
8 {
9         int i;
10         uchar pad[Hmacblksz+1], innerdigest[256];
11
12         if(xlen > sizeof(innerdigest))
13                 return nil;
14         if(klen > Hmacblksz){
15                 if(xlen > Hmacblksz)
16                         return nil;
17                 (*x)(key, klen, innerdigest, nil);
18                 key = innerdigest;
19                 klen = xlen;
20         }
21
22         /* first time through */
23         if(s == nil || s->seeded == 0){
24                 memset(pad, 0x36, Hmacblksz);
25                 pad[Hmacblksz] = 0;
26                 for(i = 0; i < klen; i++)
27                         pad[i] ^= key[i];
28                 s = (*x)(pad, Hmacblksz, nil, s);
29                 if(s == nil)
30                         return nil;
31         }
32
33         s = (*x)(p, len, nil, s);
34         if(digest == nil)
35                 return s;
36
37         /* last time through */
38         memset(pad, 0x5c, Hmacblksz);
39         pad[Hmacblksz] = 0;
40         for(i = 0; i < klen; i++)
41                 pad[i] ^= key[i];
42         (*x)(nil, 0, innerdigest, s);
43         s = (*x)(pad, Hmacblksz, nil, nil);
44         (*x)(innerdigest, xlen, digest, s);
45         return nil;
46 }