]>
Commit | Line | Data |
---|---|---|
eb173822 | 1 | /* |
a28d06f3 | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
eb173822 SL |
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 | /* Dispatch functions for AES SIV mode */ | |
11 | ||
c72fa255 MC |
12 | /* |
13 | * This file uses the low level AES functions (which are deprecated for | |
14 | * non-internal use) in order to implement provider AES ciphers. | |
15 | */ | |
16 | #include "internal/deprecated.h" | |
17 | ||
2741128e | 18 | #include <openssl/proverr.h> |
eb173822 SL |
19 | #include "cipher_aes_siv.h" |
20 | #include "prov/implementations.h" | |
f99d3eed | 21 | #include "prov/providercommon.h" |
68a51d59 | 22 | #include "prov/ciphercommon_aead.h" |
90409da6 | 23 | #include "prov/provider_ctx.h" |
eb173822 SL |
24 | |
25 | #define siv_stream_update siv_cipher | |
26 | #define SIV_FLAGS AEAD_FLAGS | |
27 | ||
12ddfa6b P |
28 | static OSSL_FUNC_cipher_set_ctx_params_fn aes_siv_set_ctx_params; |
29 | ||
eb173822 SL |
30 | static void *aes_siv_newctx(void *provctx, size_t keybits, unsigned int mode, |
31 | uint64_t flags) | |
32 | { | |
f99d3eed | 33 | PROV_AES_SIV_CTX *ctx; |
eb173822 | 34 | |
f99d3eed P |
35 | if (!ossl_prov_is_running()) |
36 | return NULL; | |
37 | ||
38 | ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
eb173822 SL |
39 | if (ctx != NULL) { |
40 | ctx->taglen = SIV_LEN; | |
41 | ctx->mode = mode; | |
eb173822 | 42 | ctx->keylen = keybits / 8; |
7d6766cb | 43 | ctx->hw = ossl_prov_cipher_hw_aes_siv(keybits); |
a829b735 | 44 | ctx->libctx = PROV_LIBCTX_OF(provctx); |
eb173822 SL |
45 | } |
46 | return ctx; | |
47 | } | |
48 | ||
49 | static void aes_siv_freectx(void *vctx) | |
50 | { | |
51 | PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; | |
52 | ||
53 | if (ctx != NULL) { | |
54 | ctx->hw->cleanup(ctx); | |
55 | OPENSSL_clear_free(ctx, sizeof(*ctx)); | |
56 | } | |
57 | } | |
58 | ||
90409da6 SL |
59 | static void *siv_dupctx(void *vctx) |
60 | { | |
61 | PROV_AES_SIV_CTX *in = (PROV_AES_SIV_CTX *)vctx; | |
f99d3eed | 62 | PROV_AES_SIV_CTX *ret; |
90409da6 | 63 | |
f99d3eed P |
64 | if (!ossl_prov_is_running()) |
65 | return NULL; | |
66 | ||
67 | ret = OPENSSL_malloc(sizeof(*ret)); | |
e077455e | 68 | if (ret == NULL) |
90409da6 | 69 | return NULL; |
90409da6 SL |
70 | if (!in->hw->dupctx(in, ret)) { |
71 | OPENSSL_free(ret); | |
72 | ret = NULL; | |
73 | } | |
74 | return ret; | |
75 | } | |
76 | ||
eb173822 | 77 | static int siv_init(void *vctx, const unsigned char *key, size_t keylen, |
12ddfa6b P |
78 | const unsigned char *iv, size_t ivlen, |
79 | const OSSL_PARAM params[], int enc) | |
eb173822 SL |
80 | { |
81 | PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; | |
82 | ||
f99d3eed P |
83 | if (!ossl_prov_is_running()) |
84 | return 0; | |
85 | ||
eb173822 SL |
86 | ctx->enc = enc; |
87 | ||
eb173822 SL |
88 | if (key != NULL) { |
89 | if (keylen != ctx->keylen) { | |
90 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); | |
91 | return 0; | |
92 | } | |
12ddfa6b P |
93 | if (!ctx->hw->initkey(ctx, key, ctx->keylen)) |
94 | return 0; | |
eb173822 | 95 | } |
12ddfa6b | 96 | return aes_siv_set_ctx_params(ctx, params); |
eb173822 SL |
97 | } |
98 | ||
99 | static int siv_einit(void *vctx, const unsigned char *key, size_t keylen, | |
12ddfa6b P |
100 | const unsigned char *iv, size_t ivlen, |
101 | const OSSL_PARAM params[]) | |
eb173822 | 102 | { |
12ddfa6b | 103 | return siv_init(vctx, key, keylen, iv, ivlen, params, 1); |
eb173822 SL |
104 | } |
105 | ||
106 | static int siv_dinit(void *vctx, const unsigned char *key, size_t keylen, | |
12ddfa6b P |
107 | const unsigned char *iv, size_t ivlen, |
108 | const OSSL_PARAM params[]) | |
eb173822 | 109 | { |
12ddfa6b | 110 | return siv_init(vctx, key, keylen, iv, ivlen, params, 0); |
eb173822 SL |
111 | } |
112 | ||
113 | static int siv_cipher(void *vctx, unsigned char *out, size_t *outl, | |
114 | size_t outsize, const unsigned char *in, size_t inl) | |
115 | { | |
116 | PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; | |
117 | ||
f99d3eed P |
118 | if (!ossl_prov_is_running()) |
119 | return 0; | |
120 | ||
4b9c750b MC |
121 | if (inl == 0) { |
122 | *outl = 0; | |
123 | return 1; | |
124 | } | |
125 | ||
eb173822 SL |
126 | if (outsize < inl) { |
127 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); | |
128 | return 0; | |
129 | } | |
130 | ||
131 | if (ctx->hw->cipher(ctx, out, in, inl) <= 0) | |
132 | return 0; | |
133 | ||
134 | if (outl != NULL) | |
135 | *outl = inl; | |
136 | return 1; | |
137 | } | |
138 | ||
139 | static int siv_stream_final(void *vctx, unsigned char *out, size_t *outl, | |
140 | size_t outsize) | |
141 | { | |
142 | PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; | |
143 | ||
f99d3eed P |
144 | if (!ossl_prov_is_running()) |
145 | return 0; | |
146 | ||
eb173822 SL |
147 | if (!ctx->hw->cipher(vctx, out, NULL, 0)) |
148 | return 0; | |
149 | ||
150 | if (outl != NULL) | |
151 | *outl = 0; | |
152 | return 1; | |
153 | } | |
154 | ||
155 | static int aes_siv_get_ctx_params(void *vctx, OSSL_PARAM params[]) | |
156 | { | |
157 | PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; | |
158 | SIV128_CONTEXT *sctx = &ctx->siv; | |
159 | OSSL_PARAM *p; | |
160 | ||
161 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); | |
162 | if (p != NULL && p->data_type == OSSL_PARAM_OCTET_STRING) { | |
163 | if (!ctx->enc | |
164 | || p->data_size != ctx->taglen | |
165 | || !OSSL_PARAM_set_octet_string(p, &sctx->tag.byte, ctx->taglen)) { | |
166 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
167 | return 0; | |
168 | } | |
169 | } | |
170 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); | |
171 | if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->taglen)) { | |
172 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
173 | return 0; | |
174 | } | |
175 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); | |
176 | if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { | |
177 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
178 | return 0; | |
179 | } | |
180 | return 1; | |
181 | } | |
182 | ||
183 | static const OSSL_PARAM aes_siv_known_gettable_ctx_params[] = { | |
184 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), | |
185 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), | |
eb173822 SL |
186 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), |
187 | OSSL_PARAM_END | |
188 | }; | |
644c5dd3 P |
189 | static const OSSL_PARAM *aes_siv_gettable_ctx_params(ossl_unused void *cctx, |
190 | ossl_unused void *provctx) | |
eb173822 SL |
191 | { |
192 | return aes_siv_known_gettable_ctx_params; | |
193 | } | |
194 | ||
195 | static int aes_siv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) | |
196 | { | |
197 | PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; | |
198 | const OSSL_PARAM *p; | |
199 | unsigned int speed = 0; | |
200 | ||
12ddfa6b P |
201 | if (params == NULL) |
202 | return 1; | |
203 | ||
eb173822 SL |
204 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); |
205 | if (p != NULL) { | |
206 | if (ctx->enc) | |
207 | return 1; | |
208 | if (p->data_type != OSSL_PARAM_OCTET_STRING | |
209 | || !ctx->hw->settag(ctx, p->data, p->data_size)) { | |
210 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
211 | return 0; | |
212 | } | |
213 | } | |
214 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_SPEED); | |
215 | if (p != NULL) { | |
216 | if (!OSSL_PARAM_get_uint(p, &speed)) { | |
217 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
218 | return 0; | |
219 | } | |
220 | ctx->hw->setspeed(ctx, (int)speed); | |
221 | } | |
222 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); | |
223 | if (p != NULL) { | |
224 | size_t keylen; | |
225 | ||
226 | if (!OSSL_PARAM_get_size_t(p, &keylen)) { | |
227 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
228 | return 0; | |
229 | } | |
230 | /* The key length can not be modified */ | |
231 | if (keylen != ctx->keylen) | |
232 | return 0; | |
233 | } | |
234 | return 1; | |
235 | } | |
236 | ||
237 | static const OSSL_PARAM aes_siv_known_settable_ctx_params[] = { | |
238 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), | |
239 | OSSL_PARAM_uint(OSSL_CIPHER_PARAM_SPEED, NULL), | |
240 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), | |
241 | OSSL_PARAM_END | |
242 | }; | |
644c5dd3 P |
243 | static const OSSL_PARAM *aes_siv_settable_ctx_params(ossl_unused void *cctx, |
244 | ossl_unused void *provctx) | |
eb173822 SL |
245 | { |
246 | return aes_siv_known_settable_ctx_params; | |
247 | } | |
248 | ||
249 | #define IMPLEMENT_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ | |
af5e1e85 P |
250 | static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ |
251 | static OSSL_FUNC_cipher_freectx_fn alg##_##lc##_freectx; \ | |
252 | static OSSL_FUNC_cipher_dupctx_fn lc##_dupctx; \ | |
253 | static OSSL_FUNC_cipher_encrypt_init_fn lc##_einit; \ | |
254 | static OSSL_FUNC_cipher_decrypt_init_fn lc##_dinit; \ | |
255 | static OSSL_FUNC_cipher_update_fn lc##_stream_update; \ | |
256 | static OSSL_FUNC_cipher_final_fn lc##_stream_final; \ | |
257 | static OSSL_FUNC_cipher_cipher_fn lc##_cipher; \ | |
363b1e5d | 258 | static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ |
af5e1e85 P |
259 | static OSSL_FUNC_cipher_get_ctx_params_fn alg##_##lc##_get_ctx_params; \ |
260 | static OSSL_FUNC_cipher_gettable_ctx_params_fn \ | |
261 | alg##_##lc##_gettable_ctx_params; \ | |
262 | static OSSL_FUNC_cipher_set_ctx_params_fn alg##_##lc##_set_ctx_params; \ | |
263 | static OSSL_FUNC_cipher_settable_ctx_params_fn \ | |
264 | alg##_##lc##_settable_ctx_params; \ | |
eb173822 SL |
265 | static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ |
266 | { \ | |
592dcfd3 | 267 | return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ |
a054d15c | 268 | flags, 2*kbits, blkbits, ivbits); \ |
eb173822 | 269 | } \ |
eb173822 SL |
270 | static void * alg##kbits##lc##_newctx(void *provctx) \ |
271 | { \ | |
272 | return alg##_##lc##_newctx(provctx, 2*kbits, EVP_CIPH_##UCMODE##_MODE, \ | |
273 | flags); \ | |
274 | } \ | |
1be63951 | 275 | const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ |
eb173822 SL |
276 | { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ |
277 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ | |
90409da6 | 278 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) lc##_dupctx }, \ |
eb173822 SL |
279 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit }, \ |
280 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit }, \ | |
281 | { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update }, \ | |
282 | { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final }, \ | |
283 | { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher }, \ | |
284 | { OSSL_FUNC_CIPHER_GET_PARAMS, \ | |
285 | (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ | |
286 | { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ | |
592dcfd3 | 287 | (void (*)(void))ossl_cipher_generic_gettable_params }, \ |
eb173822 SL |
288 | { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ |
289 | (void (*)(void)) alg##_##lc##_get_ctx_params }, \ | |
290 | { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ | |
291 | (void (*)(void)) alg##_##lc##_gettable_ctx_params }, \ | |
292 | { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ | |
293 | (void (*)(void)) alg##_##lc##_set_ctx_params }, \ | |
294 | { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ | |
295 | (void (*)(void)) alg##_##lc##_settable_ctx_params }, \ | |
1e6bd31e | 296 | OSSL_DISPATCH_END \ |
eb173822 SL |
297 | }; |
298 | ||
299 | IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 128, 8, 0) | |
300 | IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 192, 8, 0) | |
301 | IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 256, 8, 0) |