]>
Commit | Line | Data |
---|---|---|
e1178600 | 1 | /* |
eec0ad10 | 2 | * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. |
e1178600 SL |
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 | /* | |
11 | * IBM S390X support for AES modes ecb, cbc, ofb, cfb, ctr. | |
12 | * This file is included by cipher_aes_hw.c | |
13 | */ | |
14 | ||
15 | #include "s390x_arch.h" | |
16 | ||
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 | |
592dcfd3 P |
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 | |
e1178600 | 23 | |
2f9789f7 SL |
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 | |
30 | ||
e1178600 SL |
31 | static int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat, |
32 | const unsigned char *key, size_t keylen) | |
33 | { | |
34 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
35 | ||
36 | adat->plat.s390x.fc = S390X_AES_FC(keylen); | |
37 | if (!dat->enc) | |
38 | adat->plat.s390x.fc |= S390X_DECRYPT; | |
39 | ||
40 | memcpy(adat->plat.s390x.param.km.k, key, keylen); | |
41 | return 1; | |
42 | } | |
43 | ||
44 | static int s390x_aes_ecb_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, | |
45 | const unsigned char *in, size_t len) | |
46 | { | |
47 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
48 | ||
49 | s390x_km(in, len, out, adat->plat.s390x.fc, &adat->plat.s390x.param.km); | |
50 | return 1; | |
51 | } | |
52 | ||
2f9789f7 SL |
53 | static int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat, |
54 | const unsigned char *key, size_t keylen) | |
e1178600 SL |
55 | { |
56 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
57 | ||
e1178600 SL |
58 | memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); |
59 | adat->plat.s390x.fc = S390X_AES_FC(keylen); | |
60 | adat->plat.s390x.res = 0; | |
61 | return 1; | |
62 | } | |
63 | ||
2f9789f7 SL |
64 | static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, |
65 | const unsigned char *in, size_t len) | |
e1178600 SL |
66 | { |
67 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
68 | int n = adat->plat.s390x.res; | |
69 | int rem; | |
70 | ||
732a4d15 | 71 | memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); |
e1178600 SL |
72 | while (n && len) { |
73 | *out = *in ^ adat->plat.s390x.param.kmo_kmf.cv[n]; | |
74 | n = (n + 1) & 0xf; | |
75 | --len; | |
76 | ++in; | |
77 | ++out; | |
78 | } | |
79 | ||
80 | rem = len & 0xf; | |
81 | ||
82 | len &= ~(size_t)0xf; | |
83 | if (len) { | |
84 | s390x_kmo(in, len, out, adat->plat.s390x.fc, | |
85 | &adat->plat.s390x.param.kmo_kmf); | |
86 | ||
87 | out += len; | |
88 | in += len; | |
89 | } | |
90 | ||
91 | if (rem) { | |
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); | |
95 | ||
96 | while (rem--) { | |
97 | out[n] = in[n] ^ adat->plat.s390x.param.kmo_kmf.cv[n]; | |
98 | ++n; | |
99 | } | |
100 | } | |
101 | ||
52015015 | 102 | memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); |
e1178600 SL |
103 | adat->plat.s390x.res = n; |
104 | return 1; | |
105 | } | |
106 | ||
2f9789f7 SL |
107 | static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat, |
108 | const unsigned char *key, size_t keylen) | |
e1178600 SL |
109 | { |
110 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
111 | ||
112 | adat->plat.s390x.fc = S390X_AES_FC(keylen); | |
113 | adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */ | |
114 | if (!dat->enc) | |
115 | adat->plat.s390x.fc |= S390X_DECRYPT; | |
116 | ||
117 | adat->plat.s390x.res = 0; | |
e1178600 SL |
118 | memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); |
119 | return 1; | |
120 | } | |
121 | ||
2f9789f7 SL |
122 | static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, |
123 | const unsigned char *in, size_t len) | |
e1178600 SL |
124 | { |
125 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
126 | int n = adat->plat.s390x.res; | |
127 | int rem; | |
128 | unsigned char tmp; | |
129 | ||
732a4d15 | 130 | memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); |
e1178600 SL |
131 | while (n && len) { |
132 | tmp = *in; | |
133 | *out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp; | |
134 | adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp; | |
135 | n = (n + 1) & 0xf; | |
136 | --len; | |
137 | ++in; | |
138 | ++out; | |
139 | } | |
140 | ||
141 | rem = len & 0xf; | |
142 | ||
143 | len &= ~(size_t)0xf; | |
144 | if (len) { | |
145 | s390x_kmf(in, len, out, adat->plat.s390x.fc, | |
146 | &adat->plat.s390x.param.kmo_kmf); | |
147 | ||
148 | out += len; | |
149 | in += len; | |
150 | } | |
151 | ||
152 | if (rem) { | |
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); | |
156 | ||
157 | while (rem--) { | |
158 | tmp = in[n]; | |
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; | |
161 | ++n; | |
162 | } | |
163 | } | |
164 | ||
52015015 | 165 | memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); |
e1178600 SL |
166 | adat->plat.s390x.res = n; |
167 | return 1; | |
168 | } | |
169 | ||
170 | static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat, | |
171 | const unsigned char *key, size_t keylen) | |
172 | { | |
173 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
174 | ||
175 | adat->plat.s390x.fc = S390X_AES_FC(keylen); | |
176 | adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */ | |
177 | if (!dat->enc) | |
178 | adat->plat.s390x.fc |= S390X_DECRYPT; | |
179 | ||
e1178600 SL |
180 | memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen); |
181 | return 1; | |
182 | } | |
183 | ||
184 | static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, | |
185 | const unsigned char *in, size_t len) | |
186 | { | |
187 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; | |
188 | ||
732a4d15 | 189 | memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen); |
e1178600 SL |
190 | s390x_kmf(in, len, out, adat->plat.s390x.fc, |
191 | &adat->plat.s390x.param.kmo_kmf); | |
52015015 | 192 | memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); |
e1178600 SL |
193 | return 1; |
194 | } | |
195 | ||
196 | #define PROV_CIPHER_HW_declare(mode) \ | |
197 | static const PROV_CIPHER_HW s390x_aes_##mode = { \ | |
198 | s390x_aes_##mode##_initkey, \ | |
dbca0364 | 199 | s390x_aes_##mode##_cipher_hw, \ |
f75abcc0 | 200 | cipher_hw_aes_copyctx \ |
e1178600 SL |
201 | }; |
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; | |
207 |