Coverage Report

Created: 2018-08-29 13:53

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