0b0219c7adfe92e573174f98c067c5a19d8ce785
[openssl.git] / providers / implementations / ciphers / ciphercommon.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  * Generic dispatch table functions for ciphers.
12  */
13
14 #include "ciphercommon_local.h"
15 #include "prov/provider_ctx.h"
16 #include "prov/providercommonerr.h"
17
18 /*-
19  * Generic cipher functions for OSSL_PARAM gettables and settables
20  */
21 static const OSSL_PARAM cipher_known_gettable_params[] = {
22     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL),
23     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
24     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
25     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
26     OSSL_PARAM_ulong(OSSL_CIPHER_PARAM_FLAGS, NULL),
27     { OSSL_CIPHER_PARAM_TLS_MAC, OSSL_PARAM_OCTET_PTR, NULL, 0, OSSL_PARAM_UNMODIFIED },
28     OSSL_PARAM_END
29 };
30 const OSSL_PARAM *cipher_generic_gettable_params(void)
31 {
32     return cipher_known_gettable_params;
33 }
34
35 int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
36                               unsigned long flags,
37                               size_t kbits, size_t blkbits, size_t ivbits)
38 {
39     OSSL_PARAM *p;
40
41     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
42     if (p != NULL && !OSSL_PARAM_set_uint(p, md)) {
43         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
44         return 0;
45     }
46     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_FLAGS);
47     if (p != NULL && !OSSL_PARAM_set_ulong(p, flags)) {
48         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
49         return 0;
50     }
51     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
52     if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) {
53         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
54         return 0;
55     }
56     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
57     if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) {
58         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
59         return 0;
60     }
61     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
62     if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) {
63         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
64         return 0;
65     }
66     return 1;
67 }
68
69 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
70 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
71
72 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic)
73 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL),
74 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL),
75 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic)
76
77 /*
78  * Variable key length cipher functions for OSSL_PARAM settables
79  */
80
81 int cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[])
82 {
83     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
84     const OSSL_PARAM *p;
85
86     if (!cipher_generic_set_ctx_params(vctx, params))
87         return 0;
88     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
89     if (p != NULL) {
90         size_t keylen;
91
92         if (!OSSL_PARAM_get_size_t(p, &keylen)) {
93             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
94             return 0;
95         }
96         ctx->keylen = keylen;
97     }
98     return 1;
99 }
100
101 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_var_keylen)
102 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
103 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_var_keylen)
104
105 /*-
106  * AEAD cipher functions for OSSL_PARAM gettables and settables
107  */
108 static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
109     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
110     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
111     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
112     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
113     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
114     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
115     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
116     OSSL_PARAM_END
117 };
118 const OSSL_PARAM *cipher_aead_gettable_ctx_params(void)
119 {
120     return cipher_aead_known_gettable_ctx_params;
121 }
122
123 static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
124     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
125     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
126     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
127     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
128     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0),
129     OSSL_PARAM_END
130 };
131 const OSSL_PARAM *cipher_aead_settable_ctx_params(void)
132 {
133     return cipher_aead_known_settable_ctx_params;
134 }
135
136 static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
137                                         const unsigned char *key, size_t keylen,
138                                         const unsigned char *iv, size_t ivlen,
139                                         int enc)
140 {
141     ctx->enc = enc ? 1 : 0;
142
143     if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
144         if (!cipher_generic_initiv(ctx, iv, ivlen))
145             return 0;
146     }
147     if (key != NULL) {
148         if ((ctx->flags & EVP_CIPH_VARIABLE_LENGTH) == 0) {
149             if (keylen != ctx->keylen) {
150                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
151                 return 0;
152             }
153         } else {
154             ctx->keylen = keylen;
155         }
156         return ctx->hw->init(ctx, key, ctx->keylen);
157     }
158     return 1;
159 }
160
161 int cipher_generic_einit(void *vctx, const unsigned char *key, size_t keylen,
162                          const unsigned char *iv, size_t ivlen)
163 {
164     return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
165                                         iv, ivlen, 1);
166 }
167
168 int cipher_generic_dinit(void *vctx, const unsigned char *key, size_t keylen,
169                          const unsigned char *iv, size_t ivlen)
170 {
171     return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
172                                         iv, ivlen, 0);
173 }
174
175 int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,
176                                 size_t outsize, const unsigned char *in,
177                                 size_t inl)
178 {
179     size_t outlint = 0;
180     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
181     size_t blksz = ctx->blocksize;
182     size_t nextblocks;
183
184     if (ctx->tlsversion > 0) {
185         /*
186          * Each update call corresponds to a TLS record and is individually
187          * padded
188          */
189
190         /* Sanity check inputs */
191         if (in == 0
192                 || (inl % blksz) != 0
193                 || in != out
194                 || outsize < inl
195                 || !ctx->pad) {
196             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
197             return 0;
198         }
199
200         /* Shouldn't normally fail */
201         if (!ctx->hw->cipher(ctx, out, in, inl)) {
202             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
203             return 0;
204         }
205
206         /* This only fails if padding is publicly invalid */
207         /* TODO(3.0): FIX ME FIX ME - Figure out aead */
208         *outl = inl;
209         if (!ctx->enc
210                 && !tlsunpadblock(ctx->libctx, ctx->tlsversion, out, outl,
211                                   blksz, &ctx->tlsmac, &ctx->alloced,
212                                   ctx->tlsmacsize, 0)) {
213             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
214             return 0;
215         }
216         return 1;
217     }
218
219     if (ctx->bufsz != 0)
220         nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl);
221     else
222         nextblocks = inl & ~(blksz-1);
223
224     /*
225      * If we're decrypting and we end an update on a block boundary we hold
226      * the last block back in case this is the last update call and the last
227      * block is padded.
228      */
229     if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
230         if (outsize < blksz) {
231             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
232             return 0;
233         }
234         if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
235             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
236             return 0;
237         }
238         ctx->bufsz = 0;
239         outlint = blksz;
240         out += blksz;
241     }
242     if (nextblocks > 0) {
243         if (!ctx->enc && ctx->pad && nextblocks == inl) {
244             if (!ossl_assert(inl >= blksz)) {
245                 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
246                 return 0;
247             }
248             nextblocks -= blksz;
249         }
250         outlint += nextblocks;
251         if (outsize < outlint) {
252             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
253             return 0;
254         }
255     }
256     if (nextblocks > 0) {
257         if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
258             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
259             return 0;
260         }
261         in += nextblocks;
262         inl -= nextblocks;
263     }
264     if (inl != 0 && !trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
265         /* ERR_raise already called */
266         return 0;
267     }
268
269     *outl = outlint;
270     return inl == 0;
271 }
272
273 int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl,
274                                size_t outsize)
275 {
276     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
277     size_t blksz = ctx->blocksize;
278
279     if (ctx->tlsversion > 0) {
280         /* We never finalize TLS, so this is an error */
281         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
282         return 0;
283     }
284
285     if (ctx->enc) {
286         if (ctx->pad) {
287             padblock(ctx->buf, &ctx->bufsz, blksz);
288         } else if (ctx->bufsz == 0) {
289             *outl = 0;
290             return 1;
291         } else if (ctx->bufsz != blksz) {
292             ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
293             return 0;
294         }
295
296         if (outsize < blksz) {
297             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
298             return 0;
299         }
300         if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
301             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
302             return 0;
303         }
304         ctx->bufsz = 0;
305         *outl = blksz;
306         return 1;
307     }
308
309     /* Decrypting */
310     if (ctx->bufsz != blksz) {
311         if (ctx->bufsz == 0 && !ctx->pad) {
312             *outl = 0;
313             return 1;
314         }
315         ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
316         return 0;
317     }
318
319     if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
320         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
321         return 0;
322     }
323
324     if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
325         /* ERR_raise already called */
326         return 0;
327     }
328
329     if (outsize < ctx->bufsz) {
330         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
331         return 0;
332     }
333     memcpy(out, ctx->buf, ctx->bufsz);
334     *outl = ctx->bufsz;
335     ctx->bufsz = 0;
336     return 1;
337 }
338
339 int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl,
340                                  size_t outsize, const unsigned char *in,
341                                  size_t inl)
342 {
343     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
344
345     if (inl == 0) {
346         *outl = 0;
347         return 1;
348     }
349
350     if (outsize < inl) {
351         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
352         return 0;
353     }
354
355     if (!ctx->hw->cipher(ctx, out, in, inl)) {
356         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
357         return 0;
358     }
359
360     *outl = inl;
361     return 1;
362 }
363 int cipher_generic_stream_final(void *vctx, unsigned char *out, size_t *outl,
364                                 size_t outsize)
365 {
366     *outl = 0;
367     return 1;
368 }
369
370 int cipher_generic_cipher(void *vctx,
371                           unsigned char *out, size_t *outl, size_t outsize,
372                           const unsigned char *in, size_t inl)
373 {
374     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
375
376     if (outsize < inl) {
377         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
378         return 0;
379     }
380
381     if (!ctx->hw->cipher(ctx, out, in, inl)) {
382         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
383         return 0;
384     }
385
386     *outl = inl;
387     return 1;
388 }
389
390 int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
391 {
392     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
393     OSSL_PARAM *p;
394
395     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
396     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
397         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
398         return 0;
399     }
400     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
401     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) {
402         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
403         return 0;
404     }
405     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
406     if (p != NULL
407         && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
408         && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
409         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
410         return 0;
411     }
412     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
413     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) {
414         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
415         return 0;
416     }
417     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
418     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
419         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
420         return 0;
421     }
422     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC);
423     if (p != NULL
424         && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) {
425         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
426         return 0;
427     }
428     return 1;
429 }
430
431 int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
432 {
433     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
434     const OSSL_PARAM *p;
435
436     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
437     if (p != NULL) {
438         unsigned int pad;
439
440         if (!OSSL_PARAM_get_uint(p, &pad)) {
441             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
442             return 0;
443         }
444         ctx->pad = pad ? 1 : 0;
445     }
446     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
447     if (p != NULL) {
448         if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) {
449             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
450             return 0;
451         }
452     }
453     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE);
454     if (p != NULL) {
455         if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) {
456             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
457             return 0;
458         }
459     }
460     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
461     if (p != NULL) {
462         unsigned int num;
463
464         if (!OSSL_PARAM_get_uint(p, &num)) {
465             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
466             return 0;
467         }
468         ctx->num = num;
469     }
470     return 1;
471 }
472
473 int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
474                           size_t ivlen)
475 {
476     if (ivlen != ctx->ivlen
477         || ivlen > sizeof(ctx->iv)) {
478         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
479         return 0;
480     }
481     ctx->iv_set = 1;
482     memcpy(ctx->iv, iv, ivlen);
483     memcpy(ctx->oiv, iv, ivlen);
484     return 1;
485 }
486
487 void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
488                             size_t ivbits, unsigned int mode, uint64_t flags,
489                             const PROV_CIPHER_HW *hw, void *provctx)
490 {
491     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
492
493     ctx->flags = flags;
494     ctx->pad = 1;
495     ctx->keylen = ((kbits) / 8);
496     ctx->ivlen = ((ivbits) / 8);
497     ctx->hw = hw;
498     ctx->mode = mode;
499     ctx->blocksize = blkbits / 8;
500     if (provctx != NULL)
501         ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); /* used for rand */
502 }