xref: /src/crypto/openssl/providers/implementations/ciphers/ciphercommon_hw.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
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