/src/openssl/providers/implementations/ciphers/cipher_des_hw.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-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 | | * DES low level APIs are deprecated for public use, but still ok for internal |
12 | | * use. |
13 | | */ |
14 | | #include "internal/deprecated.h" |
15 | | |
16 | | #include "prov/ciphercommon.h" |
17 | | #include "cipher_des.h" |
18 | | |
19 | | static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx, |
20 | | const unsigned char *key, size_t keylen) |
21 | 0 | { |
22 | 0 | PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx; |
23 | 0 | DES_cblock *deskey = (DES_cblock *)key; |
24 | 0 | DES_key_schedule *ks = &dctx->dks.ks; |
25 | |
|
26 | 0 | dctx->dstream.cbc = NULL; |
27 | | #if defined(SPARC_DES_CAPABLE) |
28 | | if (SPARC_DES_CAPABLE) { |
29 | | if (ctx->mode == EVP_CIPH_CBC_MODE) { |
30 | | des_t4_key_expand(&deskey[0], ks); |
31 | | dctx->dstream.cbc = ctx->enc ? des_t4_cbc_encrypt : |
32 | | des_t4_cbc_decrypt; |
33 | | return 1; |
34 | | } |
35 | | } |
36 | | #endif |
37 | 0 | DES_set_key_unchecked(deskey, ks); |
38 | 0 | return 1; |
39 | 0 | } |
40 | | |
41 | | static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst, |
42 | | const PROV_CIPHER_CTX *src) |
43 | 0 | { |
44 | 0 | PROV_DES_CTX *sctx = (PROV_DES_CTX *)src; |
45 | 0 | PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst; |
46 | |
|
47 | 0 | *dctx = *sctx; |
48 | 0 | dst->ks = &dctx->dks.ks; |
49 | 0 | } |
50 | | |
51 | | static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, |
52 | | const unsigned char *in, size_t len) |
53 | 0 | { |
54 | 0 | size_t i, bl = ctx->blocksize; |
55 | 0 | DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); |
56 | |
|
57 | 0 | if (len < bl) |
58 | 0 | return 1; |
59 | 0 | for (i = 0, len -= bl; i <= len; i += bl) |
60 | 0 | DES_ecb_encrypt((const_DES_cblock *)(in + i), |
61 | 0 | (const_DES_cblock *)(out + i), key, ctx->enc); |
62 | 0 | return 1; |
63 | 0 | } |
64 | | |
65 | | static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, |
66 | | const unsigned char *in, size_t len) |
67 | 0 | { |
68 | 0 | PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx; |
69 | 0 | DES_key_schedule *key = &(dctx->dks.ks); |
70 | |
|
71 | 0 | if (dctx->dstream.cbc != NULL) { |
72 | 0 | (*dctx->dstream.cbc) (in, out, len, key, ctx->iv); |
73 | 0 | return 1; |
74 | 0 | } |
75 | | |
76 | 0 | while (len >= MAXCHUNK) { |
77 | 0 | DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, |
78 | 0 | ctx->enc); |
79 | 0 | len -= MAXCHUNK; |
80 | 0 | in += MAXCHUNK; |
81 | 0 | out += MAXCHUNK; |
82 | 0 | } |
83 | 0 | if (len > 0) |
84 | 0 | DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, |
85 | 0 | ctx->enc); |
86 | 0 | return 1; |
87 | 0 | } |
88 | | |
89 | | static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, |
90 | | const unsigned char *in, size_t len) |
91 | 0 | { |
92 | 0 | int num = ctx->num; |
93 | 0 | DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); |
94 | |
|
95 | 0 | while (len >= MAXCHUNK) { |
96 | 0 | DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num); |
97 | 0 | len -= MAXCHUNK; |
98 | 0 | in += MAXCHUNK; |
99 | 0 | out += MAXCHUNK; |
100 | 0 | } |
101 | 0 | if (len > 0) { |
102 | 0 | DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num); |
103 | 0 | } |
104 | 0 | ctx->num = num; |
105 | 0 | return 1; |
106 | 0 | } |
107 | | |
108 | | static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, |
109 | | const unsigned char *in, size_t len) |
110 | 0 | { |
111 | 0 | size_t chunk = MAXCHUNK; |
112 | 0 | DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); |
113 | 0 | int num = ctx->num; |
114 | |
|
115 | 0 | if (len < chunk) |
116 | 0 | chunk = len; |
117 | 0 | while (len > 0 && len >= chunk) { |
118 | 0 | DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv, |
119 | 0 | &num, ctx->enc); |
120 | 0 | len -= chunk; |
121 | 0 | in += chunk; |
122 | 0 | out += chunk; |
123 | 0 | if (len < chunk) |
124 | 0 | chunk = len; |
125 | 0 | } |
126 | 0 | ctx->num = num; |
127 | 0 | return 1; |
128 | 0 | } |
129 | | |
130 | | /* |
131 | | * Although we have a CFB-r implementation for DES, it doesn't pack the right |
132 | | * way, so wrap it here |
133 | | */ |
134 | | static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, |
135 | | const unsigned char *in, size_t inl) |
136 | 0 | { |
137 | 0 | size_t n, chunk = MAXCHUNK / 8; |
138 | 0 | DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); |
139 | 0 | unsigned char c[1]; |
140 | 0 | unsigned char d[1] = { 0 }; |
141 | |
|
142 | 0 | if (inl < chunk) |
143 | 0 | chunk = inl; |
144 | |
|
145 | 0 | while (inl && inl >= chunk) { |
146 | 0 | for (n = 0; n < chunk * 8; ++n) { |
147 | 0 | c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; |
148 | 0 | DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc); |
149 | 0 | out[n / 8] = |
150 | 0 | (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | |
151 | 0 | ((d[0] & 0x80) >> (unsigned int)(n % 8)); |
152 | 0 | } |
153 | 0 | inl -= chunk; |
154 | 0 | in += chunk; |
155 | 0 | out += chunk; |
156 | 0 | if (inl < chunk) |
157 | 0 | chunk = inl; |
158 | 0 | } |
159 | |
|
160 | 0 | return 1; |
161 | 0 | } |
162 | | |
163 | | static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, |
164 | | const unsigned char *in, size_t inl) |
165 | 0 | { |
166 | 0 | DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); |
167 | |
|
168 | 0 | while (inl >= MAXCHUNK) { |
169 | 0 | DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key, |
170 | 0 | (DES_cblock *)ctx->iv, ctx->enc); |
171 | 0 | inl -= MAXCHUNK; |
172 | 0 | in += MAXCHUNK; |
173 | 0 | out += MAXCHUNK; |
174 | 0 | } |
175 | 0 | if (inl > 0) |
176 | 0 | DES_cfb_encrypt(in, out, 8, (long)inl, key, |
177 | 0 | (DES_cblock *)ctx->iv, ctx->enc); |
178 | 0 | return 1; |
179 | 0 | } |
180 | | |
181 | | #define PROV_CIPHER_HW_des_mode(mode) \ |
182 | | static const PROV_CIPHER_HW des_##mode = { \ |
183 | | cipher_hw_des_initkey, \ |
184 | | cipher_hw_des_##mode##_cipher, \ |
185 | | cipher_hw_des_copyctx \ |
186 | | }; \ |
187 | 0 | const PROV_CIPHER_HW *ossl_prov_cipher_hw_des_##mode(void) \ |
188 | 0 | { \ |
189 | 0 | return &des_##mode; \ |
190 | 0 | } Unexecuted instantiation: ossl_prov_cipher_hw_des_ecb Unexecuted instantiation: ossl_prov_cipher_hw_des_cbc Unexecuted instantiation: ossl_prov_cipher_hw_des_ofb64 Unexecuted instantiation: ossl_prov_cipher_hw_des_cfb64 Unexecuted instantiation: ossl_prov_cipher_hw_des_cfb1 Unexecuted instantiation: ossl_prov_cipher_hw_des_cfb8 |
191 | | |
192 | | PROV_CIPHER_HW_des_mode(ecb) |
193 | | PROV_CIPHER_HW_des_mode(cbc) |
194 | | PROV_CIPHER_HW_des_mode(ofb64) |
195 | | PROV_CIPHER_HW_des_mode(cfb64) |
196 | | PROV_CIPHER_HW_des_mode(cfb1) |
197 | | PROV_CIPHER_HW_des_mode(cfb8) |