1 /*
2  * Copyright 2019-2024 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 #include "cipher_sm4.h"
11 
cipher_hw_sm4_initkey(PROV_CIPHER_CTX * ctx,const unsigned char * key,size_t keylen)12 static int cipher_hw_sm4_initkey(PROV_CIPHER_CTX *ctx,
13                                  const unsigned char *key, size_t keylen)
14 {
15     PROV_SM4_CTX *sctx =  (PROV_SM4_CTX *)ctx;
16     SM4_KEY *ks = &sctx->ks.ks;
17 
18     ctx->ks = ks;
19     if (ctx->enc
20             || (ctx->mode != EVP_CIPH_ECB_MODE
21                 && ctx->mode != EVP_CIPH_CBC_MODE)) {
22 #ifdef HWSM4_CAPABLE
23         if (HWSM4_CAPABLE) {
24             HWSM4_set_encrypt_key(key, ks);
25             ctx->block = (block128_f)HWSM4_encrypt;
26             ctx->stream.cbc = NULL;
27 #ifdef HWSM4_cbc_encrypt
28             if (ctx->mode == EVP_CIPH_CBC_MODE)
29                 ctx->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
30             else
31 #endif
32 #ifdef HWSM4_ecb_encrypt
33             if (ctx->mode == EVP_CIPH_ECB_MODE)
34                 ctx->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
35             else
36 #endif
37 #ifdef HWSM4_ctr32_encrypt_blocks
38             if (ctx->mode == EVP_CIPH_CTR_MODE)
39                 ctx->stream.ctr = (ctr128_f)HWSM4_ctr32_encrypt_blocks;
40             else
41 #endif
42             (void)0;            /* terminate potentially open 'else' */
43         } else
44 #endif
45 #ifdef VPSM4_EX_CAPABLE
46         if (VPSM4_EX_CAPABLE) {
47             vpsm4_ex_set_encrypt_key(key, ks);
48             ctx->block = (block128_f)vpsm4_ex_encrypt;
49             ctx->stream.cbc = NULL;
50             if (ctx->mode == EVP_CIPH_CBC_MODE)
51                 ctx->stream.cbc = (cbc128_f)vpsm4_ex_cbc_encrypt;
52             else if (ctx->mode == EVP_CIPH_ECB_MODE)
53                 ctx->stream.ecb = (ecb128_f)vpsm4_ex_ecb_encrypt;
54             else if (ctx->mode == EVP_CIPH_CTR_MODE)
55                 ctx->stream.ctr = (ctr128_f)vpsm4_ex_ctr32_encrypt_blocks;
56         } else
57 #endif
58 #ifdef VPSM4_CAPABLE
59         if (VPSM4_CAPABLE) {
60             vpsm4_set_encrypt_key(key, ks);
61             ctx->block = (block128_f)vpsm4_encrypt;
62             ctx->stream.cbc = NULL;
63             if (ctx->mode == EVP_CIPH_CBC_MODE)
64                 ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
65             else if (ctx->mode == EVP_CIPH_ECB_MODE)
66                 ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
67             else if (ctx->mode == EVP_CIPH_CTR_MODE)
68                 ctx->stream.ctr = (ctr128_f)vpsm4_ctr32_encrypt_blocks;
69         } else
70 #endif
71         {
72             ossl_sm4_set_key(key, ks);
73             ctx->block = (block128_f)ossl_sm4_encrypt;
74         }
75     } else {
76 #ifdef HWSM4_CAPABLE
77         if (HWSM4_CAPABLE) {
78             HWSM4_set_decrypt_key(key, ks);
79             ctx->block = (block128_f)HWSM4_decrypt;
80             ctx->stream.cbc = NULL;
81 #ifdef HWSM4_cbc_encrypt
82             if (ctx->mode == EVP_CIPH_CBC_MODE)
83                 ctx->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
84 #endif
85 #ifdef HWSM4_ecb_encrypt
86             if (ctx->mode == EVP_CIPH_ECB_MODE)
87                 ctx->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
88 #endif
89         } else
90 #endif
91 #ifdef VPSM4_EX_CAPABLE
92         if (VPSM4_EX_CAPABLE) {
93             vpsm4_ex_set_decrypt_key(key, ks);
94             ctx->block = (block128_f)vpsm4_ex_decrypt;
95             ctx->stream.cbc = NULL;
96             if (ctx->mode == EVP_CIPH_CBC_MODE)
97                 ctx->stream.cbc = (cbc128_f)vpsm4_ex_cbc_encrypt;
98             else if (ctx->mode == EVP_CIPH_ECB_MODE)
99                 ctx->stream.ecb = (ecb128_f)vpsm4_ex_ecb_encrypt;
100         } else
101 #endif
102 #ifdef VPSM4_CAPABLE
103         if (VPSM4_CAPABLE) {
104             vpsm4_set_decrypt_key(key, ks);
105             ctx->block = (block128_f)vpsm4_decrypt;
106             ctx->stream.cbc = NULL;
107             if (ctx->mode == EVP_CIPH_CBC_MODE)
108                 ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
109             else if (ctx->mode == EVP_CIPH_ECB_MODE)
110                 ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
111         } else
112 #endif
113         {
114             ossl_sm4_set_key(key, ks);
115             ctx->block = (block128_f)ossl_sm4_decrypt;
116         }
117     }
118 
119     return 1;
120 }
121 
122 IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_sm4_copyctx, PROV_SM4_CTX)
123 
124 # define PROV_CIPHER_HW_sm4_mode(mode)                                         \
125 static const PROV_CIPHER_HW sm4_##mode = {                                     \
126     cipher_hw_sm4_initkey,                                                     \
127     ossl_cipher_hw_generic_##mode,                                             \
128     cipher_hw_sm4_copyctx                                                      \
129 };                                                                             \
130 PROV_CIPHER_HW_declare(mode)                                                   \
131 const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_##mode(size_t keybits)           \
132 {                                                                              \
133     PROV_CIPHER_HW_select(mode)                                                \
134     return &sm4_##mode;                                                        \
135 }
136 
137 #if defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64
138 # include "cipher_sm4_hw_rv64i.inc"
139 #else
140 /* The generic case */
141 # define PROV_CIPHER_HW_declare(mode)
142 # define PROV_CIPHER_HW_select(mode)
143 #endif
144 
145 PROV_CIPHER_HW_sm4_mode(cbc)
146 PROV_CIPHER_HW_sm4_mode(ecb)
147 PROV_CIPHER_HW_sm4_mode(ofb128)
148 PROV_CIPHER_HW_sm4_mode(cfb128)
149 PROV_CIPHER_HW_sm4_mode(ctr)
150