Coverage Report

Created: 2025-12-10 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/evp/e_aria.c
Line
Count
Source
1
/*
2
 * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2017, Oracle and/or its affiliates.  All rights reserved.
4
 *
5
 * Licensed under the Apache License 2.0 (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 */
10
11
#include "internal/deprecated.h"
12
13
#include "internal/cryptlib.h"
14
#ifndef OPENSSL_NO_ARIA
15
#include <openssl/evp.h>
16
#include <openssl/modes.h>
17
#include <openssl/rand.h>
18
#include "crypto/aria.h"
19
#include "crypto/evp.h"
20
#include "crypto/modes.h"
21
#include "evp_local.h"
22
23
/* ARIA subkey Structure */
24
typedef struct {
25
    ARIA_KEY ks;
26
} EVP_ARIA_KEY;
27
28
/* ARIA GCM context */
29
typedef struct {
30
    union {
31
        OSSL_UNION_ALIGN;
32
        ARIA_KEY ks;
33
    } ks; /* ARIA subkey to use */
34
    int key_set; /* Set if key initialised */
35
    int iv_set; /* Set if an iv is set */
36
    GCM128_CONTEXT gcm;
37
    unsigned char *iv; /* Temporary IV store */
38
    int ivlen; /* IV length */
39
    int taglen;
40
    int iv_gen; /* It is OK to generate IVs */
41
    int tls_aad_len; /* TLS AAD length */
42
} EVP_ARIA_GCM_CTX;
43
44
/* ARIA CCM context */
45
typedef struct {
46
    union {
47
        OSSL_UNION_ALIGN;
48
        ARIA_KEY ks;
49
    } ks; /* ARIA key schedule to use */
50
    int key_set; /* Set if key initialised */
51
    int iv_set; /* Set if an iv is set */
52
    int tag_set; /* Set if tag is valid */
53
    int len_set; /* Set if message length set */
54
    int L, M; /* L and M parameters from RFC3610 */
55
    int tls_aad_len; /* TLS AAD length */
56
    CCM128_CONTEXT ccm;
57
    ccm128_f str;
58
} EVP_ARIA_CCM_CTX;
59
60
/* The subkey for ARIA is generated. */
61
static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
62
    const unsigned char *iv, int enc)
63
0
{
64
0
    int ret;
65
0
    int mode = EVP_CIPHER_CTX_get_mode(ctx);
66
67
0
    if (enc || (mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE))
68
0
        ret = ossl_aria_set_encrypt_key(key,
69
0
            EVP_CIPHER_CTX_get_key_length(ctx) * 8,
70
0
            EVP_CIPHER_CTX_get_cipher_data(ctx));
71
0
    else
72
0
        ret = ossl_aria_set_decrypt_key(key,
73
0
            EVP_CIPHER_CTX_get_key_length(ctx) * 8,
74
0
            EVP_CIPHER_CTX_get_cipher_data(ctx));
75
0
    if (ret < 0) {
76
0
        ERR_raise(ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED);
77
0
        return 0;
78
0
    }
79
0
    return 1;
80
0
}
81
82
static void aria_cbc_encrypt(const unsigned char *in, unsigned char *out,
83
    size_t len, const ARIA_KEY *key,
84
    unsigned char *ivec, const int enc)
85
0
{
86
87
0
    if (enc)
88
0
        CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
89
0
            (block128_f)ossl_aria_encrypt);
90
0
    else
91
0
        CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
92
0
            (block128_f)ossl_aria_encrypt);
93
0
}
94
95
static void aria_cfb128_encrypt(const unsigned char *in, unsigned char *out,
96
    size_t length, const ARIA_KEY *key,
97
    unsigned char *ivec, int *num, const int enc)
98
0
{
99
100
0
    CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
101
0
        (block128_f)ossl_aria_encrypt);
102
0
}
103
104
static void aria_cfb1_encrypt(const unsigned char *in, unsigned char *out,
105
    size_t length, const ARIA_KEY *key,
106
    unsigned char *ivec, int *num, const int enc)
107
0
{
108
0
    CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
109
0
        (block128_f)ossl_aria_encrypt);
110
0
}
111
112
static void aria_cfb8_encrypt(const unsigned char *in, unsigned char *out,
113
    size_t length, const ARIA_KEY *key,
114
    unsigned char *ivec, int *num, const int enc)
115
0
{
116
0
    CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
117
0
        (block128_f)ossl_aria_encrypt);
118
0
}
119
120
static void aria_ecb_encrypt(const unsigned char *in, unsigned char *out,
121
    const ARIA_KEY *key, const int enc)
122
0
{
123
0
    ossl_aria_encrypt(in, out, key);
124
0
}
125
126
static void aria_ofb128_encrypt(const unsigned char *in, unsigned char *out,
127
    size_t length, const ARIA_KEY *key,
128
    unsigned char *ivec, int *num)
129
0
{
130
0
    CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
131
0
        (block128_f)ossl_aria_encrypt);
132
0
}
133
134
IMPLEMENT_BLOCK_CIPHER(aria_128, ks, aria, EVP_ARIA_KEY,
135
    NID_aria_128, 16, 16, 16, 128,
136
    0, aria_init_key, NULL,
137
    EVP_CIPHER_set_asn1_iv,
138
    EVP_CIPHER_get_asn1_iv,
139
    NULL)
140
IMPLEMENT_BLOCK_CIPHER(aria_192, ks, aria, EVP_ARIA_KEY,
141
    NID_aria_192, 16, 24, 16, 128,
142
    0, aria_init_key, NULL,
143
    EVP_CIPHER_set_asn1_iv,
144
    EVP_CIPHER_get_asn1_iv,
145
    NULL)
146
IMPLEMENT_BLOCK_CIPHER(aria_256, ks, aria, EVP_ARIA_KEY,
147
    NID_aria_256, 16, 32, 16, 128,
148
    0, aria_init_key, NULL,
149
    EVP_CIPHER_set_asn1_iv,
150
    EVP_CIPHER_get_asn1_iv,
151
    NULL)
152
153
#define IMPLEMENT_ARIA_CFBR(ksize, cbits) \
154
    IMPLEMENT_CFBR(aria, aria, EVP_ARIA_KEY, ks, ksize, cbits, 16, 0)
155
IMPLEMENT_ARIA_CFBR(128, 1)
156
IMPLEMENT_ARIA_CFBR(192, 1)
157
IMPLEMENT_ARIA_CFBR(256, 1)
158
IMPLEMENT_ARIA_CFBR(128, 8)
159
IMPLEMENT_ARIA_CFBR(192, 8)
160
IMPLEMENT_ARIA_CFBR(256, 8)
161
162
#define BLOCK_CIPHER_generic(nid, keylen, blocksize, ivlen, nmode, mode, MODE, flags) \
163
    static const EVP_CIPHER aria_##keylen##_##mode = {                                \
164
        nid##_##keylen##_##nmode, blocksize, keylen / 8, ivlen,                       \
165
        flags | EVP_CIPH_##MODE##_MODE,                                               \
166
        EVP_ORIG_GLOBAL,                                                              \
167
        aria_init_key,                                                                \
168
        aria_##mode##_cipher,                                                         \
169
        NULL,                                                                         \
170
        sizeof(EVP_ARIA_KEY),                                                         \
171
        NULL, NULL, NULL, NULL                                                        \
172
    };                                                                                \
173
    const EVP_CIPHER *EVP_aria_##keylen##_##mode(void)                                \
174
9
    {                                                                                 \
175
9
        return &aria_##keylen##_##mode;                                               \
176
9
    }
EVP_aria_128_ctr
Line
Count
Source
174
3
    {                                                                                 \
175
3
        return &aria_##keylen##_##mode;                                               \
176
3
    }
EVP_aria_192_ctr
Line
Count
Source
174
3
    {                                                                                 \
175
3
        return &aria_##keylen##_##mode;                                               \
176
3
    }
EVP_aria_256_ctr
Line
Count
Source
174
3
    {                                                                                 \
175
3
        return &aria_##keylen##_##mode;                                               \
176
3
    }
177
178
static int aria_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
179
    const unsigned char *in, size_t len)
180
0
{
181
0
    int n = EVP_CIPHER_CTX_get_num(ctx);
182
0
    unsigned int num;
183
0
    EVP_ARIA_KEY *dat = EVP_C_DATA(EVP_ARIA_KEY, ctx);
184
185
0
    if (n < 0)
186
0
        return 0;
187
0
    num = (unsigned int)n;
188
189
0
    CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv,
190
0
        EVP_CIPHER_CTX_buf_noconst(ctx), &num,
191
0
        (block128_f)ossl_aria_encrypt);
192
0
    EVP_CIPHER_CTX_set_num(ctx, num);
193
0
    return 1;
194
0
}
195
196
BLOCK_CIPHER_generic(NID_aria, 128, 1, 16, ctr, ctr, CTR, 0)
197
    BLOCK_CIPHER_generic(NID_aria, 192, 1, 16, ctr, ctr, CTR, 0)
198
        BLOCK_CIPHER_generic(NID_aria, 256, 1, 16, ctr, ctr, CTR, 0)
199
200
    /* Authenticated cipher modes (GCM/CCM) */
201
202
    /* increment counter (64-bit int) by 1 */
203
    static void ctr64_inc(unsigned char *counter)
204
0
{
205
0
    int n = 8;
206
0
    unsigned char c;
207
208
0
    do {
209
0
        --n;
210
0
        c = counter[n];
211
0
        ++c;
212
0
        counter[n] = c;
213
0
        if (c)
214
0
            return;
215
0
    } while (n);
216
0
}
217
218
static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
219
    const unsigned char *iv, int enc)
220
0
{
221
0
    int ret;
222
0
    EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx);
223
224
0
    if (!iv && !key)
225
0
        return 1;
226
0
    if (key) {
227
0
        ret = ossl_aria_set_encrypt_key(key,
228
0
            EVP_CIPHER_CTX_get_key_length(ctx) * 8,
229
0
            &gctx->ks.ks);
230
0
        CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
231
0
            (block128_f)ossl_aria_encrypt);
232
0
        if (ret < 0) {
233
0
            ERR_raise(ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED);
234
0
            return 0;
235
0
        }
236
237
        /*
238
         * If we have an iv can set it directly, otherwise use saved IV.
239
         */
240
0
        if (iv == NULL && gctx->iv_set)
241
0
            iv = gctx->iv;
242
0
        if (iv) {
243
0
            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
244
0
            gctx->iv_set = 1;
245
0
        }
246
0
        gctx->key_set = 1;
247
0
    } else {
248
        /* If key set use IV, otherwise copy */
249
0
        if (gctx->key_set)
250
0
            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
251
0
        else
252
0
            memcpy(gctx->iv, iv, gctx->ivlen);
253
0
        gctx->iv_set = 1;
254
0
        gctx->iv_gen = 0;
255
0
    }
256
0
    return 1;
257
0
}
258
259
static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
260
0
{
261
0
    EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, c);
262
263
0
    switch (type) {
264
0
    case EVP_CTRL_INIT:
265
0
        gctx->key_set = 0;
266
0
        gctx->iv_set = 0;
267
0
        gctx->ivlen = EVP_CIPHER_get_iv_length(c->cipher);
268
0
        gctx->iv = c->iv;
269
0
        gctx->taglen = -1;
270
0
        gctx->iv_gen = 0;
271
0
        gctx->tls_aad_len = -1;
272
0
        return 1;
273
274
0
    case EVP_CTRL_GET_IVLEN:
275
0
        *(int *)ptr = gctx->ivlen;
276
0
        return 1;
277
278
0
    case EVP_CTRL_AEAD_SET_IVLEN:
279
0
        if (arg <= 0)
280
0
            return 0;
281
        /* Allocate memory for IV if needed */
282
0
        if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
283
0
            if (gctx->iv != c->iv)
284
0
                OPENSSL_free(gctx->iv);
285
0
            if ((gctx->iv = OPENSSL_malloc(arg)) == NULL)
286
0
                return 0;
287
0
        }
288
0
        gctx->ivlen = arg;
289
0
        return 1;
290
291
0
    case EVP_CTRL_AEAD_SET_TAG:
292
0
        if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_is_encrypting(c))
293
0
            return 0;
294
0
        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
295
0
        gctx->taglen = arg;
296
0
        return 1;
297
298
0
    case EVP_CTRL_AEAD_GET_TAG:
299
0
        if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_is_encrypting(c)
300
0
            || gctx->taglen < 0)
301
0
            return 0;
302
0
        memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg);
303
0
        return 1;
304
305
0
    case EVP_CTRL_GCM_SET_IV_FIXED:
306
        /* Special case: -1 length restores whole IV */
307
0
        if (arg == -1) {
308
0
            memcpy(gctx->iv, ptr, gctx->ivlen);
309
0
            gctx->iv_gen = 1;
310
0
            return 1;
311
0
        }
312
        /*
313
         * Fixed field must be at least 4 bytes and invocation field at least
314
         * 8.
315
         */
316
0
        if ((arg < 4) || (gctx->ivlen - arg) < 8)
317
0
            return 0;
318
0
        if (arg)
319
0
            memcpy(gctx->iv, ptr, arg);
320
0
        if (EVP_CIPHER_CTX_is_encrypting(c)
321
0
            && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
322
0
            return 0;
323
0
        gctx->iv_gen = 1;
324
0
        return 1;
325
326
0
    case EVP_CTRL_GCM_IV_GEN:
327
0
        if (gctx->iv_gen == 0 || gctx->key_set == 0)
328
0
            return 0;
329
0
        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
330
0
        if (arg <= 0 || arg > gctx->ivlen)
331
0
            arg = gctx->ivlen;
332
0
        memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
333
        /*
334
         * Invocation field will be at least 8 bytes in size and so no need
335
         * to check wrap around or increment more than last 8 bytes.
336
         */
337
0
        ctr64_inc(gctx->iv + gctx->ivlen - 8);
338
0
        gctx->iv_set = 1;
339
0
        return 1;
340
341
0
    case EVP_CTRL_GCM_SET_IV_INV:
342
0
        if (gctx->iv_gen == 0 || gctx->key_set == 0
343
0
            || EVP_CIPHER_CTX_is_encrypting(c))
344
0
            return 0;
345
0
        memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
346
0
        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
347
0
        gctx->iv_set = 1;
348
0
        return 1;
349
350
0
    case EVP_CTRL_AEAD_TLS1_AAD:
351
        /* Save the AAD for later use */
352
0
        if (arg != EVP_AEAD_TLS1_AAD_LEN)
353
0
            return 0;
354
0
        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
355
0
        gctx->tls_aad_len = arg;
356
0
        {
357
0
            unsigned int len = EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
358
0
                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
359
            /* Correct length for explicit IV */
360
0
            if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
361
0
                return 0;
362
0
            len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
363
            /* If decrypting correct for tag too */
364
0
            if (!EVP_CIPHER_CTX_is_encrypting(c)) {
365
0
                if (len < EVP_GCM_TLS_TAG_LEN)
366
0
                    return 0;
367
0
                len -= EVP_GCM_TLS_TAG_LEN;
368
0
            }
369
0
            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
370
0
            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
371
0
        }
372
        /* Extra padding: tag appended to record */
373
0
        return EVP_GCM_TLS_TAG_LEN;
374
375
0
    case EVP_CTRL_COPY: {
376
0
        EVP_CIPHER_CTX *out = ptr;
377
0
        EVP_ARIA_GCM_CTX *gctx_out = EVP_C_DATA(EVP_ARIA_GCM_CTX, out);
378
0
        if (gctx->gcm.key) {
379
0
            if (gctx->gcm.key != &gctx->ks)
380
0
                return 0;
381
0
            gctx_out->gcm.key = &gctx_out->ks;
382
0
        }
383
0
        if (gctx->iv == c->iv)
384
0
            gctx_out->iv = out->iv;
385
0
        else {
386
0
            if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL)
387
0
                return 0;
388
0
            memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
389
0
        }
390
0
        return 1;
391
0
    }
392
393
0
    default:
394
0
        return -1;
395
0
    }
396
0
}
397
398
static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
399
    const unsigned char *in, size_t len)
400
0
{
401
0
    EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx);
402
0
    int rv = -1;
403
404
    /* Encrypt/decrypt must be performed in place */
405
0
    if (out != in
406
0
        || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
407
0
        return -1;
408
    /*
409
     * Set IV from start of buffer or generate IV and write to start of
410
     * buffer.
411
     */
412
0
    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_is_encrypting(ctx) ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
413
0
            EVP_GCM_TLS_EXPLICIT_IV_LEN, out)
414
0
        <= 0)
415
0
        goto err;
416
    /* Use saved AAD */
417
0
    if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
418
0
            gctx->tls_aad_len))
419
0
        goto err;
420
    /* Fix buffer and length to point to payload */
421
0
    in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
422
0
    out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
423
0
    len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
424
0
    if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
425
        /* Encrypt payload */
426
0
        if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
427
0
            goto err;
428
0
        out += len;
429
        /* Finally write tag */
430
0
        CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
431
0
        rv = (int)(len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN);
432
0
    } else {
433
        /* Decrypt */
434
0
        if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
435
0
            goto err;
436
        /* Retrieve tag */
437
0
        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
438
0
            EVP_GCM_TLS_TAG_LEN);
439
        /* If tag mismatch wipe buffer */
440
0
        if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len,
441
0
                EVP_GCM_TLS_TAG_LEN)) {
442
0
            OPENSSL_cleanse(out, len);
443
0
            goto err;
444
0
        }
445
0
        rv = (int)len;
446
0
    }
447
448
0
err:
449
0
    gctx->iv_set = 0;
450
0
    gctx->tls_aad_len = -1;
451
0
    return rv;
452
0
}
453
454
static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
455
    const unsigned char *in, size_t len)
456
0
{
457
0
    EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx);
458
459
    /* If not set up, return error */
460
0
    if (!gctx->key_set)
461
0
        return -1;
462
463
0
    if (gctx->tls_aad_len >= 0)
464
0
        return aria_gcm_tls_cipher(ctx, out, in, len);
465
466
0
    if (!gctx->iv_set)
467
0
        return -1;
468
0
    if (in) {
469
0
        if (out == NULL) {
470
0
            if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
471
0
                return -1;
472
0
        } else if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
473
0
            if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
474
0
                return -1;
475
0
        } else {
476
0
            if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
477
0
                return -1;
478
0
        }
479
0
        return (int)len;
480
0
    }
481
0
    if (!EVP_CIPHER_CTX_is_encrypting(ctx)) {
482
0
        if (gctx->taglen < 0)
483
0
            return -1;
484
0
        if (CRYPTO_gcm128_finish(&gctx->gcm,
485
0
                EVP_CIPHER_CTX_buf_noconst(ctx),
486
0
                gctx->taglen)
487
0
            != 0)
488
0
            return -1;
489
0
        gctx->iv_set = 0;
490
0
        return 0;
491
0
    }
492
0
    CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16);
493
0
    gctx->taglen = 16;
494
    /* Don't reuse the IV */
495
0
    gctx->iv_set = 0;
496
0
    return 0;
497
0
}
498
499
static int aria_gcm_cleanup(EVP_CIPHER_CTX *ctx)
500
0
{
501
0
    EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx);
502
503
0
    if (gctx->iv != ctx->iv)
504
0
        OPENSSL_free(gctx->iv);
505
506
0
    return 1;
507
0
}
508
509
static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
510
    const unsigned char *iv, int enc)
511
0
{
512
0
    int ret;
513
0
    EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, ctx);
514
515
0
    if (!iv && !key)
516
0
        return 1;
517
518
0
    if (key) {
519
0
        ret = ossl_aria_set_encrypt_key(key,
520
0
            EVP_CIPHER_CTX_get_key_length(ctx) * 8,
521
0
            &cctx->ks.ks);
522
0
        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
523
0
            &cctx->ks, (block128_f)ossl_aria_encrypt);
524
0
        if (ret < 0) {
525
0
            ERR_raise(ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED);
526
0
            return 0;
527
0
        }
528
0
        cctx->str = NULL;
529
0
        cctx->key_set = 1;
530
0
    }
531
0
    if (iv) {
532
0
        memcpy(ctx->iv, iv, 15 - cctx->L);
533
0
        cctx->iv_set = 1;
534
0
    }
535
0
    return 1;
536
0
}
537
538
static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
539
0
{
540
0
    EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, c);
541
542
0
    switch (type) {
543
0
    case EVP_CTRL_INIT:
544
0
        cctx->key_set = 0;
545
0
        cctx->iv_set = 0;
546
0
        cctx->L = 8;
547
0
        cctx->M = 12;
548
0
        cctx->tag_set = 0;
549
0
        cctx->len_set = 0;
550
0
        cctx->tls_aad_len = -1;
551
0
        return 1;
552
553
0
    case EVP_CTRL_GET_IVLEN:
554
0
        *(int *)ptr = 15 - cctx->L;
555
0
        return 1;
556
557
0
    case EVP_CTRL_AEAD_TLS1_AAD:
558
        /* Save the AAD for later use */
559
0
        if (arg != EVP_AEAD_TLS1_AAD_LEN)
560
0
            return 0;
561
0
        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
562
0
        cctx->tls_aad_len = arg;
563
0
        {
564
0
            uint16_t len = EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
565
0
                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
566
            /* Correct length for explicit IV */
567
0
            if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
568
0
                return 0;
569
0
            len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
570
            /* If decrypting correct for tag too */
571
0
            if (!EVP_CIPHER_CTX_is_encrypting(c)) {
572
0
                if (len < cctx->M)
573
0
                    return 0;
574
0
                len -= cctx->M;
575
0
            }
576
0
            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
577
0
            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
578
0
        }
579
        /* Extra padding: tag appended to record */
580
0
        return cctx->M;
581
582
0
    case EVP_CTRL_CCM_SET_IV_FIXED:
583
        /* Sanity check length */
584
0
        if (arg != EVP_CCM_TLS_FIXED_IV_LEN)
585
0
            return 0;
586
        /* Just copy to first part of IV */
587
0
        memcpy(c->iv, ptr, arg);
588
0
        return 1;
589
590
0
    case EVP_CTRL_AEAD_SET_IVLEN:
591
0
        arg = 15 - arg;
592
        /* fall through */
593
0
    case EVP_CTRL_CCM_SET_L:
594
0
        if (arg < 2 || arg > 8)
595
0
            return 0;
596
0
        cctx->L = arg;
597
0
        return 1;
598
0
    case EVP_CTRL_AEAD_SET_TAG:
599
0
        if ((arg & 1) || arg < 4 || arg > 16)
600
0
            return 0;
601
0
        if (EVP_CIPHER_CTX_is_encrypting(c) && ptr)
602
0
            return 0;
603
0
        if (ptr) {
604
0
            cctx->tag_set = 1;
605
0
            memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
606
0
        }
607
0
        cctx->M = arg;
608
0
        return 1;
609
610
0
    case EVP_CTRL_AEAD_GET_TAG:
611
0
        if (!EVP_CIPHER_CTX_is_encrypting(c) || !cctx->tag_set)
612
0
            return 0;
613
0
        if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
614
0
            return 0;
615
0
        cctx->tag_set = 0;
616
0
        cctx->iv_set = 0;
617
0
        cctx->len_set = 0;
618
0
        return 1;
619
620
0
    case EVP_CTRL_COPY: {
621
0
        EVP_CIPHER_CTX *out = ptr;
622
0
        EVP_ARIA_CCM_CTX *cctx_out = EVP_C_DATA(EVP_ARIA_CCM_CTX, out);
623
0
        if (cctx->ccm.key) {
624
0
            if (cctx->ccm.key != &cctx->ks)
625
0
                return 0;
626
0
            cctx_out->ccm.key = &cctx_out->ks;
627
0
        }
628
0
        return 1;
629
0
    }
630
631
0
    default:
632
0
        return -1;
633
0
    }
634
0
}
635
636
static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
637
    const unsigned char *in, size_t len)
638
0
{
639
0
    EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, ctx);
640
0
    CCM128_CONTEXT *ccm = &cctx->ccm;
641
642
    /* Encrypt/decrypt must be performed in place */
643
0
    if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M))
644
0
        return -1;
645
    /* If encrypting set explicit IV from sequence number (start of AAD) */
646
0
    if (EVP_CIPHER_CTX_is_encrypting(ctx))
647
0
        memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx),
648
0
            EVP_CCM_TLS_EXPLICIT_IV_LEN);
649
    /* Get rest of IV from explicit IV */
650
0
    memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in,
651
0
        EVP_CCM_TLS_EXPLICIT_IV_LEN);
652
    /* Correct length value */
653
0
    len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
654
0
    if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,
655
0
            len))
656
0
        return -1;
657
    /* Use saved AAD */
658
0
    CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx),
659
0
        cctx->tls_aad_len);
660
    /* Fix buffer to point to payload */
661
0
    in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
662
0
    out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
663
0
    if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
664
0
        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str)
665
0
                      : CRYPTO_ccm128_encrypt(ccm, in, out, len))
666
0
            return -1;
667
0
        if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M))
668
0
            return -1;
669
0
        return (int)(len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M);
670
0
    } else {
671
0
        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, cctx->str)
672
0
                      : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
673
0
            unsigned char tag[16];
674
0
            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
675
0
                if (!CRYPTO_memcmp(tag, in + len, cctx->M))
676
0
                    return (int)len;
677
0
            }
678
0
        }
679
0
        OPENSSL_cleanse(out, len);
680
0
        return -1;
681
0
    }
682
0
}
683
684
static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
685
    const unsigned char *in, size_t len)
686
0
{
687
0
    EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, ctx);
688
0
    CCM128_CONTEXT *ccm = &cctx->ccm;
689
690
    /* If not set up, return error */
691
0
    if (!cctx->key_set)
692
0
        return -1;
693
694
0
    if (cctx->tls_aad_len >= 0)
695
0
        return aria_ccm_tls_cipher(ctx, out, in, len);
696
697
    /* EVP_*Final() doesn't return any data */
698
0
    if (in == NULL && out != NULL)
699
0
        return 0;
700
701
0
    if (!cctx->iv_set)
702
0
        return -1;
703
704
0
    if (!out) {
705
0
        if (!in) {
706
0
            if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
707
0
                return -1;
708
0
            cctx->len_set = 1;
709
0
            return (int)len;
710
0
        }
711
        /* If have AAD need message length */
712
0
        if (!cctx->len_set && len)
713
0
            return -1;
714
0
        CRYPTO_ccm128_aad(ccm, in, len);
715
0
        return (int)len;
716
0
    }
717
718
    /* The tag must be set before actually decrypting data */
719
0
    if (!EVP_CIPHER_CTX_is_encrypting(ctx) && !cctx->tag_set)
720
0
        return -1;
721
722
    /* If not set length yet do it */
723
0
    if (!cctx->len_set) {
724
0
        if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
725
0
            return -1;
726
0
        cctx->len_set = 1;
727
0
    }
728
0
    if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
729
0
        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str)
730
0
                      : CRYPTO_ccm128_encrypt(ccm, in, out, len))
731
0
            return -1;
732
0
        cctx->tag_set = 1;
733
0
        return (int)len;
734
0
    } else {
735
0
        int rv = -1;
736
0
        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
737
0
                            cctx->str)
738
0
                      : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
739
0
            unsigned char tag[16];
740
0
            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
741
0
                if (!CRYPTO_memcmp(tag, EVP_CIPHER_CTX_buf_noconst(ctx),
742
0
                        cctx->M))
743
0
                    rv = (int)len;
744
0
            }
745
0
        }
746
0
        if (rv == -1)
747
0
            OPENSSL_cleanse(out, len);
748
0
        cctx->iv_set = 0;
749
0
        cctx->tag_set = 0;
750
0
        cctx->len_set = 0;
751
0
        return rv;
752
0
    }
753
0
}
754
755
#define aria_ccm_cleanup NULL
756
757
#define ARIA_AUTH_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1    \
758
    | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
759
    | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT   \
760
    | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \
761
    | EVP_CIPH_CUSTOM_IV_LENGTH)
762
763
#define BLOCK_CIPHER_aead(keylen, mode, MODE)          \
764
    static const EVP_CIPHER aria_##keylen##_##mode = { \
765
        NID_aria_##keylen##_##mode,                    \
766
        1, keylen / 8, 12,                             \
767
        ARIA_AUTH_FLAGS | EVP_CIPH_##MODE##_MODE,      \
768
        EVP_ORIG_GLOBAL,                               \
769
        aria_##mode##_init_key,                        \
770
        aria_##mode##_cipher,                          \
771
        aria_##mode##_cleanup,                         \
772
        sizeof(EVP_ARIA_##MODE##_CTX),                 \
773
        NULL, NULL, aria_##mode##_ctrl, NULL           \
774
    };                                                 \
775
    const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \
776
18
    {                                                  \
777
18
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
18
    }
EVP_aria_128_gcm
Line
Count
Source
776
3
    {                                                  \
777
3
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
3
    }
EVP_aria_192_gcm
Line
Count
Source
776
3
    {                                                  \
777
3
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
3
    }
EVP_aria_256_gcm
Line
Count
Source
776
3
    {                                                  \
777
3
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
3
    }
EVP_aria_128_ccm
Line
Count
Source
776
3
    {                                                  \
777
3
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
3
    }
EVP_aria_192_ccm
Line
Count
Source
776
3
    {                                                  \
777
3
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
3
    }
EVP_aria_256_ccm
Line
Count
Source
776
3
    {                                                  \
777
3
        return (EVP_CIPHER *)&aria_##keylen##_##mode;  \
778
3
    }
779
780
BLOCK_CIPHER_aead(128, gcm, GCM)
781
    BLOCK_CIPHER_aead(192, gcm, GCM)
782
        BLOCK_CIPHER_aead(256, gcm, GCM)
783
784
            BLOCK_CIPHER_aead(128, ccm, CCM)
785
                BLOCK_CIPHER_aead(192, ccm, CCM)
786
                    BLOCK_CIPHER_aead(256, ccm, CCM)
787
788
#endif