]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/implementations/ciphers/cipher_des_hw.c
Providers: move all digests
[thirdparty/openssl.git] / providers / implementations / ciphers / cipher_des_hw.c
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
10 #include "prov/ciphercommon.h"
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)