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