2 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 * IBM S390X support for AES modes ecb, cbc, ofb, cfb, ctr.
12 * This file is included by cipher_aes_hw.c
15 #include "s390x_arch.h"
17 #define s390x_aes_cbc_initkey cipher_hw_aes_initkey
18 #define s390x_aes_cfb1_initkey cipher_hw_aes_initkey
19 #define s390x_aes_ctr_initkey cipher_hw_aes_initkey
20 #define s390x_aes_cbc_cipher_hw ossl_cipher_hw_generic_cbc
21 #define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1
22 #define s390x_aes_ctr_cipher_hw ossl_cipher_hw_generic_ctr
24 #define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE
25 #define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE
26 #define S390X_aes_256_ofb128_CAPABLE S390X_aes_256_ofb_CAPABLE
27 #define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE
28 #define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE
29 #define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE
31 static int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat,
32 const unsigned char *key, size_t keylen)
34 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
36 adat->plat.s390x.fc = S390X_AES_FC(keylen);
38 adat->plat.s390x.fc |= S390X_DECRYPT;
40 memcpy(adat->plat.s390x.param.km.k, key, keylen);
44 static int s390x_aes_ecb_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
45 const unsigned char *in, size_t len)
47 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
49 s390x_km(in, len, out, adat->plat.s390x.fc, &adat->plat.s390x.param.km);
53 static int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat,
54 const unsigned char *key, size_t keylen)
56 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
58 memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
59 memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
60 adat->plat.s390x.fc = S390X_AES_FC(keylen);
61 adat->plat.s390x.res = 0;
65 static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
66 const unsigned char *in, size_t len)
68 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
69 int n = adat->plat.s390x.res;
73 *out = *in ^ adat->plat.s390x.param.kmo_kmf.cv[n];
84 s390x_kmo(in, len, out, adat->plat.s390x.fc,
85 &adat->plat.s390x.param.kmo_kmf);
92 s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
93 adat->plat.s390x.param.kmo_kmf.cv, adat->plat.s390x.fc,
94 adat->plat.s390x.param.kmo_kmf.k);
97 out[n] = in[n] ^ adat->plat.s390x.param.kmo_kmf.cv[n];
102 memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
103 adat->plat.s390x.res = n;
107 static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat,
108 const unsigned char *key, size_t keylen)
110 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
112 adat->plat.s390x.fc = S390X_AES_FC(keylen);
113 adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */
115 adat->plat.s390x.fc |= S390X_DECRYPT;
117 adat->plat.s390x.res = 0;
118 memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
119 memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
123 static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
124 const unsigned char *in, size_t len)
126 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
127 int n = adat->plat.s390x.res;
133 *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
134 adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp;
145 s390x_kmf(in, len, out, adat->plat.s390x.fc,
146 &adat->plat.s390x.param.kmo_kmf);
153 s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
154 adat->plat.s390x.param.kmo_kmf.cv,
155 S390X_AES_FC(dat->keylen), adat->plat.s390x.param.kmo_kmf.k);
159 out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
160 adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp;
165 memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
166 adat->plat.s390x.res = n;
170 static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat,
171 const unsigned char *key, size_t keylen)
173 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
175 adat->plat.s390x.fc = S390X_AES_FC(keylen);
176 adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */
178 adat->plat.s390x.fc |= S390X_DECRYPT;
180 memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
181 memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
185 static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
186 const unsigned char *in, size_t len)
188 PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
190 s390x_kmf(in, len, out, adat->plat.s390x.fc,
191 &adat->plat.s390x.param.kmo_kmf);
192 memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
196 #define PROV_CIPHER_HW_declare(mode) \
197 static const PROV_CIPHER_HW s390x_aes_##mode = { \
198 s390x_aes_##mode##_initkey, \
199 s390x_aes_##mode##_cipher_hw, \
200 cipher_hw_aes_copyctx \
202 #define PROV_CIPHER_HW_select(mode) \
203 if ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE) \
204 || (keybits == 192 && S390X_aes_192_##mode##_CAPABLE) \
205 || (keybits == 256 && S390X_aes_256_##mode##_CAPABLE)) \
206 return &s390x_aes_##mode;