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