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