xref: /netbsd-src/crypto/external/bsd/openssl/dist/providers/implementations/ciphers/ciphercommon_hw.c (revision b0d1725196a7921d003d2c66a14f186abda4176b)
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