.ctags.d is previous, include it in our tarballs
[openssl.git] / providers / implementations / ciphers / cipher_des_hw.c
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];
140     unsigned char d[1] = { 0 };
141
142     if (inl < chunk)
143         chunk = inl;
144
145     while (inl && inl >= chunk) {
146         for (n = 0; n < chunk * 8; ++n) {
147             c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
148             DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc);
149             out[n / 8] =
150                 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
151                 ((d[0] & 0x80) >> (unsigned int)(n % 8));
152         }
153         inl -= chunk;
154         in += chunk;
155         out += chunk;
156         if (inl < chunk)
157             chunk = inl;
158     }
159
160     return 1;
161 }
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 {
166     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
167
168     while (inl >= MAXCHUNK) {
169         DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
170                         (DES_cblock *)ctx->iv, ctx->enc);
171         inl -= MAXCHUNK;
172         in += MAXCHUNK;
173         out += MAXCHUNK;
174     }
175     if (inl > 0)
176         DES_cfb_encrypt(in, out, 8, (long)inl, key,
177                         (DES_cblock *)ctx->iv, ctx->enc);
178     return 1;
179 }
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 const PROV_CIPHER_HW *ossl_prov_cipher_hw_des_##mode(void)                     \
188 {                                                                              \
189     return &des_##mode;                                                        \
190 }
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)