1 
2 #include <assert.h>
3 #include <limits.h>
4 #include <stdint.h>
5 
6 #include "blake2.h"
7 #include "crypto_generichash_blake2b.h"
8 #include "private/common.h"
9 #include "private/implementations.h"
10 
11 int
12 crypto_generichash_blake2b(unsigned char *out, size_t outlen,
13                            const unsigned char *in, unsigned long long inlen,
14                            const unsigned char *key, size_t keylen)
15 {
16     if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
17         keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) {
18         return -1;
19     }
20     assert(outlen <= UINT8_MAX);
21     assert(keylen <= UINT8_MAX);
22 
23     return blake2b((uint8_t *) out, in, key, (uint8_t) outlen, (uint64_t) inlen,
24                    (uint8_t) keylen);
25 }
26 
27 int
28 crypto_generichash_blake2b_salt_personal(
29     unsigned char *out, size_t outlen, const unsigned char *in,
30     unsigned long long inlen, const unsigned char *key, size_t keylen,
31     const unsigned char *salt, const unsigned char *personal)
32 {
33     if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
34         keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) {
35         return -1;
36     }
37     assert(outlen <= UINT8_MAX);
38     assert(keylen <= UINT8_MAX);
39 
40     return blake2b_salt_personal((uint8_t *) out, in, key, (uint8_t) outlen,
41                                  (uint64_t) inlen, (uint8_t) keylen, salt,
42                                  personal);
43 }
44 
45 int
46 crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state,
47                                 const unsigned char *key, const size_t keylen,
48                                 const size_t outlen)
49 {
50     if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
51         keylen > BLAKE2B_KEYBYTES) {
52         return -1;
53     }
54     assert(outlen <= UINT8_MAX);
55     assert(keylen <= UINT8_MAX);
56     COMPILER_ASSERT(sizeof(blake2b_state) <= sizeof *state);
57     if (key == NULL || keylen <= 0U) {
58         if (blake2b_init((blake2b_state *) (void *) state, (uint8_t) outlen) != 0) {
59             return -1; /* LCOV_EXCL_LINE */
60         }
61     } else if (blake2b_init_key((blake2b_state *) (void *) state, (uint8_t) outlen, key,
62                                 (uint8_t) keylen) != 0) {
63         return -1; /* LCOV_EXCL_LINE */
64     }
65     return 0;
66 }
67 
68 int
69 crypto_generichash_blake2b_init_salt_personal(
70     crypto_generichash_blake2b_state *state, const unsigned char *key,
71     const size_t keylen, const size_t outlen, const unsigned char *salt,
72     const unsigned char *personal)
73 {
74     if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
75         keylen > BLAKE2B_KEYBYTES) {
76         return -1;
77     }
78     assert(outlen <= UINT8_MAX);
79     assert(keylen <= UINT8_MAX);
80     if (key == NULL || keylen <= 0U) {
81         if (blake2b_init_salt_personal((blake2b_state *) (void *) state,
82                                        (uint8_t) outlen, salt, personal) != 0) {
83             return -1; /* LCOV_EXCL_LINE */
84         }
85     } else if (blake2b_init_key_salt_personal((blake2b_state *) (void *) state,
86                                               (uint8_t) outlen, key,
87                                               (uint8_t) keylen, salt,
88                                               personal) != 0) {
89         return -1; /* LCOV_EXCL_LINE */
90     }
91     return 0;
92 }
93 
94 int
95 crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state,
96                                   const unsigned char *in,
97                                   unsigned long long inlen)
98 {
99     return blake2b_update((blake2b_state *) (void *) state,
100                           (const uint8_t *) in, (uint64_t) inlen);
101 }
102 
103 int
104 crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state,
105                                  unsigned char *out, const size_t outlen)
106 {
107     assert(outlen <= UINT8_MAX);
108     return blake2b_final((blake2b_state *) (void *) state,
109                          (uint8_t *) out, (uint8_t) outlen);
110 }
111 
112 int
113 _crypto_generichash_blake2b_pick_best_implementation(void)
114 {
115     return blake2b_pick_best_implementation();
116 }
117