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