1 /*
2 * Copyright 2019-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 #include "prov/ciphercommon.h"
11
12 /*-
13 * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
14 * Used if there is no special hardware implementations.
15 */
ossl_cipher_hw_generic_cbc(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)16 int ossl_cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out,
17 const unsigned char *in, size_t len)
18 {
19 if (dat->stream.cbc)
20 (*dat->stream.cbc)(in, out, len, dat->ks, dat->iv, dat->enc);
21 else if (dat->enc)
22 CRYPTO_cbc128_encrypt(in, out, len, dat->ks, dat->iv, dat->block);
23 else
24 CRYPTO_cbc128_decrypt(in, out, len, dat->ks, dat->iv, dat->block);
25
26 return 1;
27 }
28
ossl_cipher_hw_generic_ecb(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)29 int ossl_cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out,
30 const unsigned char *in, size_t len)
31 {
32 size_t i, bl = dat->blocksize;
33
34 if (len < bl)
35 return 1;
36
37 if (dat->stream.ecb) {
38 (*dat->stream.ecb)(in, out, len, dat->ks, dat->enc);
39 } else {
40 for (i = 0, len -= bl; i <= len; i += bl)
41 (*dat->block)(in + i, out + i, dat->ks);
42 }
43
44 return 1;
45 }
46
ossl_cipher_hw_generic_ofb128(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)47 int ossl_cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out,
48 const unsigned char *in, size_t len)
49 {
50 int num = dat->num;
51
52 CRYPTO_ofb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->block);
53 dat->num = num;
54
55 return 1;
56 }
57
ossl_cipher_hw_generic_cfb128(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)58 int ossl_cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out,
59 const unsigned char *in, size_t len)
60 {
61 int num = dat->num;
62
63 CRYPTO_cfb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
64 dat->block);
65 dat->num = num;
66
67 return 1;
68 }
69
ossl_cipher_hw_generic_cfb8(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)70 int ossl_cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out,
71 const unsigned char *in, size_t len)
72 {
73 int num = dat->num;
74
75 CRYPTO_cfb128_8_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
76 dat->block);
77 dat->num = num;
78
79 return 1;
80 }
81
ossl_cipher_hw_generic_cfb1(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)82 int ossl_cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out,
83 const unsigned char *in, size_t len)
84 {
85 int num = dat->num;
86
87 if (dat->use_bits) {
88 CRYPTO_cfb128_1_encrypt(in, out, len, dat->ks, dat->iv, &num,
89 dat->enc, dat->block);
90 dat->num = num;
91 return 1;
92 }
93
94 while (len >= MAXBITCHUNK) {
95 CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, dat->ks,
96 dat->iv, &num, dat->enc, dat->block);
97 len -= MAXBITCHUNK;
98 out += MAXBITCHUNK;
99 in += MAXBITCHUNK;
100 }
101 if (len)
102 CRYPTO_cfb128_1_encrypt(in, out, len * 8, dat->ks, dat->iv, &num,
103 dat->enc, dat->block);
104
105 dat->num = num;
106
107 return 1;
108 }
109
ossl_cipher_hw_generic_ctr(PROV_CIPHER_CTX * dat,unsigned char * out,const unsigned char * in,size_t len)110 int ossl_cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out,
111 const unsigned char *in, size_t len)
112 {
113 unsigned int num = dat->num;
114
115 if (dat->stream.ctr)
116 CRYPTO_ctr128_encrypt_ctr32(in, out, len, dat->ks, dat->iv, dat->buf,
117 &num, dat->stream.ctr);
118 else
119 CRYPTO_ctr128_encrypt(in, out, len, dat->ks, dat->iv, dat->buf,
120 &num, dat->block);
121 dat->num = num;
122
123 return 1;
124 }
125
126 /*-
127 * The chunked cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
128 * Used if there is no special hardware implementations.
129 */
130
ossl_cipher_hw_chunked_cbc(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)131 int ossl_cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
132 const unsigned char *in, size_t inl)
133 {
134 while (inl >= MAXCHUNK) {
135 ossl_cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK);
136 inl -= MAXCHUNK;
137 in += MAXCHUNK;
138 out += MAXCHUNK;
139 }
140 if (inl > 0)
141 ossl_cipher_hw_generic_cbc(ctx, out, in, inl);
142 return 1;
143 }
144
ossl_cipher_hw_chunked_cfb8(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)145 int ossl_cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out,
146 const unsigned char *in, size_t inl)
147 {
148 size_t chunk = MAXCHUNK;
149
150 if (inl < chunk)
151 chunk = inl;
152 while (inl > 0 && inl >= chunk) {
153 ossl_cipher_hw_generic_cfb8(ctx, out, in, inl);
154 inl -= chunk;
155 in += chunk;
156 out += chunk;
157 if (inl < chunk)
158 chunk = inl;
159 }
160 return 1;
161 }
162
ossl_cipher_hw_chunked_cfb128(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)163 int ossl_cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
164 const unsigned char *in, size_t inl)
165 {
166 size_t chunk = MAXCHUNK;
167
168 if (inl < chunk)
169 chunk = inl;
170 while (inl > 0 && inl >= chunk) {
171 ossl_cipher_hw_generic_cfb128(ctx, out, in, inl);
172 inl -= chunk;
173 in += chunk;
174 out += chunk;
175 if (inl < chunk)
176 chunk = inl;
177 }
178 return 1;
179 }
180
ossl_cipher_hw_chunked_ofb128(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)181 int ossl_cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
182 const unsigned char *in, size_t inl)
183 {
184 while (inl >= MAXCHUNK) {
185 ossl_cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK);
186 inl -= MAXCHUNK;
187 in += MAXCHUNK;
188 out += MAXCHUNK;
189 }
190 if (inl > 0)
191 ossl_cipher_hw_generic_ofb128(ctx, out, in, inl);
192 return 1;
193 }
194