Cleanup ciphers and Add 3des ciphers.
[openssl.git] / providers / common / ciphers / cipher_common.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 /*
11  * Generic dispatch table functions for ciphers.
12  */
13
14 #include "cipher_locl.h"
15 #include "internal/provider_ctx.h"
16 #include "internal/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_int(OSSL_CIPHER_PARAM_MODE, NULL),
23     OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),
24     OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL),
25     OSSL_PARAM_int(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
26     OSSL_PARAM_END
27 };
28 const OSSL_PARAM *cipher_generic_gettable_params(void)
29 {
30     return cipher_known_gettable_params;
31 }
32
33 int cipher_generic_get_params(OSSL_PARAM params[], int md, unsigned long flags,
34                               int kbits, int blkbits, int ivbits)
35 {
36     OSSL_PARAM *p;
37
38     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
39     if (p != NULL && !OSSL_PARAM_set_int(p, md)) {
40         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
41         return 0;
42     }
43     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_FLAGS);
44     if (p != NULL && !OSSL_PARAM_set_ulong(p, flags)) {
45         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
46         return 0;
47     }
48     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
49     if (p != NULL && !OSSL_PARAM_set_int(p, kbits / 8)) {
50         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
51         return 0;
52     }
53     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
54     if (p != NULL && !OSSL_PARAM_set_int(p, blkbits / 8)) {
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_IVLEN);
59     if (p != NULL && !OSSL_PARAM_set_int(p, ivbits / 8)) {
60         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
61         return 0;
62     }
63     return 1;
64 }
65
66 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
67 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
68
69 static const OSSL_PARAM cipher_known_settable_ctx_params[] = {
70     OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),
71     OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL),
72     OSSL_PARAM_int(OSSL_CIPHER_PARAM_NUM, NULL),
73     OSSL_PARAM_END
74 };
75 const OSSL_PARAM *cipher_generic_settable_ctx_params(void)
76 {
77     return cipher_known_settable_ctx_params;
78 }
79
80 /*-
81  * AEAD cipher functions for OSSL_PARAM gettables and settables
82  */
83 static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
84     OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),
85     OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL),
86     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
87     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
88     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
89     OSSL_PARAM_END
90 };
91 const OSSL_PARAM *cipher_aead_gettable_ctx_params(void)
92 {
93     return cipher_aead_known_gettable_ctx_params;
94 }
95
96 static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
97     OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL),
98     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
99     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
100     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
101     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
102     OSSL_PARAM_END
103 };
104 const OSSL_PARAM *cipher_aead_settable_ctx_params(void)
105 {
106     return cipher_aead_known_settable_ctx_params;
107 }
108
109 static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
110                                         const unsigned char *key, size_t keylen,
111                                         const unsigned char *iv, size_t ivlen,
112                                         int enc)
113 {
114     ctx->enc = enc;
115
116     if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
117         if (ivlen != ctx->ivlen) {
118             ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
119             return 0;
120         }
121         memcpy(ctx->iv, iv, ctx->ivlen);
122     }
123     if (key != NULL) {
124         if (keylen != ctx->keylen) {
125             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
126             return 0;
127         }
128         return ctx->hw->init(ctx, key, ctx->keylen);
129     }
130     return 1;
131 }
132
133 int cipher_generic_einit(void *vctx, const unsigned char *key, size_t keylen,
134                          const unsigned char *iv, size_t ivlen)
135 {
136     return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
137                                         iv, ivlen, 1);
138 }
139
140 int cipher_generic_dinit(void *vctx, const unsigned char *key, size_t keylen,
141                          const unsigned char *iv, size_t ivlen)
142 {
143     return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
144                                         iv, ivlen, 0);
145 }
146
147 int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,
148                                 size_t outsize, const unsigned char *in,
149                                 size_t inl)
150 {
151     size_t outlint = 0;
152     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
153     size_t blksz = ctx->blocksize;
154     size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl);
155
156     /*
157      * If we're decrypting and we end an update on a block boundary we hold
158      * the last block back in case this is the last update call and the last
159      * block is padded.
160      */
161     if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
162         if (outsize < blksz) {
163             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
164             return 0;
165         }
166         if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
167             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
168             return 0;
169         }
170         ctx->bufsz = 0;
171         outlint = blksz;
172         out += blksz;
173     }
174     if (nextblocks > 0) {
175         if (!ctx->enc && ctx->pad && nextblocks == inl) {
176             if (!ossl_assert(inl >= blksz)) {
177                 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
178                 return 0;
179             }
180             nextblocks -= blksz;
181         }
182         outlint += nextblocks;
183         if (outsize < outlint) {
184             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
185             return 0;
186         }
187         if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
188             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
189             return 0;
190         }
191         in += nextblocks;
192         inl -= nextblocks;
193     }
194     if (!trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
195         /* ERR_raise already called */
196         return 0;
197     }
198
199     *outl = outlint;
200     return inl == 0;
201 }
202
203 int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl,
204                                size_t outsize)
205 {
206     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
207     size_t blksz = ctx->blocksize;
208
209     if (ctx->enc) {
210         if (ctx->pad) {
211             padblock(ctx->buf, &ctx->bufsz, blksz);
212         } else if (ctx->bufsz == 0) {
213             *outl = 0;
214             return 1;
215         } else if (ctx->bufsz != blksz) {
216             ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
217             return 0;
218         }
219
220         if (outsize < blksz) {
221             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
222             return 0;
223         }
224         if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
225             ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
226             return 0;
227         }
228         ctx->bufsz = 0;
229         *outl = blksz;
230         return 1;
231     }
232
233     /* Decrypting */
234     if (ctx->bufsz != blksz) {
235         if (ctx->bufsz == 0 && !ctx->pad) {
236             *outl = 0;
237             return 1;
238         }
239         ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
240         return 0;
241     }
242
243     if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
244         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
245         return 0;
246     }
247
248     if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
249         /* ERR_raise already called */
250         return 0;
251     }
252
253     if (outsize < ctx->bufsz) {
254         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
255         return 0;
256     }
257     memcpy(out, ctx->buf, ctx->bufsz);
258     *outl = ctx->bufsz;
259     ctx->bufsz = 0;
260     return 1;
261 }
262
263 int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl,
264                                  size_t outsize, const unsigned char *in,
265                                  size_t inl)
266 {
267     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
268
269     if (outsize < inl) {
270         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
271         return 0;
272     }
273
274     if (!ctx->hw->cipher(ctx, out, in, inl)) {
275         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
276         return 0;
277     }
278
279     *outl = inl;
280     return 1;
281 }
282 int cipher_generic_stream_final(void *vctx, unsigned char *out, size_t *outl,
283                                 size_t outsize)
284 {
285     *outl = 0;
286     return 1;
287 }
288
289 int cipher_generic_cipher(void *vctx,
290                           unsigned char *out, size_t *outl, size_t outsize,
291                           const unsigned char *in, size_t inl)
292 {
293     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
294
295     if (outsize < inl) {
296         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
297         return 0;
298     }
299
300     if (!ctx->hw->cipher(ctx, out, in, inl)) {
301         ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
302         return 0;
303     }
304
305     *outl = inl;
306     return 1;
307 }
308
309 int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
310 {
311     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
312     OSSL_PARAM *p;
313
314     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
315     if (p != NULL && !OSSL_PARAM_set_int(p, ctx->ivlen)) {
316         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
317         return 0;
318     }
319     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
320     if (p != NULL && !OSSL_PARAM_set_int(p, ctx->pad)) {
321         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
322         return 0;
323     }
324     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
325     if (p != NULL
326         && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
327         && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
328         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
329         return 0;
330     }
331     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
332     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->num)) {
333         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
334         return 0;
335     }
336     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
337     if (p != NULL && !OSSL_PARAM_set_int(p, ctx->keylen)) {
338         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
339         return 0;
340     }
341
342     return 1;
343 }
344
345 int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
346 {
347     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
348     const OSSL_PARAM *p;
349
350     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
351     if (p != NULL) {
352         int pad;
353
354         if (!OSSL_PARAM_get_int(p, &pad)) {
355             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
356             return 0;
357         }
358         ctx->pad = pad ? 1 : 0;
359     }
360     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
361     if (p != NULL) {
362         int num;
363
364         if (!OSSL_PARAM_get_int(p, &num)) {
365             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
366             return 0;
367         }
368         ctx->num = num;
369     }
370     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
371     if (p != NULL) {
372         int keylen;
373
374         if (!OSSL_PARAM_get_int(p, &keylen)) {
375             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
376             return 0;
377         }
378         ctx->keylen = keylen;
379     }
380     return 1;
381 }
382
383 void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
384                             size_t ivbits, int mode,
385                             const PROV_CIPHER_HW *hw, void *provctx)
386 {
387     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
388
389     ctx->pad = 1;
390     ctx->keylen = ((kbits) / 8);
391     ctx->ivlen = ((ivbits) / 8);
392     ctx->hw = hw;
393     ctx->mode = mode;
394     ctx->blocksize = blkbits / 8;
395     if (provctx != NULL)
396         ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); /* used for rand */
397 }