prov: add extra params argument to KDF implementations
[openssl.git] / providers / implementations / ciphers / cipher_aes_hw_s390x.inc
1 /*
2  * Copyright 2001-2021 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 /*
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
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
23
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
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
53 static int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat,
54                                     const unsigned char *key, size_t keylen)
55 {
56     PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
57
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
64 static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
65                                       const unsigned char *in, size_t len)
66 {
67     PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
68     int n = adat->plat.s390x.res;
69     int rem;
70
71     memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
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
102     memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
103     adat->plat.s390x.res = n;
104     return 1;
105 }
106
107 static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat,
108                                     const unsigned char *key, size_t keylen)
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;
118     memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
119     return 1;
120 }
121
122 static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
123                                       const unsigned char *in, size_t len)
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
130     memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
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
165     memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen);
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
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
189     memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
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);
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,                                                \
199     s390x_aes_##mode##_cipher_hw,                                              \
200     cipher_hw_aes_copyctx                                                      \
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