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