Move digests to providers
[openssl.git] / crypto / blake2 / blake2s_mac.c
1 /*
2  * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #ifndef OPENSSL_NO_BLAKE2
11
12 # include <openssl/evp.h>
13 # include "internal/blake2.h"
14 # include "internal/cryptlib.h"
15 # include "internal/evp_int.h"
16
17 /* typedef EVP_MAC_IMPL */
18 struct evp_mac_impl_st {
19     BLAKE2S_CTX ctx;
20     BLAKE2S_PARAM params;
21     unsigned char key[BLAKE2S_KEYBYTES];
22 };
23
24 static EVP_MAC_IMPL *blake2s_mac_new(void)
25 {
26     EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx));
27     if (macctx != NULL) {
28         blake2s_param_init(&macctx->params);
29         /* ctx initialization is deferred to BLAKE2s_Init() */
30     }
31     return macctx;
32 }
33
34 static void blake2s_mac_free(EVP_MAC_IMPL *macctx)
35 {
36     if (macctx != NULL) {
37         OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
38         OPENSSL_free(macctx);
39     }
40 }
41
42 static int blake2s_mac_copy(EVP_MAC_IMPL *dst, EVP_MAC_IMPL *src)
43 {
44     *dst = *src;
45     return 1;
46 }
47
48 static int blake2s_mac_init(EVP_MAC_IMPL *macctx)
49 {
50     /* Check key has been set */
51     if (macctx->params.key_length == 0) {
52         EVPerr(EVP_F_BLAKE2S_MAC_INIT, EVP_R_NO_KEY_SET);
53         return 0;
54     }
55
56     return blake2s_init_key(&macctx->ctx, &macctx->params, macctx->key);
57 }
58
59 static int blake2s_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data,
60                               size_t datalen)
61 {
62     return blake2s_update(&macctx->ctx, data, datalen);
63 }
64
65 static int blake2s_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out)
66 {
67     return blake2s_final(out, &macctx->ctx);
68 }
69
70 /*
71  * ALL Ctrl functions should be set before init().
72  */
73 static int blake2s_mac_ctrl(EVP_MAC_IMPL *macctx, int cmd, va_list args)
74 {
75     const unsigned char *p;
76     size_t len;
77     size_t size;
78
79     switch (cmd) {
80         case EVP_MAC_CTRL_SET_SIZE:
81             size = va_arg(args, size_t);
82             if (size < 1 || size > BLAKE2S_OUTBYTES) {
83                 EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
84                 return 0;
85             }
86             blake2s_param_set_digest_length(&macctx->params, (uint8_t)size);
87             return 1;
88
89         case EVP_MAC_CTRL_SET_KEY:
90             p = va_arg(args, const unsigned char *);
91             len = va_arg(args, size_t);
92             if (len < 1 || len > BLAKE2S_KEYBYTES) {
93                 EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
94                 return 0;
95             }
96             blake2s_param_set_key_length(&macctx->params, (uint8_t)len);
97             memcpy(macctx->key, p, len);
98             memset(macctx->key + len, 0, BLAKE2S_KEYBYTES - len);
99             return 1;
100
101         case EVP_MAC_CTRL_SET_CUSTOM:
102             p = va_arg(args, const unsigned char *);
103             len = va_arg(args, size_t);
104             if (len > BLAKE2S_PERSONALBYTES) {
105                 EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH);
106                 return 0;
107             }
108             blake2s_param_set_personal(&macctx->params, p, len);
109             return 1;
110
111         case EVP_MAC_CTRL_SET_SALT:
112             p = va_arg(args, const unsigned char *);
113             len = va_arg(args, size_t);
114             if (len > BLAKE2S_SALTBYTES) {
115                 EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH);
116                 return 0;
117             }
118             blake2s_param_set_salt(&macctx->params, p, len);
119             return 1;
120
121         default:
122             return -2;
123     }
124 }
125
126 static int blake2s_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...)
127 {
128     int rv;
129     va_list args;
130
131     va_start(args, cmd);
132     rv = blake2s_mac_ctrl(macctx, cmd, args);
133     va_end(args);
134
135     return rv;
136 }
137
138 static int blake2s_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen)
139 {
140     return blake2s_mac_ctrl_int(macctx, cmd, buf, buflen);
141 }
142
143 static int blake2s_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type,
144                                 const char *value)
145 {
146     if (value == NULL)
147         return 0;
148
149     if (strcmp(type, "outlen") == 0)
150         return blake2s_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value));
151     if (strcmp(type, "key") == 0)
152         return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY,
153                             value);
154     if (strcmp(type, "hexkey") == 0)
155         return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY,
156                             value);
157     if (strcmp(type, "custom") == 0)
158         return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM,
159                             value);
160     if (strcmp(type, "hexcustom") == 0)
161         return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM,
162                             value);
163     if (strcmp(type, "salt") == 0)
164         return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT,
165                             value);
166     if (strcmp(type, "hexsalt") == 0)
167         return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT,
168                             value);
169     return -2;
170 }
171
172 static size_t blake2s_mac_size(EVP_MAC_IMPL *macctx)
173 {
174     return macctx->params.digest_length;
175 }
176
177 const EVP_MAC blake2s_mac_meth = {
178     EVP_MAC_BLAKE2S,
179     blake2s_mac_new,
180     blake2s_mac_copy,
181     blake2s_mac_free,
182     blake2s_mac_size,
183     blake2s_mac_init,
184     blake2s_mac_update,
185     blake2s_mac_final,
186     blake2s_mac_ctrl,
187     blake2s_mac_ctrl_str
188 };
189
190 #endif