xref: /freebsd/sys/contrib/libsodium/src/libsodium/crypto_auth/hmacsha512/auth_hmacsha512.c (revision 3611ec604864a7d4dcc9a3ea898c80eb35eef8a0)
1 
2 #include <stddef.h>
3 #include <stdint.h>
4 #include <string.h>
5 
6 #include "crypto_auth_hmacsha512.h"
7 #include "crypto_hash_sha512.h"
8 #include "crypto_verify_64.h"
9 #include "randombytes.h"
10 #include "utils.h"
11 
12 size_t
crypto_auth_hmacsha512_bytes(void)13 crypto_auth_hmacsha512_bytes(void)
14 {
15     return crypto_auth_hmacsha512_BYTES;
16 }
17 
18 size_t
crypto_auth_hmacsha512_keybytes(void)19 crypto_auth_hmacsha512_keybytes(void)
20 {
21     return crypto_auth_hmacsha512_KEYBYTES;
22 }
23 
24 size_t
crypto_auth_hmacsha512_statebytes(void)25 crypto_auth_hmacsha512_statebytes(void)
26 {
27     return sizeof(crypto_auth_hmacsha512_state);
28 }
29 
30 void
crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES])31 crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES])
32 {
33     randombytes_buf(k, crypto_auth_hmacsha512_KEYBYTES);
34 }
35 
36 int
crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state * state,const unsigned char * key,size_t keylen)37 crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
38                             const unsigned char *key, size_t keylen)
39 {
40     unsigned char pad[128];
41     unsigned char khash[64];
42     size_t        i;
43 
44     if (keylen > 128) {
45         crypto_hash_sha512_init(&state->ictx);
46         crypto_hash_sha512_update(&state->ictx, key, keylen);
47         crypto_hash_sha512_final(&state->ictx, khash);
48         key    = khash;
49         keylen = 64;
50     }
51     crypto_hash_sha512_init(&state->ictx);
52     memset(pad, 0x36, 128);
53     for (i = 0; i < keylen; i++) {
54         pad[i] ^= key[i];
55     }
56     crypto_hash_sha512_update(&state->ictx, pad, 128);
57 
58     crypto_hash_sha512_init(&state->octx);
59     memset(pad, 0x5c, 128);
60     for (i = 0; i < keylen; i++) {
61         pad[i] ^= key[i];
62     }
63     crypto_hash_sha512_update(&state->octx, pad, 128);
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_hmacsha512_update(crypto_auth_hmacsha512_state * state,const unsigned char * in,unsigned long long inlen)72 crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
73                               const unsigned char *in, unsigned long long inlen)
74 {
75     crypto_hash_sha512_update(&state->ictx, in, inlen);
76 
77     return 0;
78 }
79 
80 int
crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state * state,unsigned char * out)81 crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
82                              unsigned char                *out)
83 {
84     unsigned char ihash[64];
85 
86     crypto_hash_sha512_final(&state->ictx, ihash);
87     crypto_hash_sha512_update(&state->octx, ihash, 64);
88     crypto_hash_sha512_final(&state->octx, out);
89 
90     sodium_memzero((void *) ihash, sizeof ihash);
91 
92     return 0;
93 }
94 
95 int
crypto_auth_hmacsha512(unsigned char * out,const unsigned char * in,unsigned long long inlen,const unsigned char * k)96 crypto_auth_hmacsha512(unsigned char *out, const unsigned char *in,
97                        unsigned long long inlen, const unsigned char *k)
98 {
99     crypto_auth_hmacsha512_state state;
100 
101     crypto_auth_hmacsha512_init(&state, k, crypto_auth_hmacsha512_KEYBYTES);
102     crypto_auth_hmacsha512_update(&state, in, inlen);
103     crypto_auth_hmacsha512_final(&state, out);
104 
105     return 0;
106 }
107 
108 int
crypto_auth_hmacsha512_verify(const unsigned char * h,const unsigned char * in,unsigned long long inlen,const unsigned char * k)109 crypto_auth_hmacsha512_verify(const unsigned char *h, const unsigned char *in,
110                               unsigned long long inlen, const unsigned char *k)
111 {
112     unsigned char correct[64];
113 
114     crypto_auth_hmacsha512(correct, in, inlen, k);
115 
116     return crypto_verify_64(h, correct) | (-(h == correct)) |
117            sodium_memcmp(correct, h, 64);
118 }
119