Deprecate the low level DES functions.
[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 /*
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 int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
42                                     const unsigned char *in, size_t len)
43 {
44     size_t i, bl = ctx->blocksize;
45     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
46
47     if (len < bl)
48         return 1;
49     for (i = 0, len -= bl; i <= len; i += bl)
50         DES_ecb_encrypt((const_DES_cblock *)(in + i),
51                         (const_DES_cblock *)(out + i), key, ctx->enc);
52     return 1;
53 }
54
55 static int cipher_hw_des_cbc_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
56                                     const unsigned char *in, size_t len)
57 {
58     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
59
60     while (len >= MAXCHUNK) {
61         DES_ncbc_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv,
62                          ctx->enc);
63         len -= MAXCHUNK;
64         in += MAXCHUNK;
65         out += MAXCHUNK;
66     }
67     if (len > 0)
68         DES_ncbc_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv,
69                          ctx->enc);
70     return 1;
71 }
72
73 static int cipher_hw_des_ofb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
74                                       const unsigned char *in, size_t len)
75 {
76     int num = ctx->num;
77     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
78
79     while (len >= MAXCHUNK) {
80         DES_ofb64_encrypt(in, out, MAXCHUNK, key, (DES_cblock *)ctx->iv, &num);
81         len -= MAXCHUNK;
82         in += MAXCHUNK;
83         out += MAXCHUNK;
84     }
85     if (len > 0) {
86         DES_ofb64_encrypt(in, out, (long)len, key, (DES_cblock *)ctx->iv, &num);
87     }
88     ctx->num = num;
89     return 1;
90 }
91
92 static int cipher_hw_des_cfb64_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
93                                       const unsigned char *in, size_t len)
94 {
95     size_t chunk = MAXCHUNK;
96     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
97     int num = ctx->num;
98
99     if (len < chunk)
100         chunk = len;
101     while (len > 0 && len >= chunk) {
102         DES_cfb64_encrypt(in, out, (long)chunk, key, (DES_cblock *)ctx->iv,
103                           &num, ctx->enc);
104         len -= chunk;
105         in += chunk;
106         out += chunk;
107         if (len < chunk)
108             chunk = len;
109     }
110     ctx->num = num;
111     return 1;
112 }
113
114 /*
115  * Although we have a CFB-r implementation for DES, it doesn't pack the right
116  * way, so wrap it here
117  */
118 static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
119                                      const unsigned char *in, size_t inl)
120 {
121     size_t n, chunk = MAXCHUNK / 8;
122     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
123     unsigned char c[1], d[1];
124
125     if (inl < chunk)
126         chunk = inl;
127
128     while (inl && inl >= chunk) {
129         for (n = 0; n < chunk * 8; ++n) {
130             c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
131             DES_cfb_encrypt(c, d, 1, 1, key, (DES_cblock *)ctx->iv, ctx->enc);
132             out[n / 8] =
133                 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
134                 ((d[0] & 0x80) >> (unsigned int)(n % 8));
135         }
136         inl -= chunk;
137         in += chunk;
138         out += chunk;
139         if (inl < chunk)
140             chunk = inl;
141     }
142
143     return 1;
144 }
145
146 static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
147                                      const unsigned char *in, size_t inl)
148 {
149     DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
150
151     while (inl >= MAXCHUNK) {
152         DES_cfb_encrypt(in, out, 8, (long)MAXCHUNK, key,
153                         (DES_cblock *)ctx->iv, ctx->enc);
154         inl -= MAXCHUNK;
155         in += MAXCHUNK;
156         out += MAXCHUNK;
157     }
158     if (inl > 0)
159         DES_cfb_encrypt(in, out, 8, (long)inl, key,
160                         (DES_cblock *)ctx->iv, ctx->enc);
161     return 1;
162 }
163
164 #define PROV_CIPHER_HW_des_mode(mode)                                          \
165 static const PROV_CIPHER_HW des_##mode = {                                     \
166     cipher_hw_des_initkey,                                                     \
167     cipher_hw_des_##mode##_cipher                                              \
168 };                                                                             \
169 const PROV_CIPHER_HW *PROV_CIPHER_HW_des_##mode(void)                          \
170 {                                                                              \
171     return &des_##mode;                                                        \
172 }
173
174 PROV_CIPHER_HW_des_mode(ecb)
175 PROV_CIPHER_HW_des_mode(cbc)
176 PROV_CIPHER_HW_des_mode(ofb64)
177 PROV_CIPHER_HW_des_mode(cfb64)
178 PROV_CIPHER_HW_des_mode(cfb1)
179 PROV_CIPHER_HW_des_mode(cfb8)