Coverage Report

Created: 2025-06-13 06:56

/src/openssl/crypto/evp/e_camellia.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2006-2021 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
 * Camellia low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <openssl/opensslconf.h>
17
18
#include <openssl/evp.h>
19
#include <openssl/err.h>
20
#include <string.h>
21
#include <assert.h>
22
#include <openssl/camellia.h>
23
#include "crypto/evp.h"
24
#include "crypto/modes.h"
25
#include "crypto/cmll_platform.h"
26
#include "evp_local.h"
27
28
static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
29
                             const unsigned char *iv, int enc);
30
31
/* Camellia subkey Structure */
32
typedef struct {
33
    CAMELLIA_KEY ks;
34
    block128_f block;
35
    union {
36
        cbc128_f cbc;
37
        ctr128_f ctr;
38
    } stream;
39
} EVP_CAMELLIA_KEY;
40
41
0
#define MAXBITCHUNK     ((size_t)1<<(sizeof(size_t)*8-4))
42
43
/* Attribute operation for Camellia */
44
#define data(ctx)       EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
45
46
#if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
47
/* ---------^^^ this is not a typo, just a way to detect that
48
 * assembler support was in general requested... */
49
# include "crypto/sparc_arch.h"
50
51
static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
52
                            const unsigned char *iv, int enc)
53
{
54
    int ret, mode, bits;
55
    EVP_CAMELLIA_KEY *dat =
56
        (EVP_CAMELLIA_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx);
57
58
    mode = EVP_CIPHER_CTX_get_mode(ctx);
59
    bits = EVP_CIPHER_CTX_get_key_length(ctx) * 8;
60
61
    cmll_t4_set_key(key, bits, &dat->ks);
62
63
    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
64
        && !enc) {
65
        ret = 0;
66
        dat->block = (block128_f) cmll_t4_decrypt;
67
        switch (bits) {
68
        case 128:
69
            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
70
                (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
71
            break;
72
        case 192:
73
        case 256:
74
            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
75
                (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
76
            break;
77
        default:
78
            ret = -1;
79
        }
80
    } else {
81
        ret = 0;
82
        dat->block = (block128_f) cmll_t4_encrypt;
83
        switch (bits) {
84
        case 128:
85
            if (mode == EVP_CIPH_CBC_MODE)
86
                dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
87
            else if (mode == EVP_CIPH_CTR_MODE)
88
                dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
89
            else
90
                dat->stream.cbc = NULL;
91
            break;
92
        case 192:
93
        case 256:
94
            if (mode == EVP_CIPH_CBC_MODE)
95
                dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
96
            else if (mode == EVP_CIPH_CTR_MODE)
97
                dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
98
            else
99
                dat->stream.cbc = NULL;
100
            break;
101
        default:
102
            ret = -1;
103
        }
104
    }
105
106
    if (ret < 0) {
107
        ERR_raise(ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
108
        return 0;
109
    }
110
111
    return 1;
112
}
113
114
# define cmll_t4_cbc_cipher camellia_cbc_cipher
115
static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
116
                              const unsigned char *in, size_t len);
117
118
# define cmll_t4_ecb_cipher camellia_ecb_cipher
119
static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
120
                              const unsigned char *in, size_t len);
121
122
# define cmll_t4_ofb_cipher camellia_ofb_cipher
123
static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
124
                              const unsigned char *in, size_t len);
125
126
# define cmll_t4_cfb_cipher camellia_cfb_cipher
127
static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
128
                              const unsigned char *in, size_t len);
129
130
# define cmll_t4_cfb8_cipher camellia_cfb8_cipher
131
static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
132
                               const unsigned char *in, size_t len);
133
134
# define cmll_t4_cfb1_cipher camellia_cfb1_cipher
135
static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
136
                               const unsigned char *in, size_t len);
137
138
# define cmll_t4_ctr_cipher camellia_ctr_cipher
139
static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
140
                              const unsigned char *in, size_t len);
141
142
# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
143
static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
144
        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
145
        flags|EVP_CIPH_##MODE##_MODE,   \
146
        EVP_ORIG_GLOBAL,                \
147
        cmll_t4_init_key,               \
148
        cmll_t4_##mode##_cipher,        \
149
        NULL,                           \
150
        sizeof(EVP_CAMELLIA_KEY),       \
151
        NULL,NULL,NULL,NULL }; \
152
static const EVP_CIPHER camellia_##keylen##_##mode = { \
153
        nid##_##keylen##_##nmode,blocksize,     \
154
        keylen/8,ivlen, \
155
        flags|EVP_CIPH_##MODE##_MODE,   \
156
        EVP_ORIG_GLOBAL,                \
157
        camellia_init_key,              \
158
        camellia_##mode##_cipher,       \
159
        NULL,                           \
160
        sizeof(EVP_CAMELLIA_KEY),       \
161
        NULL,NULL,NULL,NULL }; \
162
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
163
{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
164
165
#else
166
167
# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
168
static const EVP_CIPHER camellia_##keylen##_##mode = { \
169
        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
170
        flags|EVP_CIPH_##MODE##_MODE,   \
171
        EVP_ORIG_GLOBAL,                \
172
        camellia_init_key,              \
173
        camellia_##mode##_cipher,       \
174
        NULL,                           \
175
        sizeof(EVP_CAMELLIA_KEY),       \
176
        NULL,NULL,NULL,NULL }; \
177
42
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
42
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_cbc
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_ecb
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_ofb
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_cfb128
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_cfb1
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_cfb8
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_128_ctr
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_cbc
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_ecb
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_ofb
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_cfb128
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_cfb1
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_cfb8
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_192_ctr
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_cbc
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_ecb
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_ofb
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_cfb128
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_cfb1
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_cfb8
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
EVP_camellia_256_ctr
Line
Count
Source
177
2
const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
178
2
{ return &camellia_##keylen##_##mode; }
179
180
#endif
181
182
#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)             \
183
        BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
184
        BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
185
        BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
186
        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
187
        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)       \
188
        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)       \
189
        BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
190
191
/* The subkey for Camellia is generated. */
192
static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
193
                             const unsigned char *iv, int enc)
194
0
{
195
0
    int ret, mode;
196
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
197
198
0
    ret = Camellia_set_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8,
199
0
                           &dat->ks);
200
0
    if (ret < 0) {
201
0
        ERR_raise(ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
202
0
        return 0;
203
0
    }
204
205
0
    mode = EVP_CIPHER_CTX_get_mode(ctx);
206
0
    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
207
0
        && !enc) {
208
0
        dat->block = (block128_f) Camellia_decrypt;
209
0
        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
210
0
            (cbc128_f) Camellia_cbc_encrypt : NULL;
211
0
    } else {
212
0
        dat->block = (block128_f) Camellia_encrypt;
213
0
        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
214
0
            (cbc128_f) Camellia_cbc_encrypt : NULL;
215
0
    }
216
217
0
    return 1;
218
0
}
219
220
static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
221
                               const unsigned char *in, size_t len)
222
0
{
223
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
224
225
0
    if (dat->stream.cbc)
226
0
        (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv,
227
0
                            EVP_CIPHER_CTX_is_encrypting(ctx));
228
0
    else if (EVP_CIPHER_CTX_is_encrypting(ctx))
229
0
        CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
230
0
    else
231
0
        CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
232
233
0
    return 1;
234
0
}
235
236
static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
237
                               const unsigned char *in, size_t len)
238
0
{
239
0
    size_t bl = EVP_CIPHER_CTX_get_block_size(ctx);
240
0
    size_t i;
241
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
242
243
0
    if (len < bl)
244
0
        return 1;
245
246
0
    for (i = 0, len -= bl; i <= len; i += bl)
247
0
        (*dat->block) (in + i, out + i, &dat->ks);
248
249
0
    return 1;
250
0
}
251
252
static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
253
                               const unsigned char *in, size_t len)
254
0
{
255
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
256
257
0
    int num = EVP_CIPHER_CTX_get_num(ctx);
258
0
    CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, dat->block);
259
0
    EVP_CIPHER_CTX_set_num(ctx, num);
260
0
    return 1;
261
0
}
262
263
static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
264
                               const unsigned char *in, size_t len)
265
0
{
266
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
267
268
0
    int num = EVP_CIPHER_CTX_get_num(ctx);
269
0
    CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num,
270
0
                          EVP_CIPHER_CTX_is_encrypting(ctx), dat->block);
271
0
    EVP_CIPHER_CTX_set_num(ctx, num);
272
0
    return 1;
273
0
}
274
275
static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
276
                                const unsigned char *in, size_t len)
277
0
{
278
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
279
280
0
    int num = EVP_CIPHER_CTX_get_num(ctx);
281
0
    CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, ctx->iv, &num,
282
0
                            EVP_CIPHER_CTX_is_encrypting(ctx), dat->block);
283
0
    EVP_CIPHER_CTX_set_num(ctx, num);
284
0
    return 1;
285
0
}
286
287
static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
288
                                const unsigned char *in, size_t len)
289
0
{
290
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
291
292
0
    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
293
0
        int num = EVP_CIPHER_CTX_get_num(ctx);
294
0
        CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, ctx->iv, &num,
295
0
                                EVP_CIPHER_CTX_is_encrypting(ctx),
296
0
                                dat->block);
297
0
        EVP_CIPHER_CTX_set_num(ctx, num);
298
0
        return 1;
299
0
    }
300
301
0
    while (len >= MAXBITCHUNK) {
302
0
        int num = EVP_CIPHER_CTX_get_num(ctx);
303
0
        CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
304
0
                                ctx->iv, &num,
305
0
                                EVP_CIPHER_CTX_is_encrypting(ctx),
306
0
                                dat->block);
307
0
        EVP_CIPHER_CTX_set_num(ctx, num);
308
0
        len -= MAXBITCHUNK;
309
0
        out += MAXBITCHUNK;
310
0
        in  += MAXBITCHUNK;
311
0
    }
312
0
    if (len) {
313
0
        int num = EVP_CIPHER_CTX_get_num(ctx);
314
0
        CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
315
0
                                ctx->iv, &num,
316
0
                                EVP_CIPHER_CTX_is_encrypting(ctx),
317
0
                                dat->block);
318
0
        EVP_CIPHER_CTX_set_num(ctx, num);
319
0
    }
320
321
0
    return 1;
322
0
}
323
324
static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
325
                               const unsigned char *in, size_t len)
326
0
{
327
0
    int snum = EVP_CIPHER_CTX_get_num(ctx);
328
0
    unsigned int num;
329
0
    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx);
330
331
0
    if (snum < 0)
332
0
        return 0;
333
0
    num = snum;
334
0
    if (dat->stream.ctr)
335
0
        CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv,
336
0
                                    EVP_CIPHER_CTX_buf_noconst(ctx),
337
0
                                    &num,
338
0
                                    dat->stream.ctr);
339
0
    else
340
0
        CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv,
341
0
                              EVP_CIPHER_CTX_buf_noconst(ctx), &num,
342
0
                              dat->block);
343
0
    EVP_CIPHER_CTX_set_num(ctx, num);
344
0
    return 1;
345
0
}
346
347
BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
348
    BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
349
    BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)