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
13static 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
118IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_aes_copyctx, PROV_AES_CTX)
119
120#define PROV_CIPHER_HW_aes_mode(mode) \
121static const PROV_CIPHER_HW aes_##mode = { \
122 cipher_hw_aes_initkey, \
123 cipher_hw_generic_##mode, \
124 cipher_hw_aes_copyctx \
125}; \
126PROV_CIPHER_HW_declare(mode) \
127const 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
145PROV_CIPHER_HW_aes_mode(cbc)
146PROV_CIPHER_HW_aes_mode(ecb)
147PROV_CIPHER_HW_aes_mode(ofb128)
148PROV_CIPHER_HW_aes_mode(cfb128)
149PROV_CIPHER_HW_aes_mode(cfb1)
150PROV_CIPHER_HW_aes_mode(cfb8)
151PROV_CIPHER_HW_aes_mode(ctr)
152