ece4341a3fd73c74a3fc41161c21a48950ccf11a
[openssl.git] / providers / implementations / ciphers / cipher_aes_cbc_hmac_sha.c
1 /*
2  * Copyright 2019-2020 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 #include "cipher_aes_cbc_hmac_sha.h"
20 #include "prov/implementations.h"
21
22 #ifndef AES_CBC_HMAC_SHA_CAPABLE
23 # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags)              \
24 const OSSL_DISPATCH nm##kbits##sub##_functions[] = {                           \
25     { 0, NULL }                                                                \
26 };
27 #else
28 # include "prov/providercommonerr.h"
29
30 /* TODO(3.0) Figure out what flags are required */
31 # define AES_CBC_HMAC_SHA_FLAGS (EVP_CIPH_CBC_MODE                             \
32                                  | EVP_CIPH_FLAG_DEFAULT_ASN1                  \
33                                  | EVP_CIPH_FLAG_AEAD_CIPHER                   \
34                                  | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)
35
36 static OSSL_OP_cipher_freectx_fn aes_cbc_hmac_sha1_freectx;
37 static OSSL_OP_cipher_freectx_fn aes_cbc_hmac_sha256_freectx;
38 static OSSL_OP_cipher_get_ctx_params_fn aes_get_ctx_params;
39 static OSSL_OP_cipher_gettable_ctx_params_fn aes_gettable_ctx_params;
40 static OSSL_OP_cipher_set_ctx_params_fn aes_set_ctx_params;
41 static OSSL_OP_cipher_settable_ctx_params_fn aes_settable_ctx_params;
42 # define aes_gettable_params cipher_generic_gettable_params
43 # define aes_einit cipher_generic_einit
44 # define aes_dinit cipher_generic_dinit
45 # define aes_update cipher_generic_stream_update
46 # define aes_final cipher_generic_stream_final
47 # define aes_cipher 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(void)
63 {
64     return cipher_aes_known_settable_ctx_params;
65 }
66
67 static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
68 {
69     PROV_AES_HMAC_SHA_CTX *ctx = (PROV_AES_HMAC_SHA_CTX *)vctx;
70     PROV_CIPHER_HW_AES_HMAC_SHA *hw =
71        (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->hw;
72     const OSSL_PARAM *p;
73     int ret = 1;
74 # if !defined(OPENSSL_NO_MULTIBLOCK)
75     EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
76 # endif
77
78     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_MAC_KEY);
79     if (p != NULL) {
80         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
81             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
82             return 0;
83         }
84         hw->init_mac_key(ctx, p->data, p->data_size);
85     }
86
87 # if !defined(OPENSSL_NO_MULTIBLOCK)
88     p = OSSL_PARAM_locate_const(params,
89             OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT);
90     if (p != NULL
91             && !OSSL_PARAM_get_size_t(p, &ctx->multiblock_max_send_fragment)) {
92         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
93         return 0;
94     }
95     /*
96      * The inputs to tls1_multiblock_aad are:
97      *   mb_param->inp
98      *   mb_param->len
99      *   mb_param->interleave
100      * The outputs of tls1_multiblock_aad are written to:
101      *   ctx->multiblock_interleave
102      *   ctx->multiblock_aad_packlen
103      */
104     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD);
105     if (p != NULL) {
106         const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params,
107                                    OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
108         if (p->data_type != OSSL_PARAM_OCTET_STRING
109             || p1 == NULL
110             || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) {
111             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
112             return 0;
113         }
114         mb_param.inp = p->data;
115         mb_param.len = p->data_size;
116         if (hw->tls1_multiblock_aad(vctx, &mb_param) <= 0)
117             return 0;
118     }
119
120     /*
121      * The inputs to tls1_multiblock_encrypt are:
122      *   mb_param->inp
123      *   mb_param->len
124      *   mb_param->interleave
125      *   mb_param->out
126      * The outputs of tls1_multiblock_encrypt are:
127      *   ctx->multiblock_encrypt_len
128      */
129     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC);
130     if (p != NULL) {
131         const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params,
132                                    OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
133         const OSSL_PARAM *pin = OSSL_PARAM_locate_const(params,
134                                     OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN);
135
136         if (p->data_type != OSSL_PARAM_OCTET_STRING
137             || pin == NULL
138             || pin->data_type != OSSL_PARAM_OCTET_STRING
139             || p1 == NULL
140             || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) {
141             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
142             return 0;
143         }
144         mb_param.out = p->data;
145         mb_param.inp = pin->data;
146         mb_param.len = pin->data_size;
147         if (hw->tls1_multiblock_encrypt(vctx, &mb_param) <= 0)
148             return 0;
149     }
150 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
151
152     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
153     if (p != NULL) {
154         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
155             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
156             return 0;
157         }
158         if (hw->set_tls1_aad(ctx, p->data, p->data_size) <= 0)
159             return 0;
160     }
161
162     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
163     if (p != NULL) {
164         size_t keylen;
165
166         if (!OSSL_PARAM_get_size_t(p, &keylen)) {
167             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
168             return 0;
169         }
170         if (ctx->base.keylen != keylen) {
171             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
172             return 0;
173         }
174     }
175     return ret;
176 }
177
178 static int aes_get_ctx_params(void *vctx, OSSL_PARAM params[])
179 {
180     PROV_AES_HMAC_SHA_CTX *ctx = (PROV_AES_HMAC_SHA_CTX *)vctx;
181     OSSL_PARAM *p;
182
183 # if !defined(OPENSSL_NO_MULTIBLOCK)
184     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE);
185     if (p != NULL) {
186         PROV_CIPHER_HW_AES_HMAC_SHA *hw =
187            (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->hw;
188         size_t len = hw->tls1_multiblock_max_bufsize(ctx);
189
190         if (!OSSL_PARAM_set_size_t(p, len)) {
191             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
192             return 0;
193         }
194     }
195
196     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
197     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->multiblock_interleave)) {
198         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
199         return 0;
200     }
201
202     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN);
203     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->multiblock_aad_packlen)) {
204         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
205         return 0;
206     }
207
208     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN);
209     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->multiblock_encrypt_len)) {
210         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
211         return 0;
212     }
213 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
214
215     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
216     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad)) {
217         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
218         return 0;
219     }
220     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
221     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.keylen)) {
222         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
223         return 0;
224     }
225     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
226     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.ivlen)) {
227         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
228         return 0;
229     }
230     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
231     if (p != NULL
232         && !OSSL_PARAM_set_octet_string(p, ctx->base.oiv, ctx->base.ivlen)
233         && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.oiv, ctx->base.ivlen)) {
234         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
235         return 0;
236     }
237     return 1;
238 }
239
240 static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = {
241 # if !defined(OPENSSL_NO_MULTIBLOCK)
242     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, NULL),
243     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL),
244     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, NULL),
245     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, NULL),
246 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
247     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
248     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
249     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
250     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
251     OSSL_PARAM_END
252 };
253 const OSSL_PARAM *aes_gettable_ctx_params(void)
254 {
255     return cipher_aes_known_gettable_ctx_params;
256 }
257
258 static void base_init(void *provctx, PROV_AES_HMAC_SHA_CTX *ctx,
259                       const PROV_CIPHER_HW_AES_HMAC_SHA *meths,
260                       size_t kbits, size_t blkbits, size_t ivbits,
261                       uint64_t flags)
262 {
263     cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits,
264                            EVP_CIPH_CBC_MODE, flags,
265                            &meths->base, provctx);
266     ctx->hw = (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->base.hw;
267 }
268
269 static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits,
270                                       size_t blkbits, size_t ivbits,
271                                       uint64_t flags)
272 {
273     PROV_AES_HMAC_SHA1_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
274
275     if (ctx != NULL)
276         base_init(provctx, &ctx->base_ctx,
277                   PROV_CIPHER_HW_aes_cbc_hmac_sha1(), kbits, blkbits,
278                   ivbits, flags);
279     return ctx;
280 }
281
282 static void aes_cbc_hmac_sha1_freectx(void *vctx)
283 {
284     PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx;
285
286     if (ctx != NULL)
287         OPENSSL_clear_free(ctx, sizeof(*ctx));
288 }
289
290 static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits,
291                                         size_t blkbits, size_t ivbits,
292                                         uint64_t flags)
293 {
294     PROV_AES_HMAC_SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
295
296     if (ctx != NULL)
297         base_init(provctx, &ctx->base_ctx,
298                   PROV_CIPHER_HW_aes_cbc_hmac_sha256(), kbits, blkbits,
299                   ivbits, flags);
300     return ctx;
301 }
302
303 static void aes_cbc_hmac_sha256_freectx(void *vctx)
304 {
305     PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx;
306
307     if (ctx != NULL)
308         OPENSSL_clear_free(ctx, sizeof(*ctx));
309 }
310
311 # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags)               \
312 static OSSL_OP_cipher_newctx_fn nm##_##kbits##_##sub##_newctx;                 \
313 static void *nm##_##kbits##_##sub##_newctx(void *provctx)                      \
314 {                                                                              \
315     return nm##_##sub##_newctx(provctx, kbits, blkbits, ivbits, flags);        \
316 }                                                                              \
317 static OSSL_OP_cipher_get_params_fn nm##_##kbits##_##sub##_get_params;         \
318 static int nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[])              \
319 {                                                                              \
320     return cipher_generic_get_params(params, EVP_CIPH_CBC_MODE,                \
321                                      flags, kbits, blkbits, ivbits);           \
322 }                                                                              \
323 const OSSL_DISPATCH nm##kbits##sub##_functions[] = {                           \
324     { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))nm##_##kbits##_##sub##_newctx },\
325     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))nm##_##sub##_freectx },        \
326     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))nm##_einit },             \
327     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))nm##_dinit },             \
328     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))nm##_update },                  \
329     { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))nm##_final },                    \
330     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))nm##_cipher },                  \
331     { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
332         (void (*)(void))nm##_##kbits##_##sub##_get_params },                   \
333     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
334         (void (*)(void))nm##_gettable_params },                                \
335     { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
336          (void (*)(void))nm##_get_ctx_params },                                \
337     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
338         (void (*)(void))nm##_gettable_ctx_params },                            \
339     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
340         (void (*)(void))nm##_set_ctx_params },                                 \
341     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
342         (void (*)(void))nm##_settable_ctx_params },                            \
343     { 0, NULL }                                                                \
344 };
345
346 #endif /* AES_CBC_HMAC_SHA_CAPABLE */
347
348 /* aes128cbc_hmac_sha1_functions */
349 IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
350 /* aes256cbc_hmac_sha1_functions */
351 IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
352 /* aes128cbc_hmac_sha256_functions */
353 IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
354 /* aes256cbc_hmac_sha256_functions */
355 IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS)