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