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