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