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 <stdio.h> 17#include "internal/cryptlib.h" 18#ifndef OPENSSL_NO_DES 19# include <openssl/evp.h> 20# include <openssl/objects.h> 21# include "crypto/evp.h" 22# include <openssl/des.h> 23# include <openssl/rand.h> 24# include "evp_local.h" 25 26typedef struct { 27 union { 28 OSSL_UNION_ALIGN; 29 DES_key_schedule ks; 30 } ks; 31 union { 32 void (*cbc) (const void *, void *, size_t, 33 const DES_key_schedule *, unsigned char *); 34 } stream; 35} EVP_DES_KEY; 36 37# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) 38/* ----------^^^ this is not a typo, just a way to detect that 39 * assembler support was in general requested... */ 40# include "crypto/sparc_arch.h" 41 42# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) 43 44void des_t4_key_expand(const void *key, DES_key_schedule *ks); 45void des_t4_cbc_encrypt(const void *inp, void *out, size_t len, 46 const DES_key_schedule *ks, unsigned char iv[8]); 47void des_t4_cbc_decrypt(const void *inp, void *out, size_t len, 48 const DES_key_schedule *ks, unsigned char iv[8]); 49# endif 50 51static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 52 const unsigned char *iv, int enc); 53static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 54 55/* 56 * Because of various casts and different names can't use 57 * IMPLEMENT_BLOCK_CIPHER 58 */ 59 60static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 61 const unsigned char *in, size_t inl) 62{ 63 BLOCK_CIPHER_ecb_loop() 64 DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), 65 EVP_CIPHER_CTX_get_cipher_data(ctx), 66 EVP_CIPHER_CTX_is_encrypting(ctx)); 67 return 1; 68} 69 70static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 71 const unsigned char *in, size_t inl) 72{ 73 while (inl >= EVP_MAXCHUNK) { 74 int num = EVP_CIPHER_CTX_get_num(ctx); 75 DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, 76 EVP_CIPHER_CTX_get_cipher_data(ctx), 77 (DES_cblock *)ctx->iv, &num); 78 EVP_CIPHER_CTX_set_num(ctx, num); 79 inl -= EVP_MAXCHUNK; 80 in += EVP_MAXCHUNK; 81 out += EVP_MAXCHUNK; 82 } 83 if (inl) { 84 int num = EVP_CIPHER_CTX_get_num(ctx); 85 DES_ofb64_encrypt(in, out, (long)inl, 86 EVP_CIPHER_CTX_get_cipher_data(ctx), 87 (DES_cblock *)ctx->iv, &num); 88 EVP_CIPHER_CTX_set_num(ctx, num); 89 } 90 return 1; 91} 92 93static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 94 const unsigned char *in, size_t inl) 95{ 96 EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx); 97 98 if (dat->stream.cbc != NULL) { 99 (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv); 100 return 1; 101 } 102 while (inl >= EVP_MAXCHUNK) { 103 DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, 104 EVP_CIPHER_CTX_get_cipher_data(ctx), 105 (DES_cblock *)ctx->iv, 106 EVP_CIPHER_CTX_is_encrypting(ctx)); 107 inl -= EVP_MAXCHUNK; 108 in += EVP_MAXCHUNK; 109 out += EVP_MAXCHUNK; 110 } 111 if (inl) 112 DES_ncbc_encrypt(in, out, (long)inl, 113 EVP_CIPHER_CTX_get_cipher_data(ctx), 114 (DES_cblock *)ctx->iv, 115 EVP_CIPHER_CTX_is_encrypting(ctx)); 116 return 1; 117} 118 119static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 120 const unsigned char *in, size_t inl) 121{ 122 while (inl >= EVP_MAXCHUNK) { 123 int num = EVP_CIPHER_CTX_get_num(ctx); 124 DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 125 EVP_CIPHER_CTX_get_cipher_data(ctx), 126 (DES_cblock *)ctx->iv, &num, 127 EVP_CIPHER_CTX_is_encrypting(ctx)); 128 EVP_CIPHER_CTX_set_num(ctx, num); 129 inl -= EVP_MAXCHUNK; 130 in += EVP_MAXCHUNK; 131 out += EVP_MAXCHUNK; 132 } 133 if (inl) { 134 int num = EVP_CIPHER_CTX_get_num(ctx); 135 DES_cfb64_encrypt(in, out, (long)inl, 136 EVP_CIPHER_CTX_get_cipher_data(ctx), 137 (DES_cblock *)ctx->iv, &num, 138 EVP_CIPHER_CTX_is_encrypting(ctx)); 139 EVP_CIPHER_CTX_set_num(ctx, num); 140 } 141 return 1; 142} 143 144/* 145 * Although we have a CFB-r implementation for DES, it doesn't pack the right 146 * way, so wrap it here 147 */ 148static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 149 const unsigned char *in, size_t inl) 150{ 151 size_t n, chunk = EVP_MAXCHUNK / 8; 152 unsigned char c[1], d[1]; 153 154 if (inl < chunk) 155 chunk = inl; 156 157 while (inl && inl >= chunk) { 158 for (n = 0; n < chunk * 8; ++n) { 159 c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; 160 DES_cfb_encrypt(c, d, 1, 1, EVP_CIPHER_CTX_get_cipher_data(ctx), 161 (DES_cblock *)ctx->iv, 162 EVP_CIPHER_CTX_is_encrypting(ctx)); 163 out[n / 8] = 164 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | 165 ((d[0] & 0x80) >> (unsigned int)(n % 8)); 166 } 167 inl -= chunk; 168 in += chunk; 169 out += chunk; 170 if (inl < chunk) 171 chunk = inl; 172 } 173 174 return 1; 175} 176 177static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 178 const unsigned char *in, size_t inl) 179{ 180 while (inl >= EVP_MAXCHUNK) { 181 DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, 182 EVP_CIPHER_CTX_get_cipher_data(ctx), 183 (DES_cblock *)ctx->iv, 184 EVP_CIPHER_CTX_is_encrypting(ctx)); 185 inl -= EVP_MAXCHUNK; 186 in += EVP_MAXCHUNK; 187 out += EVP_MAXCHUNK; 188 } 189 if (inl) 190 DES_cfb_encrypt(in, out, 8, (long)inl, 191 EVP_CIPHER_CTX_get_cipher_data(ctx), 192 (DES_cblock *)ctx->iv, 193 EVP_CIPHER_CTX_is_encrypting(ctx)); 194 return 1; 195} 196 197BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64, 198 EVP_CIPH_RAND_KEY, des_init_key, NULL, 199 EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 200 201 BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1, 202 EVP_CIPH_RAND_KEY, des_init_key, NULL, 203 EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 204 205 BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8, 206 EVP_CIPH_RAND_KEY, des_init_key, NULL, 207 EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 208 209static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 210 const unsigned char *iv, int enc) 211{ 212 DES_cblock *deskey = (DES_cblock *)key; 213 EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx); 214 215 dat->stream.cbc = NULL; 216# if defined(SPARC_DES_CAPABLE) 217 if (SPARC_DES_CAPABLE) { 218 int mode = EVP_CIPHER_CTX_get_mode(ctx); 219 220 if (mode == EVP_CIPH_CBC_MODE) { 221 des_t4_key_expand(key, &dat->ks.ks); 222 dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt; 223 return 1; 224 } 225 } 226# endif 227 DES_set_key_unchecked(deskey, EVP_CIPHER_CTX_get_cipher_data(ctx)); 228 return 1; 229} 230 231static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 232{ 233 234 switch (type) { 235 case EVP_CTRL_RAND_KEY: 236 if (RAND_priv_bytes(ptr, 8) <= 0) 237 return 0; 238 DES_set_odd_parity((DES_cblock *)ptr); 239 return 1; 240 241 default: 242 return -1; 243 } 244} 245 246#endif 247