e9a7c31f98908251b1c95f9fff7d086d1717a56b
[openssl.git] / providers / implementations / ciphers / cipher_aes_hw.c
1 /*
2  * Copyright 2001-2019 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_aes.h"
11 #include "prov/providercommonerr.h"
12
13 static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat,
14                                  const unsigned char *key, size_t keylen)
15 {
16     int ret;
17     PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
18     AES_KEY *ks = &adat->ks.ks;
19
20     dat->ks = ks;
21
22     if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
23         && !dat->enc) {
24 #ifdef HWAES_CAPABLE
25         if (HWAES_CAPABLE) {
26             ret = HWAES_set_decrypt_key(key, keylen * 8, ks);
27             dat->block = (block128_f)HWAES_decrypt;
28             dat->stream.cbc = NULL;
29 # ifdef HWAES_cbc_encrypt
30             if (dat->mode == EVP_CIPH_CBC_MODE)
31                 dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
32 # endif
33 # ifdef HWAES_ecb_encrypt
34             if (dat->mode == EVP_CIPH_ECB_MODE)
35                 dat->stream.ecb = (ecb128_f)HWAES_ecb_encrypt;
36 # endif
37         } else
38 #endif
39 #ifdef BSAES_CAPABLE
40         if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CBC_MODE) {
41             ret = AES_set_decrypt_key(key, keylen * 8, ks);
42             dat->block = (block128_f)AES_decrypt;
43             dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
44         } else
45 #endif
46 #ifdef VPAES_CAPABLE
47         if (VPAES_CAPABLE) {
48             ret = vpaes_set_decrypt_key(key, keylen * 8, ks);
49             dat->block = (block128_f)vpaes_decrypt;
50             dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
51                               ?(cbc128_f)vpaes_cbc_encrypt : NULL;
52         } else
53 #endif
54         {
55             ret = AES_set_decrypt_key(key, keylen * 8, ks);
56             dat->block = (block128_f)AES_decrypt;
57             dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
58                               ? (cbc128_f)AES_cbc_encrypt : NULL;
59         }
60     } else
61 #ifdef HWAES_CAPABLE
62     if (HWAES_CAPABLE) {
63         ret = HWAES_set_encrypt_key(key, keylen * 8, ks);
64         dat->block = (block128_f)HWAES_encrypt;
65         dat->stream.cbc = NULL;
66 # ifdef HWAES_cbc_encrypt
67         if (dat->mode == EVP_CIPH_CBC_MODE)
68             dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
69         else
70 # endif
71 # ifdef HWAES_ecb_encrypt
72         if (dat->mode == EVP_CIPH_ECB_MODE)
73             dat->stream.ecb = (ecb128_f)HWAES_ecb_encrypt;
74         else
75 # endif
76 # ifdef HWAES_ctr32_encrypt_blocks
77         if (dat->mode == EVP_CIPH_CTR_MODE)
78             dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
79         else
80 # endif
81             (void)0;            /* terminate potentially open 'else' */
82     } else
83 #endif
84 #ifdef BSAES_CAPABLE
85     if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CTR_MODE) {
86         ret = AES_set_encrypt_key(key, keylen * 8, ks);
87         dat->block = (block128_f)AES_encrypt;
88         dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
89     } else
90 #endif
91 #ifdef VPAES_CAPABLE
92     if (VPAES_CAPABLE) {
93         ret = vpaes_set_encrypt_key(key, keylen * 8, ks);
94         dat->block = (block128_f)vpaes_encrypt;
95         dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
96                           ? (cbc128_f)vpaes_cbc_encrypt : NULL;
97     } else
98 #endif
99     {
100         ret = AES_set_encrypt_key(key, keylen * 8, ks);
101         dat->block = (block128_f)AES_encrypt;
102         dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
103                           ? (cbc128_f)AES_cbc_encrypt : NULL;
104 #ifdef AES_CTR_ASM
105         if (dat->mode == EVP_CIPH_CTR_MODE)
106             dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
107 #endif
108     }
109
110     if (ret < 0) {
111         ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED);
112         return 0;
113     }
114
115     return 1;
116 }
117
118 IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_aes_copyctx, PROV_AES_CTX)
119
120 #define PROV_CIPHER_HW_aes_mode(mode)                                          \
121 static const PROV_CIPHER_HW aes_##mode = {                                     \
122     cipher_hw_aes_initkey,                                                     \
123     cipher_hw_generic_##mode,                                                  \
124     cipher_hw_aes_copyctx                                                      \
125 };                                                                             \
126 PROV_CIPHER_HW_declare(mode)                                                   \
127 const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_##mode(size_t keybits)                \
128 {                                                                              \
129     PROV_CIPHER_HW_select(mode)                                                \
130     return &aes_##mode;                                                        \
131 }
132
133 #if defined(AESNI_CAPABLE)
134 # include "cipher_aes_hw_aesni.inc"
135 #elif defined(SPARC_AES_CAPABLE)
136 # include "cipher_aes_hw_t4.inc"
137 #elif defined(S390X_aes_128_CAPABLE)
138 # include "cipher_aes_hw_s390x.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_aes_mode(cbc)
146 PROV_CIPHER_HW_aes_mode(ecb)
147 PROV_CIPHER_HW_aes_mode(ofb128)
148 PROV_CIPHER_HW_aes_mode(cfb128)
149 PROV_CIPHER_HW_aes_mode(cfb1)
150 PROV_CIPHER_HW_aes_mode(cfb8)
151 PROV_CIPHER_HW_aes_mode(ctr)