Home | History | Annotate | Line # | Download | only in hmacsha512
      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
     13 crypto_auth_hmacsha512_bytes(void)
     14 {
     15     return crypto_auth_hmacsha512_BYTES;
     16 }
     17 
     18 size_t
     19 crypto_auth_hmacsha512_keybytes(void)
     20 {
     21     return crypto_auth_hmacsha512_KEYBYTES;
     22 }
     23 
     24 size_t
     25 crypto_auth_hmacsha512_statebytes(void)
     26 {
     27     return sizeof(crypto_auth_hmacsha512_state);
     28 }
     29 
     30 void
     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
     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
     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
     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
     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
    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