1 /* 2 * Copyright 2019-2023 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 <openssl/rand.h> 17 #include <openssl/proverr.h> 18 #include "prov/ciphercommon.h" 19 #include "cipher_des.h" 20 #include "prov/implementations.h" 21 #include "prov/providercommon.h" 22 23 #define DES_FLAGS PROV_CIPHER_FLAG_RAND_KEY 24 25 static OSSL_FUNC_cipher_freectx_fn des_freectx; 26 static OSSL_FUNC_cipher_encrypt_init_fn des_einit; 27 static OSSL_FUNC_cipher_decrypt_init_fn des_dinit; 28 static OSSL_FUNC_cipher_get_ctx_params_fn des_get_ctx_params; 29 static OSSL_FUNC_cipher_gettable_ctx_params_fn des_gettable_ctx_params; 30 31 static void *des_newctx(void *provctx, size_t kbits, size_t blkbits, 32 size_t ivbits, unsigned int mode, uint64_t flags, 33 const PROV_CIPHER_HW *hw) 34 { 35 PROV_DES_CTX *ctx; 36 37 if (!ossl_prov_is_running()) 38 return NULL; 39 40 ctx = OPENSSL_zalloc(sizeof(*ctx)); 41 if (ctx != NULL) 42 ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, 43 hw, provctx); 44 return ctx; 45 } 46 47 static void *des_dupctx(void *ctx) 48 { 49 PROV_DES_CTX *in = (PROV_DES_CTX *)ctx; 50 PROV_DES_CTX *ret; 51 52 if (!ossl_prov_is_running()) 53 return NULL; 54 55 ret = OPENSSL_malloc(sizeof(*ret)); 56 if (ret == NULL) 57 return NULL; 58 in->base.hw->copyctx(&ret->base, &in->base); 59 60 return ret; 61 } 62 63 static void des_freectx(void *vctx) 64 { 65 PROV_DES_CTX *ctx = (PROV_DES_CTX *)vctx; 66 67 ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); 68 OPENSSL_clear_free(ctx, sizeof(*ctx)); 69 } 70 71 static int des_init(void *vctx, const unsigned char *key, size_t keylen, 72 const unsigned char *iv, size_t ivlen, 73 const OSSL_PARAM params[], int enc) 74 { 75 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 76 77 if (!ossl_prov_is_running()) 78 return 0; 79 80 ctx->num = 0; 81 ctx->bufsz = 0; 82 ctx->enc = enc; 83 84 if (iv != NULL) { 85 if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) 86 return 0; 87 } else if (ctx->iv_set) { 88 /* reset IV to keep compatibility with 1.1.1 */ 89 memcpy(ctx->iv, ctx->oiv, ctx->ivlen); 90 } 91 92 if (key != NULL) { 93 if (keylen != ctx->keylen) { 94 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 95 return 0; 96 } 97 if (!ctx->hw->init(ctx, key, keylen)) 98 return 0; 99 ctx->key_set = 1; 100 } 101 return ossl_cipher_generic_set_ctx_params(ctx, params); 102 } 103 104 static int des_einit(void *vctx, const unsigned char *key, size_t keylen, 105 const unsigned char *iv, size_t ivlen, 106 const OSSL_PARAM params[]) 107 { 108 return des_init(vctx, key, keylen, iv, ivlen, params, 1); 109 } 110 111 static int des_dinit(void *vctx, const unsigned char *key, size_t keylen, 112 const unsigned char *iv, size_t ivlen, 113 const OSSL_PARAM params[]) 114 { 115 return des_init(vctx, key, keylen, iv, ivlen, params, 0); 116 } 117 118 static int des_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) 119 { 120 121 DES_cblock *deskey = ptr; 122 size_t kl = ctx->keylen; 123 124 if (kl == 0 || RAND_priv_bytes_ex(ctx->libctx, ptr, kl, 0) <= 0) 125 return 0; 126 DES_set_odd_parity(deskey); 127 return 1; 128 } 129 130 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(des) 131 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), 132 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(des) 133 134 static int des_get_ctx_params(void *vctx, OSSL_PARAM params[]) 135 { 136 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 137 OSSL_PARAM *p; 138 139 if (!ossl_cipher_generic_get_ctx_params(vctx, params)) 140 return 0; 141 142 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); 143 if (p != NULL && !des_generatekey(ctx, p->data)) { 144 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); 145 return 0; 146 } 147 return 1; 148 } 149 150 #define IMPLEMENT_des_cipher(type, lcmode, UCMODE, flags, \ 151 kbits, blkbits, ivbits, block) \ 152 static OSSL_FUNC_cipher_newctx_fn type##_##lcmode##_newctx; \ 153 static void *des_##lcmode##_newctx(void *provctx) \ 154 { \ 155 return des_newctx(provctx, kbits, blkbits, ivbits, \ 156 EVP_CIPH_##UCMODE##_MODE, flags, \ 157 ossl_prov_cipher_hw_des_##lcmode()); \ 158 } \ 159 static OSSL_FUNC_cipher_get_params_fn des_##lcmode##_get_params; \ 160 static int des_##lcmode##_get_params(OSSL_PARAM params[]) \ 161 { \ 162 return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ 163 flags, kbits, blkbits, ivbits); \ 164 } \ 165 const OSSL_DISPATCH ossl_##des_##lcmode##_functions[] = { \ 166 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))des_einit }, \ 167 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))des_dinit }, \ 168 { OSSL_FUNC_CIPHER_UPDATE, \ 169 (void (*)(void))ossl_cipher_generic_##block##_update }, \ 170 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##block##_final },\ 171 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ 172 { OSSL_FUNC_CIPHER_NEWCTX, \ 173 (void (*)(void))des_##lcmode##_newctx }, \ 174 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))des_dupctx }, \ 175 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))des_freectx }, \ 176 { OSSL_FUNC_CIPHER_GET_PARAMS, \ 177 (void (*)(void))des_##lcmode##_get_params }, \ 178 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ 179 (void (*)(void))ossl_cipher_generic_gettable_params }, \ 180 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))des_get_ctx_params }, \ 181 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ 182 (void (*)(void))des_gettable_ctx_params }, \ 183 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ 184 (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ 185 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ 186 (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ 187 OSSL_DISPATCH_END \ 188 } 189 190 /* ossl_des_ecb_functions */ 191 IMPLEMENT_des_cipher(des, ecb, ECB, DES_FLAGS, 64, 64, 0, block); 192 /* ossl_des_cbc_functions */ 193 IMPLEMENT_des_cipher(des, cbc, CBC, DES_FLAGS, 64, 64, 64, block); 194 /* ossl_des_ofb64_functions */ 195 IMPLEMENT_des_cipher(des, ofb64, OFB, DES_FLAGS, 64, 8, 64, stream); 196 /* ossl_des_cfb64_functions */ 197 IMPLEMENT_des_cipher(des, cfb64, CFB, DES_FLAGS, 64, 8, 64, stream); 198 /* ossl_des_cfb1_functions */ 199 IMPLEMENT_des_cipher(des, cfb1, CFB, DES_FLAGS, 64, 8, 64, stream); 200 /* ossl_des_cfb8_functions */ 201 IMPLEMENT_des_cipher(des, cfb8, CFB, DES_FLAGS, 64, 8, 64, stream); 202