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_sm4.c
Line
Count
Source
1
/*
2
 * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright 2017 Ribose Inc. All Rights Reserved.
4
 * Ported from Ribose contributions from Botan.
5
 *
6
 * Licensed under the Apache License 2.0 (the "License").  You may not use
7
 * this file except in compliance with the License.  You can obtain a copy
8
 * in the file LICENSE in the source distribution or at
9
 * https://www.openssl.org/source/license.html
10
 */
11
12
#include "internal/deprecated.h"
13
14
#include "internal/cryptlib.h"
15
#ifndef OPENSSL_NO_SM4
16
#include <openssl/evp.h>
17
#include <openssl/modes.h>
18
#include "crypto/sm4.h"
19
#include "crypto/evp.h"
20
#include "crypto/sm4_platform.h"
21
#include "evp_local.h"
22
23
typedef struct {
24
    union {
25
        OSSL_UNION_ALIGN;
26
        SM4_KEY ks;
27
    } ks;
28
    block128_f block;
29
    union {
30
        ecb128_f ecb;
31
        cbc128_f cbc;
32
        ctr128_f ctr;
33
    } stream;
34
} EVP_SM4_KEY;
35
36
#define BLOCK_CIPHER_generic(nid, blocksize, ivlen, nmode, mode, MODE, flags) \
37
    static const EVP_CIPHER sm4_##mode = {                                    \
38
        nid##_##nmode, blocksize, 128 / 8, ivlen,                             \
39
        flags | EVP_CIPH_##MODE##_MODE,                                       \
40
        EVP_ORIG_GLOBAL,                                                      \
41
        sm4_init_key,                                                         \
42
        sm4_##mode##_cipher,                                                  \
43
        NULL,                                                                 \
44
        sizeof(EVP_SM4_KEY),                                                  \
45
        NULL, NULL, NULL, NULL                                                \
46
    };                                                                        \
47
    const EVP_CIPHER *EVP_sm4_##mode(void)                                    \
48
15
    {                                                                         \
49
15
        return &sm4_##mode;                                                   \
50
15
    }
EVP_sm4_cbc
Line
Count
Source
48
3
    {                                                                         \
49
3
        return &sm4_##mode;                                                   \
50
3
    }
EVP_sm4_ecb
Line
Count
Source
48
3
    {                                                                         \
49
3
        return &sm4_##mode;                                                   \
50
3
    }
EVP_sm4_ofb
Line
Count
Source
48
3
    {                                                                         \
49
3
        return &sm4_##mode;                                                   \
50
3
    }
EVP_sm4_cfb128
Line
Count
Source
48
3
    {                                                                         \
49
3
        return &sm4_##mode;                                                   \
50
3
    }
EVP_sm4_ctr
Line
Count
Source
48
3
    {                                                                         \
49
3
        return &sm4_##mode;                                                   \
50
3
    }
51
52
#define DEFINE_BLOCK_CIPHERS(nid, flags)                                                               \
53
    BLOCK_CIPHER_generic(nid, 16, 16, cbc, cbc, CBC, flags | EVP_CIPH_FLAG_DEFAULT_ASN1)               \
54
        BLOCK_CIPHER_generic(nid, 16, 0, ecb, ecb, ECB, flags | EVP_CIPH_FLAG_DEFAULT_ASN1)            \
55
            BLOCK_CIPHER_generic(nid, 1, 16, ofb128, ofb, OFB, flags | EVP_CIPH_FLAG_DEFAULT_ASN1)     \
56
                BLOCK_CIPHER_generic(nid, 1, 16, cfb128, cfb, CFB, flags | EVP_CIPH_FLAG_DEFAULT_ASN1) \
57
                    BLOCK_CIPHER_generic(nid, 1, 16, ctr, ctr, CTR, flags)
58
59
static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
60
    const unsigned char *iv, int enc)
61
0
{
62
0
    int mode;
63
0
    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
64
65
0
    mode = EVP_CIPHER_CTX_get_mode(ctx);
66
0
    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
67
0
        && !enc) {
68
#ifdef HWSM4_CAPABLE
69
        if (HWSM4_CAPABLE) {
70
            HWSM4_set_decrypt_key(key, &dat->ks.ks);
71
            dat->block = (block128_f)HWSM4_decrypt;
72
            dat->stream.cbc = NULL;
73
#ifdef HWSM4_cbc_encrypt
74
            if (mode == EVP_CIPH_CBC_MODE)
75
                dat->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
76
#endif
77
#ifdef HWSM4_ecb_encrypt
78
            if (mode == EVP_CIPH_ECB_MODE)
79
                dat->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
80
#endif
81
        } else
82
#endif
83
#ifdef VPSM4_CAPABLE
84
            if (VPSM4_CAPABLE) {
85
            vpsm4_set_decrypt_key(key, &dat->ks.ks);
86
            dat->block = (block128_f)vpsm4_decrypt;
87
            dat->stream.cbc = NULL;
88
            if (mode == EVP_CIPH_CBC_MODE)
89
                dat->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
90
            else if (mode == EVP_CIPH_ECB_MODE)
91
                dat->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
92
        } else
93
#endif
94
0
        {
95
0
            dat->block = (block128_f)ossl_sm4_decrypt;
96
0
            ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx));
97
0
        }
98
0
    } else
99
#ifdef HWSM4_CAPABLE
100
        if (HWSM4_CAPABLE) {
101
        HWSM4_set_encrypt_key(key, &dat->ks.ks);
102
        dat->block = (block128_f)HWSM4_encrypt;
103
        dat->stream.cbc = NULL;
104
#ifdef HWSM4_cbc_encrypt
105
        if (mode == EVP_CIPH_CBC_MODE)
106
            dat->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
107
        else
108
#endif
109
#ifdef HWSM4_ecb_encrypt
110
            if (mode == EVP_CIPH_ECB_MODE)
111
            dat->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
112
        else
113
#endif
114
#ifdef HWSM4_ctr32_encrypt_blocks
115
            if (mode == EVP_CIPH_CTR_MODE)
116
            dat->stream.ctr = (ctr128_f)HWSM4_ctr32_encrypt_blocks;
117
        else
118
#endif
119
            (void)0; /* terminate potentially open 'else' */
120
    } else
121
#endif
122
#ifdef VPSM4_CAPABLE
123
        if (VPSM4_CAPABLE) {
124
        vpsm4_set_encrypt_key(key, &dat->ks.ks);
125
        dat->block = (block128_f)vpsm4_encrypt;
126
        dat->stream.cbc = NULL;
127
        if (mode == EVP_CIPH_CBC_MODE)
128
            dat->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
129
        else if (mode == EVP_CIPH_ECB_MODE)
130
            dat->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
131
        else if (mode == EVP_CIPH_CTR_MODE)
132
            dat->stream.ctr = (ctr128_f)vpsm4_ctr32_encrypt_blocks;
133
    } else
134
#endif
135
0
    {
136
0
        dat->block = (block128_f)ossl_sm4_encrypt;
137
0
        ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx));
138
0
    }
139
0
    return 1;
140
0
}
141
142
static int sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
143
    const unsigned char *in, size_t len)
144
0
{
145
0
    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
146
147
0
    if (dat->stream.cbc)
148
0
        (*dat->stream.cbc)(in, out, len, &dat->ks.ks, ctx->iv,
149
0
            EVP_CIPHER_CTX_is_encrypting(ctx));
150
0
    else if (EVP_CIPHER_CTX_is_encrypting(ctx))
151
0
        CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv,
152
0
            dat->block);
153
0
    else
154
0
        CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
155
0
            ctx->iv, dat->block);
156
0
    return 1;
157
0
}
158
159
static int sm4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
160
    const unsigned char *in, size_t len)
161
0
{
162
0
    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
163
0
    int num = EVP_CIPHER_CTX_get_num(ctx);
164
165
0
    CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
166
0
        ctx->iv, &num,
167
0
        EVP_CIPHER_CTX_is_encrypting(ctx), dat->block);
168
0
    EVP_CIPHER_CTX_set_num(ctx, num);
169
0
    return 1;
170
0
}
171
172
static int sm4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
173
    const unsigned char *in, size_t len)
174
0
{
175
0
    size_t bl = EVP_CIPHER_CTX_get_block_size(ctx);
176
0
    size_t i;
177
0
    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
178
179
0
    if (len < bl)
180
0
        return 1;
181
182
0
    if (dat->stream.ecb != NULL)
183
0
        (*dat->stream.ecb)(in, out, len, &dat->ks.ks,
184
0
            EVP_CIPHER_CTX_is_encrypting(ctx));
185
0
    else
186
0
        for (i = 0, len -= bl; i <= len; i += bl)
187
0
            (*dat->block)(in + i, out + i, &dat->ks);
188
189
0
    return 1;
190
0
}
191
192
static int sm4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
193
    const unsigned char *in, size_t len)
194
0
{
195
0
    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
196
0
    int num = EVP_CIPHER_CTX_get_num(ctx);
197
198
0
    CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
199
0
        ctx->iv, &num, dat->block);
200
0
    EVP_CIPHER_CTX_set_num(ctx, num);
201
0
    return 1;
202
0
}
203
204
static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
205
    const unsigned char *in, size_t len)
206
0
{
207
0
    int n = EVP_CIPHER_CTX_get_num(ctx);
208
0
    unsigned int num;
209
0
    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
210
211
0
    if (n < 0)
212
0
        return 0;
213
0
    num = (unsigned int)n;
214
215
0
    if (dat->stream.ctr)
216
0
        CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
217
0
            ctx->iv,
218
0
            EVP_CIPHER_CTX_buf_noconst(ctx),
219
0
            &num, dat->stream.ctr);
220
0
    else
221
0
        CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
222
0
            ctx->iv,
223
0
            EVP_CIPHER_CTX_buf_noconst(ctx), &num,
224
0
            dat->block);
225
0
    EVP_CIPHER_CTX_set_num(ctx, num);
226
0
    return 1;
227
0
}
228
229
DEFINE_BLOCK_CIPHERS(NID_sm4, 0)
230
#endif