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 ctx->key_set = 1; 102 } 103 return ossl_cipher_generic_set_ctx_params(ctx, params); 104 } 105 106 static int des_einit(void *vctx, const unsigned char *key, size_t keylen, 107 const unsigned char *iv, size_t ivlen, 108 const OSSL_PARAM params[]) 109 { 110 return des_init(vctx, key, keylen, iv, ivlen, params, 1); 111 } 112 113 static int des_dinit(void *vctx, const unsigned char *key, size_t keylen, 114 const unsigned char *iv, size_t ivlen, 115 const OSSL_PARAM params[]) 116 { 117 return des_init(vctx, key, keylen, iv, ivlen, params, 0); 118 } 119 120 static int des_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) 121 { 122 123 DES_cblock *deskey = ptr; 124 size_t kl = ctx->keylen; 125 126 if (kl == 0 || RAND_priv_bytes_ex(ctx->libctx, ptr, kl, 0) <= 0) 127 return 0; 128 DES_set_odd_parity(deskey); 129 return 1; 130 } 131 132 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(des) 133 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), 134 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(des) 135 136 static int des_get_ctx_params(void *vctx, OSSL_PARAM params[]) 137 { 138 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 139 OSSL_PARAM *p; 140 141 if (!ossl_cipher_generic_get_ctx_params(vctx, params)) 142 return 0; 143 144 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); 145 if (p != NULL && !des_generatekey(ctx, p->data)) { 146 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); 147 return 0; 148 } 149 return 1; 150 } 151 152 #define IMPLEMENT_des_cipher(type, lcmode, UCMODE, flags, \ 153 kbits, blkbits, ivbits, block) \ 154 static OSSL_FUNC_cipher_newctx_fn type##_##lcmode##_newctx; \ 155 static void *des_##lcmode##_newctx(void *provctx) \ 156 { \ 157 return des_newctx(provctx, kbits, blkbits, ivbits, \ 158 EVP_CIPH_##UCMODE##_MODE, flags, \ 159 ossl_prov_cipher_hw_des_##lcmode()); \ 160 } \ 161 static OSSL_FUNC_cipher_get_params_fn des_##lcmode##_get_params; \ 162 static int des_##lcmode##_get_params(OSSL_PARAM params[]) \ 163 { \ 164 return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ 165 flags, kbits, blkbits, ivbits); \ 166 } \ 167 const OSSL_DISPATCH ossl_##des_##lcmode##_functions[] = { \ 168 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))des_einit }, \ 169 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))des_dinit }, \ 170 { OSSL_FUNC_CIPHER_UPDATE, \ 171 (void (*)(void))ossl_cipher_generic_##block##_update }, \ 172 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##block##_final },\ 173 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ 174 { OSSL_FUNC_CIPHER_NEWCTX, \ 175 (void (*)(void))des_##lcmode##_newctx }, \ 176 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))des_dupctx }, \ 177 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))des_freectx }, \ 178 { OSSL_FUNC_CIPHER_GET_PARAMS, \ 179 (void (*)(void))des_##lcmode##_get_params }, \ 180 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ 181 (void (*)(void))ossl_cipher_generic_gettable_params }, \ 182 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))des_get_ctx_params }, \ 183 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ 184 (void (*)(void))des_gettable_ctx_params }, \ 185 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ 186 (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ 187 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ 188 (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ 189 { 0, NULL } \ 190 } 191 192 /* ossl_des_ecb_functions */ 193 IMPLEMENT_des_cipher(des, ecb, ECB, DES_FLAGS, 64, 64, 0, block); 194 /* ossl_des_cbc_functions */ 195 IMPLEMENT_des_cipher(des, cbc, CBC, DES_FLAGS, 64, 64, 64, block); 196 /* ossl_des_ofb64_functions */ 197 IMPLEMENT_des_cipher(des, ofb64, OFB, DES_FLAGS, 64, 8, 64, stream); 198 /* ossl_des_cfb64_functions */ 199 IMPLEMENT_des_cipher(des, cfb64, CFB, DES_FLAGS, 64, 8, 64, stream); 200 /* ossl_des_cfb1_functions */ 201 IMPLEMENT_des_cipher(des, cfb1, CFB, DES_FLAGS, 64, 8, 64, stream); 202 /* ossl_des_cfb8_functions */ 203 IMPLEMENT_des_cipher(des, cfb8, CFB, DES_FLAGS, 64, 8, 64, stream); 204