prov: upport modified gettable/settable ctx calls for ciphers
[openssl.git] / providers / implementations / ciphers / cipher_aes_cbc_hmac_sha.c
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 /*
11  * AES low level APIs are deprecated for public use, but still ok for internal
12  * use where we're using them to implement the higher level EVP interface, as is
13  * the case here.
14  */
15 #include "internal/deprecated.h"
16
17 /* Dispatch functions for AES_CBC_HMAC_SHA ciphers */
18
19 /* Only for SSL3_VERSION and TLS1_VERSION */
20 #include <openssl/ssl.h>
21 #include <openssl/proverr.h>
22 #include "cipher_aes_cbc_hmac_sha.h"
23 #include "prov/implementations.h"
24 #include "prov/providercommon.h"
25
26 #ifndef AES_CBC_HMAC_SHA_CAPABLE
27 # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags)              \
28 const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = {                    \
29     { 0, NULL }                                                                \
30 };
31 #else
32
33 # define AES_CBC_HMAC_SHA_FLAGS (PROV_CIPHER_FLAG_AEAD                         \
34                                  | PROV_CIPHER_FLAG_TLS1_MULTIBLOCK)
35
36 static OSSL_FUNC_cipher_freectx_fn aes_cbc_hmac_sha1_freectx;
37 static OSSL_FUNC_cipher_freectx_fn aes_cbc_hmac_sha256_freectx;
38 static OSSL_FUNC_cipher_get_ctx_params_fn aes_get_ctx_params;
39 static OSSL_FUNC_cipher_gettable_ctx_params_fn aes_gettable_ctx_params;
40 static OSSL_FUNC_cipher_set_ctx_params_fn aes_set_ctx_params;
41 static OSSL_FUNC_cipher_settable_ctx_params_fn aes_settable_ctx_params;
42 # define aes_gettable_params ossl_cipher_generic_gettable_params
43 # define aes_einit ossl_cipher_generic_einit
44 # define aes_dinit ossl_cipher_generic_dinit
45 # define aes_update ossl_cipher_generic_stream_update
46 # define aes_final ossl_cipher_generic_stream_final
47 # define aes_cipher ossl_cipher_generic_cipher
48
49 static const OSSL_PARAM cipher_aes_known_settable_ctx_params[] = {
50     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_MAC_KEY, NULL, 0),
51     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
52 # if !defined(OPENSSL_NO_MULTIBLOCK)
53     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, NULL),
54     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, NULL),
55     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL),
56     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, NULL, 0),
57     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, NULL, 0),
58 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
59     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
60     OSSL_PARAM_END
61 };
62 const OSSL_PARAM *aes_settable_ctx_params(ossl_unused void *cctx,
63                                           ossl_unused void *provctx)
64 {
65     return cipher_aes_known_settable_ctx_params;
66 }
67
68 static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
69 {
70     PROV_AES_HMAC_SHA_CTX *ctx = (PROV_AES_HMAC_SHA_CTX *)vctx;
71     PROV_CIPHER_HW_AES_HMAC_SHA *hw =
72        (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->hw;
73     const OSSL_PARAM *p;
74     int ret = 1;
75 # if !defined(OPENSSL_NO_MULTIBLOCK)
76     EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
77 # endif
78
79     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_MAC_KEY);
80     if (p != NULL) {
81         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
82             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
83             return 0;
84         }
85         hw->init_mac_key(ctx, p->data, p->data_size);
86     }
87
88 # if !defined(OPENSSL_NO_MULTIBLOCK)
89     p = OSSL_PARAM_locate_const(params,
90             OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT);
91     if (p != NULL
92             && !OSSL_PARAM_get_size_t(p, &ctx->multiblock_max_send_fragment)) {
93         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
94         return 0;
95     }
96     /*
97      * The inputs to tls1_multiblock_aad are:
98      *   mb_param->inp
99      *   mb_param->len
100      *   mb_param->interleave
101      * The outputs of tls1_multiblock_aad are written to:
102      *   ctx->multiblock_interleave
103      *   ctx->multiblock_aad_packlen
104      */
105     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD);
106     if (p != NULL) {
107         const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params,
108                                    OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
109         if (p->data_type != OSSL_PARAM_OCTET_STRING
110             || p1 == NULL
111             || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) {
112             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
113             return 0;
114         }
115         mb_param.inp = p->data;
116         mb_param.len = p->data_size;
117         if (hw->tls1_multiblock_aad(vctx, &mb_param) <= 0)
118             return 0;
119     }
120
121     /*
122      * The inputs to tls1_multiblock_encrypt are:
123      *   mb_param->inp
124      *   mb_param->len
125      *   mb_param->interleave
126      *   mb_param->out
127      * The outputs of tls1_multiblock_encrypt are:
128      *   ctx->multiblock_encrypt_len
129      */
130     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC);
131     if (p != NULL) {
132         const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params,
133                                    OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
134         const OSSL_PARAM *pin = OSSL_PARAM_locate_const(params,
135                                     OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN);
136
137         if (p->data_type != OSSL_PARAM_OCTET_STRING
138             || pin == NULL
139             || pin->data_type != OSSL_PARAM_OCTET_STRING
140             || p1 == NULL
141             || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) {
142             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
143             return 0;
144         }
145         mb_param.out = p->data;
146         mb_param.inp = pin->data;
147         mb_param.len = pin->data_size;
148         if (hw->tls1_multiblock_encrypt(vctx, &mb_param) <= 0)
149             return 0;
150     }
151 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
152
153     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
154     if (p != NULL) {
155         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
156             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
157             return 0;
158         }
159         if (hw->set_tls1_aad(ctx, p->data, p->data_size) <= 0)
160             return 0;
161     }
162
163     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
164     if (p != NULL) {
165         size_t keylen;
166
167         if (!OSSL_PARAM_get_size_t(p, &keylen)) {
168             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
169             return 0;
170         }
171         if (ctx->base.keylen != keylen) {
172             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
173             return 0;
174         }
175     }
176
177     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
178     if (p != NULL) {
179         if (!OSSL_PARAM_get_uint(p, &ctx->base.tlsversion)) {
180             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
181             return 0;
182         }
183         if (ctx->base.tlsversion == SSL3_VERSION
184                 || ctx->base.tlsversion == TLS1_VERSION) {
185             if (!ossl_assert(ctx->base.removetlsfixed >= AES_BLOCK_SIZE)) {
186                 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
187                 return 0;
188             }
189             /*
190              * There is no explicit IV with these TLS versions, so don't attempt
191              * to remove it.
192              */
193             ctx->base.removetlsfixed -= AES_BLOCK_SIZE;
194         }
195     }
196     return ret;
197 }
198
199 static int aes_get_ctx_params(void *vctx, OSSL_PARAM params[])
200 {
201     PROV_AES_HMAC_SHA_CTX *ctx = (PROV_AES_HMAC_SHA_CTX *)vctx;
202     OSSL_PARAM *p;
203
204 # if !defined(OPENSSL_NO_MULTIBLOCK)
205     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE);
206     if (p != NULL) {
207         PROV_CIPHER_HW_AES_HMAC_SHA *hw =
208            (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->hw;
209         size_t len = hw->tls1_multiblock_max_bufsize(ctx);
210
211         if (!OSSL_PARAM_set_size_t(p, len)) {
212             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
213             return 0;
214         }
215     }
216
217     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
218     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->multiblock_interleave)) {
219         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
220         return 0;
221     }
222
223     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN);
224     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->multiblock_aad_packlen)) {
225         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
226         return 0;
227     }
228
229     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN);
230     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->multiblock_encrypt_len)) {
231         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
232         return 0;
233     }
234 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
235
236     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
237     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad)) {
238         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
239         return 0;
240     }
241     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
242     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.keylen)) {
243         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
244         return 0;
245     }
246     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
247     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.ivlen)) {
248         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
249         return 0;
250     }
251     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
252     if (p != NULL
253         && !OSSL_PARAM_set_octet_string(p, ctx->base.oiv, ctx->base.ivlen)
254         && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.oiv, ctx->base.ivlen)) {
255         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
256         return 0;
257     }
258     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
259     if (p != NULL
260         && !OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen)
261         && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.iv, ctx->base.ivlen)) {
262         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
263         return 0;
264     }
265     return 1;
266 }
267
268 static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = {
269 # if !defined(OPENSSL_NO_MULTIBLOCK)
270     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, NULL),
271     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL),
272     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, NULL),
273     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, NULL),
274 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
275     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
276     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
277     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
278     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
279     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
280     OSSL_PARAM_END
281 };
282 const OSSL_PARAM *aes_gettable_ctx_params(ossl_unused void *cctx,
283                                           ossl_unused void *provctx)
284 {
285     return cipher_aes_known_gettable_ctx_params;
286 }
287
288 static void base_init(void *provctx, PROV_AES_HMAC_SHA_CTX *ctx,
289                       const PROV_CIPHER_HW_AES_HMAC_SHA *meths,
290                       size_t kbits, size_t blkbits, size_t ivbits,
291                       uint64_t flags)
292 {
293     ossl_cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits,
294                                 EVP_CIPH_CBC_MODE, flags,
295                                 &meths->base, provctx);
296     ctx->hw = (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->base.hw;
297 }
298
299 static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits,
300                                       size_t blkbits, size_t ivbits,
301                                       uint64_t flags)
302 {
303     PROV_AES_HMAC_SHA1_CTX *ctx;
304
305     if (!ossl_prov_is_running())
306         return NULL;
307
308     ctx = OPENSSL_zalloc(sizeof(*ctx));
309     if (ctx != NULL)
310         base_init(provctx, &ctx->base_ctx,
311                   ossl_prov_cipher_hw_aes_cbc_hmac_sha1(), kbits, blkbits,
312                   ivbits, flags);
313     return ctx;
314 }
315
316 static void aes_cbc_hmac_sha1_freectx(void *vctx)
317 {
318     PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx;
319
320     if (ctx != NULL) {
321         ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
322         OPENSSL_clear_free(ctx, sizeof(*ctx));
323     }
324 }
325
326 static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits,
327                                         size_t blkbits, size_t ivbits,
328                                         uint64_t flags)
329 {
330     PROV_AES_HMAC_SHA256_CTX *ctx;
331
332     if (!ossl_prov_is_running())
333         return NULL;
334
335     ctx = OPENSSL_zalloc(sizeof(*ctx));
336     if (ctx != NULL)
337         base_init(provctx, &ctx->base_ctx,
338                   ossl_prov_cipher_hw_aes_cbc_hmac_sha256(), kbits, blkbits,
339                   ivbits, flags);
340     return ctx;
341 }
342
343 static void aes_cbc_hmac_sha256_freectx(void *vctx)
344 {
345     PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx;
346
347     if (ctx != NULL) {
348         ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
349         OPENSSL_clear_free(ctx, sizeof(*ctx));
350     }
351 }
352
353 # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags)              \
354 static OSSL_FUNC_cipher_newctx_fn nm##_##kbits##_##sub##_newctx;               \
355 static void *nm##_##kbits##_##sub##_newctx(void *provctx)                      \
356 {                                                                              \
357     return nm##_##sub##_newctx(provctx, kbits, blkbits, ivbits, flags);        \
358 }                                                                              \
359 static OSSL_FUNC_cipher_get_params_fn nm##_##kbits##_##sub##_get_params;       \
360 static int nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[])              \
361 {                                                                              \
362     return ossl_cipher_generic_get_params(params, EVP_CIPH_CBC_MODE,           \
363                                           flags, kbits, blkbits, ivbits);      \
364 }                                                                              \
365 const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = {                    \
366     { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))nm##_##kbits##_##sub##_newctx },\
367     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))nm##_##sub##_freectx },        \
368     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))nm##_einit },             \
369     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))nm##_dinit },             \
370     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))nm##_update },                  \
371     { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))nm##_final },                    \
372     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))nm##_cipher },                  \
373     { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
374         (void (*)(void))nm##_##kbits##_##sub##_get_params },                   \
375     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
376         (void (*)(void))nm##_gettable_params },                                \
377     { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
378          (void (*)(void))nm##_get_ctx_params },                                \
379     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
380         (void (*)(void))nm##_gettable_ctx_params },                            \
381     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
382         (void (*)(void))nm##_set_ctx_params },                                 \
383     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
384         (void (*)(void))nm##_settable_ctx_params },                            \
385     { 0, NULL }                                                                \
386 };
387
388 #endif /* AES_CBC_HMAC_SHA_CAPABLE */
389
390 /* ossl_aes128cbc_hmac_sha1_functions */
391 IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
392 /* ossl_aes256cbc_hmac_sha1_functions */
393 IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
394 /* ossl_aes128cbc_hmac_sha256_functions */
395 IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
396 /* ossl_aes256cbc_hmac_sha256_functions */
397 IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS)