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 25static OSSL_FUNC_cipher_freectx_fn des_freectx; 26static OSSL_FUNC_cipher_encrypt_init_fn des_einit; 27static OSSL_FUNC_cipher_decrypt_init_fn des_dinit; 28static OSSL_FUNC_cipher_get_ctx_params_fn des_get_ctx_params; 29static OSSL_FUNC_cipher_gettable_ctx_params_fn des_gettable_ctx_params; 30 31static 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 47static 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 65static 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 73static 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 106static 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 113static 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 120static 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 132CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(des) 133 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), 134CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(des) 135 136static 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) \ 154static OSSL_FUNC_cipher_newctx_fn type##_##lcmode##_newctx; \ 155static 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} \ 161static OSSL_FUNC_cipher_get_params_fn des_##lcmode##_get_params; \ 162static 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} \ 167const 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 */ 193IMPLEMENT_des_cipher(des, ecb, ECB, DES_FLAGS, 64, 64, 0, block); 194/* ossl_des_cbc_functions */ 195IMPLEMENT_des_cipher(des, cbc, CBC, DES_FLAGS, 64, 64, 64, block); 196/* ossl_des_ofb64_functions */ 197IMPLEMENT_des_cipher(des, ofb64, OFB, DES_FLAGS, 64, 8, 64, stream); 198/* ossl_des_cfb64_functions */ 199IMPLEMENT_des_cipher(des, cfb64, CFB, DES_FLAGS, 64, 8, 64, stream); 200/* ossl_des_cfb1_functions */ 201IMPLEMENT_des_cipher(des, cfb1, CFB, DES_FLAGS, 64, 8, 64, stream); 202/* ossl_des_cfb8_functions */ 203IMPLEMENT_des_cipher(des, cfb8, CFB, DES_FLAGS, 64, 8, 64, stream); 204