1 /*
2  * Copyright 2019-2022 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_CAPABLE
46         if (VPSM4_CAPABLE) {
47             vpsm4_set_encrypt_key(key, ks);
48             ctx->block = (block128_f)vpsm4_encrypt;
49             ctx->stream.cbc = NULL;
50             if (ctx->mode == EVP_CIPH_CBC_MODE)
51                 ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
52             else if (ctx->mode == EVP_CIPH_ECB_MODE)
53                 ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
54             else if (ctx->mode == EVP_CIPH_CTR_MODE)
55                 ctx->stream.ctr = (ctr128_f)vpsm4_ctr32_encrypt_blocks;
56         } else
57 #endif
58         {
59             ossl_sm4_set_key(key, ks);
60             ctx->block = (block128_f)ossl_sm4_encrypt;
61         }
62     } else {
63 #ifdef HWSM4_CAPABLE
64         if (HWSM4_CAPABLE) {
65             HWSM4_set_decrypt_key(key, ks);
66             ctx->block = (block128_f)HWSM4_decrypt;
67             ctx->stream.cbc = NULL;
68 #ifdef HWSM4_cbc_encrypt
69             if (ctx->mode == EVP_CIPH_CBC_MODE)
70                 ctx->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
71 #endif
72 #ifdef HWSM4_ecb_encrypt
73             if (ctx->mode == EVP_CIPH_ECB_MODE)
74                 ctx->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
75 #endif
76         } else
77 #endif
78 #ifdef VPSM4_CAPABLE
79         if (VPSM4_CAPABLE) {
80             vpsm4_set_decrypt_key(key, ks);
81             ctx->block = (block128_f)vpsm4_decrypt;
82             ctx->stream.cbc = NULL;
83             if (ctx->mode == EVP_CIPH_CBC_MODE)
84                 ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
85         else if (ctx->mode == EVP_CIPH_ECB_MODE)
86                 ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
87         } else
88 #endif
89         {
90             ossl_sm4_set_key(key, ks);
91             ctx->block = (block128_f)ossl_sm4_decrypt;
92         }
93     }
94 
95     return 1;
96 }
97 
98 IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_sm4_copyctx, PROV_SM4_CTX)
99 
100 # define PROV_CIPHER_HW_sm4_mode(mode)                                         \
101 static const PROV_CIPHER_HW sm4_##mode = {                                     \
102     cipher_hw_sm4_initkey,                                                     \
103     ossl_cipher_hw_generic_##mode,                                             \
104     cipher_hw_sm4_copyctx                                                      \
105 };                                                                             \
106 const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_##mode(size_t keybits)           \
107 {                                                                              \
108     return &sm4_##mode;                                                        \
109 }
110 
111 PROV_CIPHER_HW_sm4_mode(cbc)
112 PROV_CIPHER_HW_sm4_mode(ecb)
113 PROV_CIPHER_HW_sm4_mode(ofb128)
114 PROV_CIPHER_HW_sm4_mode(cfb128)
115 PROV_CIPHER_HW_sm4_mode(ctr)
116