34bd3c151fc0448ebc5c16d1d87dd88cb60bbfc3
[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         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
234         return 0;
235     }
236     return 1;
237 }
238
239 static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = {
240 # if !defined(OPENSSL_NO_MULTIBLOCK)
241     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, NULL),
242     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL),
243     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, NULL),
244     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, NULL),
245 # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
246     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
247     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
248     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
249     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
250     OSSL_PARAM_END
251 };
252 const OSSL_PARAM *aes_gettable_ctx_params(void)
253 {
254     return cipher_aes_known_gettable_ctx_params;
255 }
256
257 static void base_init(void *provctx, PROV_AES_HMAC_SHA_CTX *ctx,
258                       const PROV_CIPHER_HW_AES_HMAC_SHA *meths,
259                       size_t kbits, size_t blkbits, size_t ivbits,
260                       uint64_t flags)
261 {
262     cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits,
263                            EVP_CIPH_CBC_MODE, flags,
264                            &meths->base, provctx);
265     ctx->hw = (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->base.hw;
266 }
267
268 static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits,
269                                       size_t blkbits, size_t ivbits,
270                                       uint64_t flags)
271 {
272     PROV_AES_HMAC_SHA1_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
273
274     if (ctx != NULL)
275         base_init(provctx, &ctx->base_ctx,
276                   PROV_CIPHER_HW_aes_cbc_hmac_sha1(), kbits, blkbits,
277                   ivbits, flags);
278     return ctx;
279 }
280
281 static void aes_cbc_hmac_sha1_freectx(void *vctx)
282 {
283     PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx;
284
285     if (ctx != NULL)
286         OPENSSL_clear_free(ctx, sizeof(*ctx));
287 }
288
289 static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits,
290                                         size_t blkbits, size_t ivbits,
291                                         uint64_t flags)
292 {
293     PROV_AES_HMAC_SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
294
295     if (ctx != NULL)
296         base_init(provctx, &ctx->base_ctx,
297                   PROV_CIPHER_HW_aes_cbc_hmac_sha256(), kbits, blkbits,
298                   ivbits, flags);
299     return ctx;
300 }
301
302 static void aes_cbc_hmac_sha256_freectx(void *vctx)
303 {
304     PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx;
305
306     if (ctx != NULL)
307         OPENSSL_clear_free(ctx, sizeof(*ctx));
308 }
309
310 # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags)               \
311 static OSSL_OP_cipher_newctx_fn nm##_##kbits##_##sub##_newctx;                 \
312 static void *nm##_##kbits##_##sub##_newctx(void *provctx)                      \
313 {                                                                              \
314     return nm##_##sub##_newctx(provctx, kbits, blkbits, ivbits, flags);        \
315 }                                                                              \
316 static OSSL_OP_cipher_get_params_fn nm##_##kbits##_##sub##_get_params;         \
317 static int nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[])              \
318 {                                                                              \
319     return cipher_generic_get_params(params, EVP_CIPH_CBC_MODE,                \
320                                      flags, kbits, blkbits, ivbits);           \
321 }                                                                              \
322 const OSSL_DISPATCH nm##kbits##sub##_functions[] = {                           \
323     { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))nm##_##kbits##_##sub##_newctx },\
324     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))nm##_##sub##_freectx },        \
325     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))nm##_einit },             \
326     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))nm##_dinit },             \
327     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))nm##_update },                  \
328     { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))nm##_final },                    \
329     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))nm##_cipher },                  \
330     { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
331         (void (*)(void))nm##_##kbits##_##sub##_get_params },                   \
332     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
333         (void (*)(void))nm##_gettable_params },                                \
334     { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
335          (void (*)(void))nm##_get_ctx_params },                                \
336     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
337         (void (*)(void))nm##_gettable_ctx_params },                            \
338     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
339         (void (*)(void))nm##_set_ctx_params },                                 \
340     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
341         (void (*)(void))nm##_settable_ctx_params },                            \
342     { 0, NULL }                                                                \
343 };
344
345 #endif /* AES_CBC_HMAC_SHA_CAPABLE */
346
347 /* aes128cbc_hmac_sha1_functions */
348 IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
349 /* aes256cbc_hmac_sha1_functions */
350 IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
351 /* aes128cbc_hmac_sha256_functions */
352 IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS)
353 /* aes256cbc_hmac_sha256_functions */
354 IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS)