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
cipher_hw_des_initkey(PROV_CIPHER_CTX * ctx,const unsigned char * key,size_t keylen)19 static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx,
20 const unsigned char *key, size_t keylen)
21 {
22 PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
23 DES_cblock *deskey = (DES_cblock *)key;
24 DES_key_schedule *ks = &dctx->dks.ks;
25
26 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 DES_set_key_unchecked(deskey, ks);
38 return 1;
39 }
40
cipher_hw_des_copyctx(PROV_CIPHER_CTX * dst,const PROV_CIPHER_CTX * src)41 static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst,
42 const PROV_CIPHER_CTX *src)
43 {
44 PROV_DES_CTX *sctx = (PROV_DES_CTX *)src;
45 PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst;
46
47 *dctx = *sctx;
48 dst->ks = &dctx->dks.ks;
49 }
50
cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)51 static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
52 const unsigned char *in, size_t len)
53 {
54 size_t i, bl = ctx->blocksize;
55 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
56
57 if (len < bl)
58 return 1;
59 for (i = 0, len -= bl; i <= len; i += bl)
60 DES_ecb_encrypt((const_DES_cblock *)(in + i),
61 (const_DES_cblock *)(out + i), key, ctx->enc);
62 return 1;
63 }
64
cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)65 static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
66 const unsigned char *in, size_t len)
67 {
68 PROV_DES_CTX *dctx = (PROV_DES_CTX *)ctx;
69 DES_key_schedule *key = &(dctx->dks.ks);
70
71 if (dctx->dstream.cbc != NULL) {
72 (*dctx->dstream.cbc) (in, out, len, key, ctx->iv);
73 return 1;
74 }
75
76 while (len >= MAXCHUNK) {
77 DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv,
78 ctx->enc);
79 len -= MAXCHUNK;
80 in += MAXCHUNK;
81 out += MAXCHUNK;
82 }
83 if (len > 0)
84 DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv,
85 ctx->enc);
86 return 1;
87 }
88
cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)89 static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
90 const unsigned char *in, size_t len)
91 {
92 int num = ctx->num;
93 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
94
95 while (len >= MAXCHUNK) {
96 DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num);
97 len -= MAXCHUNK;
98 in += MAXCHUNK;
99 out += MAXCHUNK;
100 }
101 if (len > 0) {
102 DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num);
103 }
104 ctx->num = num;
105 return 1;
106 }
107
cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)108 static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
109 const unsigned char *in, size_t len)
110 {
111 size_t chunk = MAXCHUNK;
112 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
113 int num = ctx->num;
114
115 if (len < chunk)
116 chunk = len;
117 while (len > 0 && len >= chunk) {
118 DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv,
119 &num, ctx->enc);
120 len -= chunk;
121 in += chunk;
122 out += chunk;
123 if (len < chunk)
124 chunk = len;
125 }
126 ctx->num = num;
127 return 1;
128 }
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 */
cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)134 static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
135 const unsigned char *in, size_t inl)
136 {
137 size_t n, chunk = MAXCHUNK / 8;
138 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
139 unsigned char c[1], d[1];
140
141 if (inl < chunk)
142 chunk = inl;
143
144 while (inl && inl >= chunk) {
145 for (n = 0; n < chunk * 8; ++n) {
146 c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
147 DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc);
148 out[n / 8] =
149 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
150 ((d[0] & 0x80) >> (unsigned int)(n % 8));
151 }
152 inl -= chunk;
153 in += chunk;
154 out += chunk;
155 if (inl < chunk)
156 chunk = inl;
157 }
158
159 return 1;
160 }
161
cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)162 static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
163 const unsigned char *in, size_t inl)
164 {
165 DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
166
167 while (inl >= MAXCHUNK) {
168 DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
169 (DES_cblock *)ctx->iv, ctx->enc);
170 inl -= MAXCHUNK;
171 in += MAXCHUNK;
172 out += MAXCHUNK;
173 }
174 if (inl > 0)
175 DES_cfb_encrypt(in, out, 8, (long)inl, key,
176 (DES_cblock *)ctx->iv, ctx->enc);
177 return 1;
178 }
179
180 #define PROV_CIPHER_HW_des_mode(mode) \
181 static const PROV_CIPHER_HW des_##mode = { \
182 cipher_hw_des_initkey, \
183 cipher_hw_des_##mode##_cipher, \
184 cipher_hw_des_copyctx \
185 }; \
186 const PROV_CIPHER_HW *ossl_prov_cipher_hw_des_##mode(void) \
187 { \
188 return &des_##mode; \
189 }
190
191 PROV_CIPHER_HW_des_mode(ecb)
192 PROV_CIPHER_HW_des_mode(cbc)
193 PROV_CIPHER_HW_des_mode(ofb64)
194 PROV_CIPHER_HW_des_mode(cfb64)
195 PROV_CIPHER_HW_des_mode(cfb1)
196 PROV_CIPHER_HW_des_mode(cfb8)
197