1
2 #include <stddef.h>
3 #include <stdint.h>
4 #include <string.h>
5
6 #include "crypto_auth_hmacsha256.h"
7 #include "crypto_hash_sha256.h"
8 #include "crypto_verify_32.h"
9 #include "randombytes.h"
10 #include "utils.h"
11
12 size_t
crypto_auth_hmacsha256_bytes(void)13 crypto_auth_hmacsha256_bytes(void)
14 {
15 return crypto_auth_hmacsha256_BYTES;
16 }
17
18 size_t
crypto_auth_hmacsha256_keybytes(void)19 crypto_auth_hmacsha256_keybytes(void)
20 {
21 return crypto_auth_hmacsha256_KEYBYTES;
22 }
23
24 size_t
crypto_auth_hmacsha256_statebytes(void)25 crypto_auth_hmacsha256_statebytes(void)
26 {
27 return sizeof(crypto_auth_hmacsha256_state);
28 }
29
30 void
crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES])31 crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES])
32 {
33 randombytes_buf(k, crypto_auth_hmacsha256_KEYBYTES);
34 }
35
36 int
crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state * state,const unsigned char * key,size_t keylen)37 crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
38 const unsigned char *key, size_t keylen)
39 {
40 unsigned char pad[64];
41 unsigned char khash[32];
42 size_t i;
43
44 if (keylen > 64) {
45 crypto_hash_sha256_init(&state->ictx);
46 crypto_hash_sha256_update(&state->ictx, key, keylen);
47 crypto_hash_sha256_final(&state->ictx, khash);
48 key = khash;
49 keylen = 32;
50 }
51 crypto_hash_sha256_init(&state->ictx);
52 memset(pad, 0x36, 64);
53 for (i = 0; i < keylen; i++) {
54 pad[i] ^= key[i];
55 }
56 crypto_hash_sha256_update(&state->ictx, pad, 64);
57
58 crypto_hash_sha256_init(&state->octx);
59 memset(pad, 0x5c, 64);
60 for (i = 0; i < keylen; i++) {
61 pad[i] ^= key[i];
62 }
63 crypto_hash_sha256_update(&state->octx, pad, 64);
64
65 sodium_memzero((void *) pad, sizeof pad);
66 sodium_memzero((void *) khash, sizeof khash);
67
68 return 0;
69 }
70
71 int
crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state * state,const unsigned char * in,unsigned long long inlen)72 crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
73 const unsigned char *in, unsigned long long inlen)
74 {
75 crypto_hash_sha256_update(&state->ictx, in, inlen);
76
77 return 0;
78 }
79
80 int
crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state * state,unsigned char * out)81 crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
82 unsigned char *out)
83 {
84 unsigned char ihash[32];
85
86 crypto_hash_sha256_final(&state->ictx, ihash);
87 crypto_hash_sha256_update(&state->octx, ihash, 32);
88 crypto_hash_sha256_final(&state->octx, out);
89
90 sodium_memzero((void *) ihash, sizeof ihash);
91
92 return 0;
93 }
94
95 int
crypto_auth_hmacsha256(unsigned char * out,const unsigned char * in,unsigned long long inlen,const unsigned char * k)96 crypto_auth_hmacsha256(unsigned char *out, const unsigned char *in,
97 unsigned long long inlen, const unsigned char *k)
98 {
99 crypto_auth_hmacsha256_state state;
100
101 crypto_auth_hmacsha256_init(&state, k, crypto_auth_hmacsha256_KEYBYTES);
102 crypto_auth_hmacsha256_update(&state, in, inlen);
103 crypto_auth_hmacsha256_final(&state, out);
104
105 return 0;
106 }
107
108 int
crypto_auth_hmacsha256_verify(const unsigned char * h,const unsigned char * in,unsigned long long inlen,const unsigned char * k)109 crypto_auth_hmacsha256_verify(const unsigned char *h, const unsigned char *in,
110 unsigned long long inlen, const unsigned char *k)
111 {
112 unsigned char correct[32];
113
114 crypto_auth_hmacsha256(correct, in, inlen, k);
115
116 return crypto_verify_32(h, correct) | (-(h == correct)) |
117 sodium_memcmp(correct, h, 32);
118 }
119