]>
Commit | Line | Data |
---|---|---|
e1178600 | 1 | /* |
bd0c7129 | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
e1178600 SL |
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 | * Generic dispatch table functions for ciphers. | |
12 | */ | |
13 | ||
2d9f56e9 MC |
14 | /* For SSL3_VERSION */ |
15 | #include <openssl/ssl.h> | |
2741128e | 16 | #include <openssl/proverr.h> |
68a51d59 | 17 | #include "ciphercommon_local.h" |
ddd21319 | 18 | #include "prov/provider_ctx.h" |
f99d3eed | 19 | #include "prov/providercommon.h" |
e1178600 SL |
20 | |
21 | /*- | |
4a42e264 | 22 | * Generic cipher functions for OSSL_PARAM gettables and settables |
e1178600 SL |
23 | */ |
24 | static const OSSL_PARAM cipher_known_gettable_params[] = { | |
1c3ace68 SL |
25 | OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), |
26 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), | |
27 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), | |
28 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), | |
a054d15c SL |
29 | OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), |
30 | OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), | |
31 | OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), | |
32 | OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), | |
e71fd827 | 33 | { OSSL_CIPHER_PARAM_TLS_MAC, OSSL_PARAM_OCTET_PTR, NULL, 0, OSSL_PARAM_UNMODIFIED }, |
e1178600 SL |
34 | OSSL_PARAM_END |
35 | }; | |
644c5dd3 | 36 | const OSSL_PARAM *ossl_cipher_generic_gettable_params(ossl_unused void *provctx) |
e1178600 SL |
37 | { |
38 | return cipher_known_gettable_params; | |
39 | } | |
40 | ||
592dcfd3 | 41 | int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, |
a054d15c | 42 | uint64_t flags, |
592dcfd3 | 43 | size_t kbits, size_t blkbits, size_t ivbits) |
e1178600 SL |
44 | { |
45 | OSSL_PARAM *p; | |
46 | ||
47 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); | |
1c3ace68 | 48 | if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { |
e1178600 SL |
49 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
50 | return 0; | |
51 | } | |
a054d15c SL |
52 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); |
53 | if (p != NULL | |
54 | && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { | |
55 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
56 | return 0; | |
57 | } | |
58 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); | |
59 | if (p != NULL | |
60 | && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { | |
61 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
62 | return 0; | |
63 | } | |
64 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); | |
65 | if (p != NULL | |
66 | && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { | |
67 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
68 | return 0; | |
69 | } | |
70 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); | |
71 | if (p != NULL | |
72 | && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { | |
e1178600 SL |
73 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
74 | return 0; | |
75 | } | |
76 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); | |
1c3ace68 | 77 | if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { |
e1178600 SL |
78 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
79 | return 0; | |
80 | } | |
81 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); | |
1c3ace68 | 82 | if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { |
e1178600 SL |
83 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
84 | return 0; | |
85 | } | |
86 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); | |
1c3ace68 | 87 | if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { |
e1178600 SL |
88 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
89 | return 0; | |
90 | } | |
91 | return 1; | |
92 | } | |
93 | ||
592dcfd3 P |
94 | CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic) |
95 | CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_cipher_generic) | |
e1178600 | 96 | |
592dcfd3 | 97 | CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_generic) |
e71fd827 MC |
98 | OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL), |
99 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL), | |
592dcfd3 | 100 | CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_generic) |
e1178600 | 101 | |
d23adad1 MC |
102 | /* |
103 | * Variable key length cipher functions for OSSL_PARAM settables | |
104 | */ | |
592dcfd3 | 105 | int ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[]) |
d23adad1 MC |
106 | { |
107 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
108 | const OSSL_PARAM *p; | |
109 | ||
592dcfd3 | 110 | if (!ossl_cipher_generic_set_ctx_params(vctx, params)) |
d23adad1 MC |
111 | return 0; |
112 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); | |
113 | if (p != NULL) { | |
114 | size_t keylen; | |
115 | ||
116 | if (!OSSL_PARAM_get_size_t(p, &keylen)) { | |
117 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
118 | return 0; | |
119 | } | |
120 | ctx->keylen = keylen; | |
121 | } | |
122 | return 1; | |
123 | } | |
124 | ||
592dcfd3 | 125 | CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_var_keylen) |
d23adad1 | 126 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), |
592dcfd3 | 127 | CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_var_keylen) |
d23adad1 | 128 | |
e1178600 SL |
129 | /*- |
130 | * AEAD cipher functions for OSSL_PARAM gettables and settables | |
131 | */ | |
132 | static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = { | |
1c3ace68 SL |
133 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), |
134 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), | |
dc64dc2e | 135 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), |
e1178600 | 136 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), |
0d83b7b9 | 137 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), |
e1178600 SL |
138 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), |
139 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), | |
11b44359 | 140 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), |
e1178600 SL |
141 | OSSL_PARAM_END |
142 | }; | |
592dcfd3 | 143 | const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params( |
644c5dd3 | 144 | ossl_unused void *cctx, ossl_unused void *provctx |
592dcfd3 | 145 | ) |
e1178600 SL |
146 | { |
147 | return cipher_aead_known_gettable_ctx_params; | |
148 | } | |
149 | ||
150 | static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = { | |
e1178600 SL |
151 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), |
152 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), | |
153 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), | |
154 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), | |
11b44359 | 155 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), |
e1178600 SL |
156 | OSSL_PARAM_END |
157 | }; | |
592dcfd3 | 158 | const OSSL_PARAM *ossl_cipher_aead_settable_ctx_params( |
644c5dd3 | 159 | ossl_unused void *cctx, ossl_unused void *provctx |
592dcfd3 | 160 | ) |
e1178600 SL |
161 | { |
162 | return cipher_aead_known_settable_ctx_params; | |
163 | } | |
164 | ||
592dcfd3 | 165 | void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx) |
63ee6ec1 MC |
166 | { |
167 | if (ctx != NULL && ctx->alloced) { | |
168 | OPENSSL_free(ctx->tlsmac); | |
169 | ctx->alloced = 0; | |
170 | ctx->tlsmac = NULL; | |
171 | } | |
172 | } | |
173 | ||
e1178600 SL |
174 | static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx, |
175 | const unsigned char *key, size_t keylen, | |
176 | const unsigned char *iv, size_t ivlen, | |
177 | int enc) | |
178 | { | |
90409da6 | 179 | ctx->num = 0; |
914f97ee | 180 | ctx->bufsz = 0; |
90409da6 | 181 | ctx->updated = 0; |
1c3ace68 | 182 | ctx->enc = enc ? 1 : 0; |
e1178600 | 183 | |
f99d3eed P |
184 | if (!ossl_prov_is_running()) |
185 | return 0; | |
186 | ||
e1178600 | 187 | if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { |
592dcfd3 | 188 | if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) |
e1178600 | 189 | return 0; |
e1178600 SL |
190 | } |
191 | if (key != NULL) { | |
a054d15c | 192 | if (ctx->variable_keylength == 0) { |
55c7dc79 | 193 | if (keylen != ctx->keylen) { |
f5f29796 | 194 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); |
55c7dc79 SL |
195 | return 0; |
196 | } | |
197 | } else { | |
198 | ctx->keylen = keylen; | |
e1178600 SL |
199 | } |
200 | return ctx->hw->init(ctx, key, ctx->keylen); | |
201 | } | |
202 | return 1; | |
203 | } | |
204 | ||
592dcfd3 P |
205 | int ossl_cipher_generic_einit(void *vctx, const unsigned char *key, |
206 | size_t keylen, const unsigned char *iv, | |
207 | size_t ivlen) | |
e1178600 SL |
208 | { |
209 | return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen, | |
210 | iv, ivlen, 1); | |
211 | } | |
212 | ||
592dcfd3 P |
213 | int ossl_cipher_generic_dinit(void *vctx, const unsigned char *key, |
214 | size_t keylen, const unsigned char *iv, | |
215 | size_t ivlen) | |
e1178600 SL |
216 | { |
217 | return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen, | |
218 | iv, ivlen, 0); | |
219 | } | |
220 | ||
2d9f56e9 MC |
221 | /* Max padding including padding length byte */ |
222 | #define MAX_PADDING 256 | |
223 | ||
592dcfd3 P |
224 | int ossl_cipher_generic_block_update(void *vctx, unsigned char *out, |
225 | size_t *outl, size_t outsize, | |
226 | const unsigned char *in, size_t inl) | |
e1178600 SL |
227 | { |
228 | size_t outlint = 0; | |
229 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
4a42e264 | 230 | size_t blksz = ctx->blocksize; |
c339c702 KR |
231 | size_t nextblocks; |
232 | ||
e71fd827 MC |
233 | if (ctx->tlsversion > 0) { |
234 | /* | |
235 | * Each update call corresponds to a TLS record and is individually | |
236 | * padded | |
237 | */ | |
238 | ||
239 | /* Sanity check inputs */ | |
2d9f56e9 | 240 | if (in == NULL |
e71fd827 MC |
241 | || in != out |
242 | || outsize < inl | |
243 | || !ctx->pad) { | |
244 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
245 | return 0; | |
246 | } | |
247 | ||
2d9f56e9 MC |
248 | if (ctx->enc) { |
249 | unsigned char padval; | |
250 | size_t padnum, loop; | |
251 | ||
252 | /* Add padding */ | |
253 | ||
254 | padnum = blksz - (inl % blksz); | |
255 | ||
256 | if (outsize < inl + padnum) { | |
257 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
258 | return 0; | |
259 | } | |
260 | ||
261 | if (padnum > MAX_PADDING) { | |
262 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
263 | return 0; | |
264 | } | |
265 | padval = (unsigned char)(padnum - 1); | |
266 | if (ctx->tlsversion == SSL3_VERSION) { | |
267 | if (padnum > 1) | |
268 | memset(out + inl, 0, padnum - 1); | |
269 | *(out + inl + padnum - 1) = padval; | |
270 | } else { | |
271 | /* we need to add 'padnum' padding bytes of value padval */ | |
272 | for (loop = inl; loop < inl + padnum; loop++) | |
273 | out[loop] = padval; | |
274 | } | |
275 | inl += padnum; | |
276 | } | |
277 | ||
278 | if ((inl % blksz) != 0) { | |
279 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
280 | return 0; | |
281 | } | |
282 | ||
283 | ||
e71fd827 MC |
284 | /* Shouldn't normally fail */ |
285 | if (!ctx->hw->cipher(ctx, out, in, inl)) { | |
286 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
287 | return 0; | |
288 | } | |
289 | ||
63ee6ec1 MC |
290 | if (ctx->alloced) { |
291 | OPENSSL_free(ctx->tlsmac); | |
292 | ctx->alloced = 0; | |
293 | ctx->tlsmac = NULL; | |
294 | } | |
295 | ||
e71fd827 | 296 | /* This only fails if padding is publicly invalid */ |
e71fd827 MC |
297 | *outl = inl; |
298 | if (!ctx->enc | |
e36b3c2f SL |
299 | && !ossl_cipher_tlsunpadblock(ctx->libctx, ctx->tlsversion, |
300 | out, outl, | |
301 | blksz, &ctx->tlsmac, &ctx->alloced, | |
302 | ctx->tlsmacsize, 0)) { | |
e71fd827 MC |
303 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); |
304 | return 0; | |
305 | } | |
306 | return 1; | |
307 | } | |
308 | ||
c339c702 | 309 | if (ctx->bufsz != 0) |
e36b3c2f SL |
310 | nextblocks = ossl_cipher_fillblock(ctx->buf, &ctx->bufsz, blksz, |
311 | &in, &inl); | |
c339c702 KR |
312 | else |
313 | nextblocks = inl & ~(blksz-1); | |
e1178600 SL |
314 | |
315 | /* | |
316 | * If we're decrypting and we end an update on a block boundary we hold | |
317 | * the last block back in case this is the last update call and the last | |
318 | * block is padded. | |
319 | */ | |
4a42e264 SL |
320 | if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) { |
321 | if (outsize < blksz) { | |
e1178600 SL |
322 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); |
323 | return 0; | |
324 | } | |
4a42e264 | 325 | if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) { |
e1178600 SL |
326 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); |
327 | return 0; | |
328 | } | |
329 | ctx->bufsz = 0; | |
4a42e264 SL |
330 | outlint = blksz; |
331 | out += blksz; | |
e1178600 SL |
332 | } |
333 | if (nextblocks > 0) { | |
334 | if (!ctx->enc && ctx->pad && nextblocks == inl) { | |
4a42e264 | 335 | if (!ossl_assert(inl >= blksz)) { |
e1178600 SL |
336 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); |
337 | return 0; | |
338 | } | |
4a42e264 | 339 | nextblocks -= blksz; |
e1178600 SL |
340 | } |
341 | outlint += nextblocks; | |
342 | if (outsize < outlint) { | |
343 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); | |
344 | return 0; | |
345 | } | |
51356a06 PS |
346 | } |
347 | if (nextblocks > 0) { | |
e1178600 SL |
348 | if (!ctx->hw->cipher(ctx, out, in, nextblocks)) { |
349 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
350 | return 0; | |
351 | } | |
352 | in += nextblocks; | |
353 | inl -= nextblocks; | |
354 | } | |
e36b3c2f SL |
355 | if (inl != 0 |
356 | && !ossl_cipher_trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) { | |
e1178600 SL |
357 | /* ERR_raise already called */ |
358 | return 0; | |
359 | } | |
360 | ||
361 | *outl = outlint; | |
362 | return inl == 0; | |
363 | } | |
364 | ||
592dcfd3 P |
365 | int ossl_cipher_generic_block_final(void *vctx, unsigned char *out, |
366 | size_t *outl, size_t outsize) | |
e1178600 SL |
367 | { |
368 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
4a42e264 | 369 | size_t blksz = ctx->blocksize; |
e1178600 | 370 | |
f99d3eed P |
371 | if (!ossl_prov_is_running()) |
372 | return 0; | |
373 | ||
e71fd827 MC |
374 | if (ctx->tlsversion > 0) { |
375 | /* We never finalize TLS, so this is an error */ | |
376 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
377 | return 0; | |
378 | } | |
379 | ||
e1178600 SL |
380 | if (ctx->enc) { |
381 | if (ctx->pad) { | |
e36b3c2f | 382 | ossl_cipher_padblock(ctx->buf, &ctx->bufsz, blksz); |
e1178600 SL |
383 | } else if (ctx->bufsz == 0) { |
384 | *outl = 0; | |
385 | return 1; | |
4a42e264 | 386 | } else if (ctx->bufsz != blksz) { |
e1178600 SL |
387 | ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); |
388 | return 0; | |
389 | } | |
390 | ||
4a42e264 | 391 | if (outsize < blksz) { |
e1178600 SL |
392 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); |
393 | return 0; | |
394 | } | |
4a42e264 | 395 | if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) { |
e1178600 SL |
396 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); |
397 | return 0; | |
398 | } | |
399 | ctx->bufsz = 0; | |
4a42e264 | 400 | *outl = blksz; |
e1178600 SL |
401 | return 1; |
402 | } | |
403 | ||
404 | /* Decrypting */ | |
4a42e264 | 405 | if (ctx->bufsz != blksz) { |
e1178600 SL |
406 | if (ctx->bufsz == 0 && !ctx->pad) { |
407 | *outl = 0; | |
408 | return 1; | |
409 | } | |
410 | ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); | |
411 | return 0; | |
412 | } | |
413 | ||
4a42e264 | 414 | if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) { |
e1178600 SL |
415 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); |
416 | return 0; | |
417 | } | |
418 | ||
e36b3c2f | 419 | if (ctx->pad && !ossl_cipher_unpadblock(ctx->buf, &ctx->bufsz, blksz)) { |
e1178600 SL |
420 | /* ERR_raise already called */ |
421 | return 0; | |
422 | } | |
423 | ||
424 | if (outsize < ctx->bufsz) { | |
425 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); | |
426 | return 0; | |
427 | } | |
428 | memcpy(out, ctx->buf, ctx->bufsz); | |
429 | *outl = ctx->bufsz; | |
430 | ctx->bufsz = 0; | |
431 | return 1; | |
432 | } | |
433 | ||
592dcfd3 P |
434 | int ossl_cipher_generic_stream_update(void *vctx, unsigned char *out, |
435 | size_t *outl, size_t outsize, | |
436 | const unsigned char *in, size_t inl) | |
e1178600 SL |
437 | { |
438 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
439 | ||
4b9c750b MC |
440 | if (inl == 0) { |
441 | *outl = 0; | |
442 | return 1; | |
443 | } | |
444 | ||
e1178600 SL |
445 | if (outsize < inl) { |
446 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); | |
447 | return 0; | |
448 | } | |
449 | ||
450 | if (!ctx->hw->cipher(ctx, out, in, inl)) { | |
451 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
452 | return 0; | |
453 | } | |
454 | ||
455 | *outl = inl; | |
e260bee0 | 456 | if (!ctx->enc && ctx->tlsversion > 0) { |
01c6551c MC |
457 | /* |
458 | * Remove any TLS padding. Only used by cipher_aes_cbc_hmac_sha1_hw.c and | |
459 | * cipher_aes_cbc_hmac_sha256_hw.c | |
460 | */ | |
6db0d58d MC |
461 | if (ctx->removetlspad) { |
462 | /* | |
463 | * We should have already failed in the cipher() call above if this | |
464 | * isn't true. | |
465 | */ | |
466 | if (!ossl_assert(*outl >= (size_t)(out[inl - 1] + 1))) | |
467 | return 0; | |
01c6551c MC |
468 | /* The actual padding length */ |
469 | *outl -= out[inl - 1] + 1; | |
01c6551c | 470 | } |
f29dbb08 | 471 | |
6db0d58d MC |
472 | /* TLS MAC and explicit IV if relevant. We should have already failed |
473 | * in the cipher() call above if *outl is too short. | |
474 | */ | |
475 | if (!ossl_assert(*outl >= ctx->removetlsfixed)) | |
476 | return 0; | |
477 | *outl -= ctx->removetlsfixed; | |
478 | ||
01c6551c MC |
479 | /* Extract the MAC if there is one */ |
480 | if (ctx->tlsmacsize > 0) { | |
481 | if (*outl < ctx->tlsmacsize) | |
482 | return 0; | |
483 | ||
484 | ctx->tlsmac = out + *outl - ctx->tlsmacsize; | |
485 | *outl -= ctx->tlsmacsize; | |
486 | } | |
f29dbb08 MC |
487 | } |
488 | ||
e1178600 SL |
489 | return 1; |
490 | } | |
592dcfd3 P |
491 | int ossl_cipher_generic_stream_final(void *vctx, unsigned char *out, |
492 | size_t *outl, size_t outsize) | |
e1178600 | 493 | { |
f99d3eed P |
494 | if (!ossl_prov_is_running()) |
495 | return 0; | |
496 | ||
e1178600 SL |
497 | *outl = 0; |
498 | return 1; | |
499 | } | |
500 | ||
592dcfd3 P |
501 | int ossl_cipher_generic_cipher(void *vctx, unsigned char *out, size_t *outl, |
502 | size_t outsize, const unsigned char *in, | |
503 | size_t inl) | |
e1178600 SL |
504 | { |
505 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
506 | ||
f99d3eed P |
507 | if (!ossl_prov_is_running()) |
508 | return 0; | |
509 | ||
e1178600 SL |
510 | if (outsize < inl) { |
511 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); | |
512 | return 0; | |
513 | } | |
514 | ||
515 | if (!ctx->hw->cipher(ctx, out, in, inl)) { | |
516 | ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); | |
517 | return 0; | |
518 | } | |
519 | ||
520 | *outl = inl; | |
521 | return 1; | |
522 | } | |
523 | ||
592dcfd3 | 524 | int ossl_cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[]) |
e1178600 SL |
525 | { |
526 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
527 | OSSL_PARAM *p; | |
528 | ||
529 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); | |
1c3ace68 | 530 | if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) { |
e1178600 SL |
531 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
532 | return 0; | |
533 | } | |
534 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); | |
1c3ace68 | 535 | if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) { |
e1178600 SL |
536 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
537 | return 0; | |
538 | } | |
539 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); | |
540 | if (p != NULL | |
089cb623 SL |
541 | && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen) |
542 | && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) { | |
e1178600 SL |
543 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
544 | return 0; | |
545 | } | |
0d83b7b9 | 546 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); |
84890268 BK |
547 | if (p != NULL |
548 | && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen) | |
549 | && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) { | |
550 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
551 | return 0; | |
552 | } | |
e1178600 | 553 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM); |
1c3ace68 | 554 | if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) { |
e1178600 SL |
555 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
556 | return 0; | |
557 | } | |
558 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); | |
1c3ace68 | 559 | if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { |
e1178600 SL |
560 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); |
561 | return 0; | |
562 | } | |
e71fd827 MC |
563 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC); |
564 | if (p != NULL | |
565 | && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) { | |
566 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
567 | return 0; | |
568 | } | |
e1178600 SL |
569 | return 1; |
570 | } | |
571 | ||
592dcfd3 | 572 | int ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[]) |
e1178600 SL |
573 | { |
574 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
575 | const OSSL_PARAM *p; | |
576 | ||
577 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING); | |
578 | if (p != NULL) { | |
1c3ace68 | 579 | unsigned int pad; |
e1178600 | 580 | |
1c3ace68 | 581 | if (!OSSL_PARAM_get_uint(p, &pad)) { |
e1178600 SL |
582 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); |
583 | return 0; | |
584 | } | |
585 | ctx->pad = pad ? 1 : 0; | |
586 | } | |
e71fd827 MC |
587 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION); |
588 | if (p != NULL) { | |
589 | if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) { | |
590 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
591 | return 0; | |
592 | } | |
593 | } | |
594 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE); | |
595 | if (p != NULL) { | |
596 | if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) { | |
597 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
598 | return 0; | |
599 | } | |
600 | } | |
e1178600 SL |
601 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM); |
602 | if (p != NULL) { | |
1c3ace68 | 603 | unsigned int num; |
e1178600 | 604 | |
1c3ace68 | 605 | if (!OSSL_PARAM_get_uint(p, &num)) { |
e1178600 SL |
606 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); |
607 | return 0; | |
608 | } | |
609 | ctx->num = num; | |
610 | } | |
e1178600 SL |
611 | return 1; |
612 | } | |
613 | ||
592dcfd3 P |
614 | int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, |
615 | size_t ivlen) | |
089cb623 SL |
616 | { |
617 | if (ivlen != ctx->ivlen | |
618 | || ivlen > sizeof(ctx->iv)) { | |
f5f29796 | 619 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); |
089cb623 SL |
620 | return 0; |
621 | } | |
622 | ctx->iv_set = 1; | |
623 | memcpy(ctx->iv, iv, ivlen); | |
624 | memcpy(ctx->oiv, iv, ivlen); | |
625 | return 1; | |
626 | } | |
627 | ||
592dcfd3 P |
628 | void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, |
629 | size_t ivbits, unsigned int mode, | |
630 | uint64_t flags, const PROV_CIPHER_HW *hw, | |
631 | void *provctx) | |
e1178600 SL |
632 | { |
633 | PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; | |
634 | ||
a054d15c SL |
635 | if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0) |
636 | ctx->inverse_cipher = 1; | |
637 | if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0) | |
638 | ctx->variable_keylength = 1; | |
639 | ||
e1178600 SL |
640 | ctx->pad = 1; |
641 | ctx->keylen = ((kbits) / 8); | |
4a42e264 | 642 | ctx->ivlen = ((ivbits) / 8); |
e1178600 SL |
643 | ctx->hw = hw; |
644 | ctx->mode = mode; | |
4a42e264 SL |
645 | ctx->blocksize = blkbits / 8; |
646 | if (provctx != NULL) | |
a829b735 | 647 | ctx->libctx = PROV_LIBCTX_OF(provctx); /* used for rand */ |
e1178600 | 648 | } |