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 | {
|
---|
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 |
|
---|
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 |
|
---|
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 |
|
---|
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 |
|
---|
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 |
|
---|
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 | */
|
---|
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 |
|
---|
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)
|
---|