Coverage Report

Created: 2025-06-13 06:57

/src/openssl/providers/implementations/ciphers/ciphercommon.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2019-2025 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
/*
12
 * Generic dispatch table functions for ciphers.
13
 */
14
15
/* For SSL3_VERSION */
16
#include <string.h>
17
#include <openssl/prov_ssl.h>
18
#include <openssl/proverr.h>
19
#include "ciphercommon_local.h"
20
#include "prov/provider_ctx.h"
21
#include "prov/providercommon.h"
22
#include "internal/skey.h"
23
#include "internal/e_os.h"
24
#include "internal/param_names.h"
25
#include "crypto/types.h"
26
27
/*-
28
 * Generic cipher functions for OSSL_PARAM gettables and settables
29
 */
30
static const OSSL_PARAM cipher_known_gettable_params[] = {
31
    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL),
32
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
33
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
34
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
35
    OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL),
36
    OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL),
37
    OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL),
38
    OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL),
39
    OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL),
40
    OSSL_PARAM_END
41
};
42
const OSSL_PARAM *ossl_cipher_generic_gettable_params(ossl_unused void *provctx)
43
0
{
44
0
    return cipher_known_gettable_params;
45
0
}
46
47
int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
48
                                   uint64_t flags,
49
                                   size_t kbits, size_t blkbits, size_t ivbits)
50
40.6k
{
51
40.6k
    OSSL_PARAM *p;
52
53
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
54
40.6k
    if (p != NULL && !OSSL_PARAM_set_uint(p, md)) {
55
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
56
0
        return 0;
57
0
    }
58
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD);
59
40.6k
    if (p != NULL
60
40.6k
        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) {
61
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
62
0
        return 0;
63
0
    }
64
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV);
65
40.6k
    if (p != NULL
66
40.6k
        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) {
67
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
68
0
        return 0;
69
0
    }
70
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS);
71
40.6k
    if (p != NULL
72
40.6k
        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) {
73
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
74
0
        return 0;
75
0
    }
76
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK);
77
40.6k
    if (p != NULL
78
40.6k
        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) {
79
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
80
0
        return 0;
81
0
    }
82
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY);
83
40.6k
    if (p != NULL
84
40.6k
        && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) {
85
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
86
0
        return 0;
87
0
    }
88
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC);
89
40.6k
    if (p != NULL
90
40.6k
        && !OSSL_PARAM_set_int(p, (flags & EVP_CIPH_FLAG_ENC_THEN_MAC) != 0)) {
91
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
92
0
        return 0;
93
0
    }
94
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
95
40.6k
    if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) {
96
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
97
0
        return 0;
98
0
    }
99
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
100
40.6k
    if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) {
101
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
102
0
        return 0;
103
0
    }
104
40.6k
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
105
40.6k
    if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) {
106
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
107
0
        return 0;
108
0
    }
109
40.6k
    return 1;
110
40.6k
}
111
112
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic)
113
{ OSSL_CIPHER_PARAM_TLS_MAC, OSSL_PARAM_OCTET_PTR, NULL, 0, OSSL_PARAM_UNMODIFIED },
114
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_cipher_generic)
115
116
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_generic)
117
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_USE_BITS, NULL),
118
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL),
119
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL),
120
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_generic)
121
122
/*
123
 * Variable key length cipher functions for OSSL_PARAM settables
124
 */
125
int ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[])
126
0
{
127
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
128
0
    const OSSL_PARAM *p;
129
130
0
    if (ossl_param_is_empty(params))
131
0
        return 1;
132
133
0
    if (!ossl_cipher_generic_set_ctx_params(vctx, params))
134
0
        return 0;
135
0
    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
136
0
    if (p != NULL) {
137
0
        size_t keylen;
138
139
0
        if (!OSSL_PARAM_get_size_t(p, &keylen)) {
140
0
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
141
0
            return 0;
142
0
        }
143
0
        if (ctx->keylen != keylen) {
144
0
            ctx->keylen = keylen;
145
0
            ctx->key_set = 0;
146
0
        }
147
0
    }
148
0
    return 1;
149
0
}
150
151
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_var_keylen)
152
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
153
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_var_keylen)
154
155
/*-
156
 * AEAD cipher functions for OSSL_PARAM gettables and settables
157
 */
158
159
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
160
static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
161
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
162
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
163
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
164
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
165
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
166
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
167
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
168
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
169
    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_AEAD_IV_GENERATED, NULL),
170
    OSSL_PARAM_END
171
};
172
173
int ossl_cipher_aead_get_ctx_params_find_pidx(const char *s)
174
0
{
175
0
    switch(s[0]) {
176
0
    default:
177
0
        break;
178
0
    case 'i':
179
0
        switch(s[1]) {
180
0
        default:
181
0
            break;
182
0
        case 'v':
183
0
            switch(s[2]) {
184
0
            default:
185
0
                break;
186
0
            case '-':
187
0
                if (strcmp("generated", s + 3) == 0)
188
0
                    return PIDX_CIPHER_PARAM_AEAD_IV_GENERATED;
189
0
                break;
190
0
            case 'l':
191
0
                if (strcmp("en", s + 3) == 0)
192
0
                    return PIDX_CIPHER_PARAM_IVLEN;
193
0
                break;
194
0
            case '\0':
195
0
                return PIDX_CIPHER_PARAM_IV;
196
0
            }
197
0
        }
198
0
        break;
199
0
    case 'k':
200
0
        if (strcmp("eylen", s + 1) == 0)
201
0
            return PIDX_CIPHER_PARAM_KEYLEN;
202
0
        break;
203
0
    case 't':
204
0
        switch(s[1]) {
205
0
        default:
206
0
            break;
207
0
        case 'a':
208
0
            switch(s[2]) {
209
0
            default:
210
0
                break;
211
0
            case 'g':
212
0
                switch(s[3]) {
213
0
                default:
214
0
                    break;
215
0
                case 'l':
216
0
                    if (strcmp("en", s + 4) == 0)
217
0
                        return PIDX_CIPHER_PARAM_AEAD_TAGLEN;
218
0
                    break;
219
0
                case '\0':
220
0
                    return PIDX_CIPHER_PARAM_AEAD_TAG;
221
0
                }
222
0
            }
223
0
            break;
224
0
        case 'l':
225
0
            switch(s[2]) {
226
0
            default:
227
0
                break;
228
0
            case 's':
229
0
                switch(s[3]) {
230
0
                default:
231
0
                    break;
232
0
                case 'a':
233
0
                    if (strcmp("adpad", s + 4) == 0)
234
0
                        return PIDX_CIPHER_PARAM_AEAD_TLS1_AAD_PAD;
235
0
                    break;
236
0
                case 'i':
237
0
                    if (strcmp("vgen", s + 4) == 0)
238
0
                        return PIDX_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN;
239
0
                }
240
0
            }
241
0
        }
242
0
        break;
243
0
    case 'u':
244
0
        if (strcmp("pdated-iv", s + 1) == 0)
245
0
            return PIDX_CIPHER_PARAM_UPDATED_IV;
246
0
    }
247
0
    return -1;
248
0
}
249
250
/* End of machine generated */
251
252
const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params(
253
        ossl_unused void *cctx, ossl_unused void *provctx
254
    )
255
14
{
256
14
    return cipher_aead_known_gettable_ctx_params;
257
14
}
258
259
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
260
static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
261
    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
262
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
263
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
264
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
265
    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0),
266
    OSSL_PARAM_END
267
};
268
269
int ossl_cipher_aead_set_ctx_params_find_pidx(const char *s)
270
0
{
271
0
    switch(s[0]) {
272
0
    default:
273
0
        break;
274
0
    case 'i':
275
0
        if (strcmp("vlen", s + 1) == 0)
276
0
            return PIDX_CIPHER_PARAM_AEAD_IVLEN;
277
0
        break;
278
0
    case 't':
279
0
        switch(s[1]) {
280
0
        default:
281
0
            break;
282
0
        case 'a':
283
0
            if (strcmp("g", s + 2) == 0)
284
0
                return PIDX_CIPHER_PARAM_AEAD_TAG;
285
0
            break;
286
0
        case 'l':
287
0
            switch(s[2]) {
288
0
            default:
289
0
                break;
290
0
            case 's':
291
0
                switch(s[3]) {
292
0
                default:
293
0
                    break;
294
0
                case 'a':
295
0
                    if (strcmp("ad", s + 4) == 0)
296
0
                        return PIDX_CIPHER_PARAM_AEAD_TLS1_AAD;
297
0
                    break;
298
0
                case 'i':
299
0
                    switch(s[4]) {
300
0
                    default:
301
0
                        break;
302
0
                    case 'v':
303
0
                        switch(s[5]) {
304
0
                        default:
305
0
                            break;
306
0
                        case 'f':
307
0
                            if (strcmp("ixed", s + 6) == 0)
308
0
                                return PIDX_CIPHER_PARAM_AEAD_TLS1_IV_FIXED;
309
0
                            break;
310
0
                        case 'i':
311
0
                            if (strcmp("nv", s + 6) == 0)
312
0
                                return PIDX_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV;
313
0
                        }
314
0
                    }
315
0
                }
316
0
            }
317
0
        }
318
0
    }
319
0
    return -1;
320
0
}
321
322
/* End of machine generated */
323
324
const OSSL_PARAM *ossl_cipher_aead_settable_ctx_params(
325
        ossl_unused void *cctx, ossl_unused void *provctx
326
    )
327
0
{
328
0
    return cipher_aead_known_settable_ctx_params;
329
0
}
330
331
void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx)
332
0
{
333
0
    if (ctx != NULL && ctx->alloced) {
334
0
        OPENSSL_free(ctx->tlsmac);
335
0
        ctx->alloced = 0;
336
0
        ctx->tlsmac = NULL;
337
0
    }
338
0
}
339
340
static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
341
                                        const unsigned char *key, size_t keylen,
342
                                        const unsigned char *iv, size_t ivlen,
343
                                        const OSSL_PARAM params[], int enc)
344
0
{
345
0
    ctx->num = 0;
346
0
    ctx->bufsz = 0;
347
0
    ctx->updated = 0;
348
0
    ctx->enc = enc ? 1 : 0;
349
350
0
    if (!ossl_prov_is_running())
351
0
        return 0;
352
353
0
    if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
354
0
        if (!ossl_cipher_generic_initiv(ctx, iv, ivlen))
355
0
            return 0;
356
0
    }
357
0
    if (iv == NULL && ctx->iv_set
358
0
        && (ctx->mode == EVP_CIPH_CBC_MODE
359
0
            || ctx->mode == EVP_CIPH_CFB_MODE
360
0
            || ctx->mode == EVP_CIPH_OFB_MODE))
361
        /* reset IV for these modes to keep compatibility with 1.1.1 */
362
0
        memcpy(ctx->iv, ctx->oiv, ctx->ivlen);
363
364
0
    if (key != NULL) {
365
0
        if (ctx->variable_keylength == 0) {
366
0
            if (keylen != ctx->keylen) {
367
0
                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
368
0
                return 0;
369
0
            }
370
0
        } else {
371
0
            ctx->keylen = keylen;
372
0
        }
373
0
        if (!ctx->hw->init(ctx, key, ctx->keylen))
374
0
            return 0;
375
0
        ctx->key_set = 1;
376
0
    }
377
0
    return ossl_cipher_generic_set_ctx_params(ctx, params);
378
0
}
379
380
int ossl_cipher_generic_einit(void *vctx, const unsigned char *key,
381
                              size_t keylen, const unsigned char *iv,
382
                              size_t ivlen, const OSSL_PARAM params[])
383
0
{
384
0
    return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
385
0
                                        iv, ivlen, params, 1);
386
0
}
387
388
int ossl_cipher_generic_dinit(void *vctx, const unsigned char *key,
389
                              size_t keylen, const unsigned char *iv,
390
                              size_t ivlen, const OSSL_PARAM params[])
391
0
{
392
0
    return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
393
0
                                        iv, ivlen, params, 0);
394
0
}
395
396
int ossl_cipher_generic_skey_einit(void *vctx, void *skeydata,
397
                                   const unsigned char *iv, size_t ivlen,
398
                                   const OSSL_PARAM params[])
399
0
{
400
0
    PROV_SKEY *key = skeydata;
401
402
0
    return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx,
403
0
                                        key->data, key->length,
404
0
                                        iv, ivlen, params, 1);
405
0
}
406
407
int ossl_cipher_generic_skey_dinit(void *vctx, void *skeydata,
408
                                   const unsigned char *iv, size_t ivlen,
409
                                   const OSSL_PARAM params[])
410
0
{
411
0
    PROV_SKEY *key = skeydata;
412
413
0
    return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx,
414
0
                                        key->data, key->length,
415
0
                                        iv, ivlen, params, 0);
416
0
}
417
418
/* Max padding including padding length byte */
419
0
#define MAX_PADDING 256
420
421
int ossl_cipher_generic_block_update(void *vctx, unsigned char *out,
422
                                     size_t *outl, size_t outsize,
423
                                     const unsigned char *in, size_t inl)
424
0
{
425
0
    size_t outlint = 0;
426
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
427
0
    size_t blksz = ctx->blocksize;
428
0
    size_t nextblocks;
429
430
0
    if (!ctx->key_set) {
431
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
432
0
        return 0;
433
0
    }
434
435
0
    if (ctx->tlsversion > 0) {
436
        /*
437
         * Each update call corresponds to a TLS record and is individually
438
         * padded
439
         */
440
441
        /* Sanity check inputs */
442
0
        if (in == NULL
443
0
                || in != out
444
0
                || outsize < inl
445
0
                || !ctx->pad) {
446
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
447
0
            return 0;
448
0
        }
449
450
0
        if (ctx->enc) {
451
0
            unsigned char padval;
452
0
            size_t padnum, loop;
453
454
            /* Add padding */
455
456
0
            padnum = blksz - (inl % blksz);
457
458
0
            if (outsize < inl + padnum) {
459
0
                ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
460
0
                return 0;
461
0
            }
462
463
0
            if (padnum > MAX_PADDING) {
464
0
                ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
465
0
                return 0;
466
0
            }
467
0
            padval = (unsigned char)(padnum - 1);
468
0
            if (ctx->tlsversion == SSL3_VERSION) {
469
0
                if (padnum > 1)
470
0
                    memset(out + inl, 0, padnum - 1);
471
0
                *(out + inl + padnum - 1) = padval;
472
0
            } else {
473
                /* we need to add 'padnum' padding bytes of value padval */
474
0
                for (loop = inl; loop < inl + padnum; loop++)
475
0
                    out[loop] = padval;
476
0
            }
477
0
            inl += padnum;
478
0
        }
479
480
0
        if ((inl % blksz) != 0) {
481
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
482
0
            return 0;
483
0
        }
484
485
486
        /* Shouldn't normally fail */
487
0
        if (!ctx->hw->cipher(ctx, out, in, inl)) {
488
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
489
0
            return 0;
490
0
        }
491
492
0
        if (ctx->alloced) {
493
0
            OPENSSL_free(ctx->tlsmac);
494
0
            ctx->alloced = 0;
495
0
            ctx->tlsmac = NULL;
496
0
        }
497
498
        /* This only fails if padding is publicly invalid */
499
0
        *outl = inl;
500
0
        if (!ctx->enc
501
0
            && !ossl_cipher_tlsunpadblock(ctx->libctx, ctx->tlsversion,
502
0
                                          out, outl,
503
0
                                          blksz, &ctx->tlsmac, &ctx->alloced,
504
0
                                          ctx->tlsmacsize, 0)) {
505
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
506
0
            return 0;
507
0
        }
508
0
        return 1;
509
0
    }
510
511
0
    if (ctx->bufsz != 0)
512
0
        nextblocks = ossl_cipher_fillblock(ctx->buf, &ctx->bufsz, blksz,
513
0
                                           &in, &inl);
514
0
    else
515
0
        nextblocks = inl & ~(blksz-1);
516
517
    /*
518
     * If we're decrypting and we end an update on a block boundary we hold
519
     * the last block back in case this is the last update call and the last
520
     * block is padded.
521
     */
522
0
    if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
523
0
        if (outsize < blksz) {
524
0
            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
525
0
            return 0;
526
0
        }
527
0
        if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
528
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
529
0
            return 0;
530
0
        }
531
0
        ctx->bufsz = 0;
532
0
        outlint = blksz;
533
0
        out += blksz;
534
0
    }
535
0
    if (nextblocks > 0) {
536
0
        if (!ctx->enc && ctx->pad && nextblocks == inl) {
537
0
            if (!ossl_assert(inl >= blksz)) {
538
0
                ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
539
0
                return 0;
540
0
            }
541
0
            nextblocks -= blksz;
542
0
        }
543
0
        outlint += nextblocks;
544
0
        if (outsize < outlint) {
545
0
            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
546
0
            return 0;
547
0
        }
548
0
    }
549
0
    if (nextblocks > 0) {
550
0
        if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
551
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
552
0
            return 0;
553
0
        }
554
0
        in += nextblocks;
555
0
        inl -= nextblocks;
556
0
    }
557
0
    if (inl != 0
558
0
        && !ossl_cipher_trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
559
        /* ERR_raise already called */
560
0
        return 0;
561
0
    }
562
563
0
    *outl = outlint;
564
0
    return inl == 0;
565
0
}
566
567
int ossl_cipher_generic_block_final(void *vctx, unsigned char *out,
568
                                    size_t *outl, size_t outsize)
569
0
{
570
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
571
0
    size_t blksz = ctx->blocksize;
572
573
0
    if (!ossl_prov_is_running())
574
0
        return 0;
575
576
0
    if (!ctx->key_set) {
577
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
578
0
        return 0;
579
0
    }
580
581
0
    if (ctx->tlsversion > 0) {
582
        /* We never finalize TLS, so this is an error */
583
0
        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
584
0
        return 0;
585
0
    }
586
587
0
    if (ctx->enc) {
588
0
        if (ctx->pad) {
589
0
            ossl_cipher_padblock(ctx->buf, &ctx->bufsz, blksz);
590
0
        } else if (ctx->bufsz == 0) {
591
0
            *outl = 0;
592
0
            return 1;
593
0
        } else if (ctx->bufsz != blksz) {
594
0
            ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
595
0
            return 0;
596
0
        }
597
598
0
        if (outsize < blksz) {
599
0
            ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
600
0
            return 0;
601
0
        }
602
0
        if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
603
0
            ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
604
0
            return 0;
605
0
        }
606
0
        ctx->bufsz = 0;
607
0
        *outl = blksz;
608
0
        return 1;
609
0
    }
610
611
    /* Decrypting */
612
0
    if (ctx->bufsz != blksz) {
613
0
        if (ctx->bufsz == 0 && !ctx->pad) {
614
0
            *outl = 0;
615
0
            return 1;
616
0
        }
617
0
        ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
618
0
        return 0;
619
0
    }
620
621
0
    if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
622
0
        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
623
0
        return 0;
624
0
    }
625
626
0
    if (ctx->pad && !ossl_cipher_unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
627
        /* ERR_raise already called */
628
0
        return 0;
629
0
    }
630
631
0
    if (outsize < ctx->bufsz) {
632
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
633
0
        return 0;
634
0
    }
635
0
    memcpy(out, ctx->buf, ctx->bufsz);
636
0
    *outl = ctx->bufsz;
637
0
    ctx->bufsz = 0;
638
0
    return 1;
639
0
}
640
641
int ossl_cipher_generic_stream_update(void *vctx, unsigned char *out,
642
                                      size_t *outl, size_t outsize,
643
                                      const unsigned char *in, size_t inl)
644
0
{
645
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
646
647
0
    if (!ctx->key_set) {
648
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
649
0
        return 0;
650
0
    }
651
652
0
    if (inl == 0) {
653
0
        *outl = 0;
654
0
        return 1;
655
0
    }
656
657
0
    if (outsize < inl) {
658
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
659
0
        return 0;
660
0
    }
661
662
0
    if (!ctx->hw->cipher(ctx, out, in, inl)) {
663
0
        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
664
0
        return 0;
665
0
    }
666
667
0
    *outl = inl;
668
0
    if (!ctx->enc && ctx->tlsversion > 0) {
669
        /*
670
        * Remove any TLS padding. Only used by cipher_aes_cbc_hmac_sha1_hw.c and
671
        * cipher_aes_cbc_hmac_sha256_hw.c
672
        */
673
0
        if (ctx->removetlspad) {
674
            /*
675
             * We should have already failed in the cipher() call above if this
676
             * isn't true.
677
             */
678
0
            if (!ossl_assert(*outl >= (size_t)(out[inl - 1] + 1)))
679
0
                return 0;
680
            /* The actual padding length */
681
0
            *outl -= out[inl - 1] + 1;
682
0
        }
683
684
        /* TLS MAC and explicit IV if relevant. We should have already failed
685
         * in the cipher() call above if *outl is too short.
686
         */
687
0
        if (!ossl_assert(*outl >= ctx->removetlsfixed))
688
0
            return 0;
689
0
        *outl -= ctx->removetlsfixed;
690
691
        /* Extract the MAC if there is one */
692
0
        if (ctx->tlsmacsize > 0) {
693
0
            if (*outl < ctx->tlsmacsize)
694
0
                return 0;
695
696
0
            ctx->tlsmac = out + *outl - ctx->tlsmacsize;
697
0
            *outl -= ctx->tlsmacsize;
698
0
        }
699
0
    }
700
701
0
    return 1;
702
0
}
703
int ossl_cipher_generic_stream_final(void *vctx, unsigned char *out,
704
                                     size_t *outl, size_t outsize)
705
0
{
706
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
707
708
0
    if (!ossl_prov_is_running())
709
0
        return 0;
710
711
0
    if (!ctx->key_set) {
712
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
713
0
        return 0;
714
0
    }
715
716
0
    *outl = 0;
717
0
    return 1;
718
0
}
719
720
int ossl_cipher_generic_cipher(void *vctx, unsigned char *out, size_t *outl,
721
                               size_t outsize, const unsigned char *in,
722
                               size_t inl)
723
0
{
724
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
725
726
0
    if (!ossl_prov_is_running())
727
0
        return 0;
728
729
0
    if (!ctx->key_set) {
730
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
731
0
        return 0;
732
0
    }
733
734
0
    if (outsize < inl) {
735
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
736
0
        return 0;
737
0
    }
738
739
0
    if (!ctx->hw->cipher(ctx, out, in, inl)) {
740
0
        ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
741
0
        return 0;
742
0
    }
743
744
0
    *outl = inl;
745
0
    return 1;
746
0
}
747
748
int ossl_cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
749
0
{
750
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
751
0
    OSSL_PARAM *p;
752
753
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
754
0
    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
755
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
756
0
        return 0;
757
0
    }
758
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
759
0
    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) {
760
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
761
0
        return 0;
762
0
    }
763
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
764
0
    if (p != NULL
765
0
        && !OSSL_PARAM_set_octet_string_or_ptr(p, ctx->oiv, ctx->ivlen)) {
766
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
767
0
        return 0;
768
0
    }
769
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
770
0
    if (p != NULL
771
0
        && !OSSL_PARAM_set_octet_string_or_ptr(p, ctx->iv, ctx->ivlen)) {
772
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
773
0
        return 0;
774
0
    }
775
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
776
0
    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) {
777
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
778
0
        return 0;
779
0
    }
780
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
781
0
    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
782
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
783
0
        return 0;
784
0
    }
785
0
    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC);
786
0
    if (p != NULL
787
0
        && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) {
788
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
789
0
        return 0;
790
0
    }
791
0
    return 1;
792
0
}
793
794
int ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
795
0
{
796
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
797
0
    const OSSL_PARAM *p;
798
799
0
    if (ossl_param_is_empty(params))
800
0
        return 1;
801
802
0
    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
803
0
    if (p != NULL) {
804
0
        unsigned int pad;
805
806
0
        if (!OSSL_PARAM_get_uint(p, &pad)) {
807
0
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
808
0
            return 0;
809
0
        }
810
0
        ctx->pad = pad ? 1 : 0;
811
0
    }
812
0
    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_USE_BITS);
813
0
    if (p != NULL) {
814
0
        unsigned int bits;
815
816
0
        if (!OSSL_PARAM_get_uint(p, &bits)) {
817
0
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
818
0
            return 0;
819
0
        }
820
0
        ctx->use_bits = bits ? 1 : 0;
821
0
    }
822
0
    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
823
0
    if (p != NULL) {
824
0
        if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) {
825
0
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
826
0
            return 0;
827
0
        }
828
0
    }
829
0
    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE);
830
0
    if (p != NULL) {
831
0
        if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) {
832
0
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
833
0
            return 0;
834
0
        }
835
0
    }
836
0
    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
837
0
    if (p != NULL) {
838
0
        unsigned int num;
839
840
0
        if (!OSSL_PARAM_get_uint(p, &num)) {
841
0
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
842
0
            return 0;
843
0
        }
844
0
        ctx->num = num;
845
0
    }
846
0
    return 1;
847
0
}
848
849
int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
850
                               size_t ivlen)
851
0
{
852
0
    if (ivlen != ctx->ivlen
853
0
        || ivlen > sizeof(ctx->iv)) {
854
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
855
0
        return 0;
856
0
    }
857
0
    ctx->iv_set = 1;
858
0
    memcpy(ctx->iv, iv, ivlen);
859
0
    memcpy(ctx->oiv, iv, ivlen);
860
0
    return 1;
861
0
}
862
863
void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
864
                                 size_t ivbits, unsigned int mode,
865
                                 uint64_t flags, const PROV_CIPHER_HW *hw,
866
                                 void *provctx)
867
0
{
868
0
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
869
870
0
    if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0)
871
0
        ctx->inverse_cipher = 1;
872
0
    if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0)
873
0
        ctx->variable_keylength = 1;
874
875
0
    ctx->pad = 1;
876
0
    ctx->keylen = ((kbits) / 8);
877
0
    ctx->ivlen = ((ivbits) / 8);
878
0
    ctx->hw = hw;
879
0
    ctx->mode = mode;
880
0
    ctx->blocksize = blkbits / 8;
881
0
    if (provctx != NULL)
882
0
        ctx->libctx = PROV_LIBCTX_OF(provctx); /* used for rand */
883
0
}