1 /* 2 * Copyright 2019-2024 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_tdes.h" 20 #include "prov/implementations.h" 21 #include "prov/providercommon.h" 22 23 void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits, 24 size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw) 25 { 26 PROV_TDES_CTX *tctx; 27 28 if (!ossl_prov_is_running()) 29 return NULL; 30 31 tctx = OPENSSL_zalloc(sizeof(*tctx)); 32 if (tctx != NULL) { 33 OSSL_FIPS_IND_INIT(tctx) 34 ossl_cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, 35 hw, provctx); 36 } 37 return tctx; 38 } 39 40 void *ossl_tdes_dupctx(void *ctx) 41 { 42 PROV_TDES_CTX *in = (PROV_TDES_CTX *)ctx; 43 PROV_TDES_CTX *ret; 44 45 if (!ossl_prov_is_running()) 46 return NULL; 47 48 ret = OPENSSL_malloc(sizeof(*ret)); 49 if (ret == NULL) 50 return NULL; 51 OSSL_FIPS_IND_COPY(ret, in) 52 in->base.hw->copyctx(&ret->base, &in->base); 53 54 return ret; 55 } 56 57 void ossl_tdes_freectx(void *vctx) 58 { 59 PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx; 60 61 ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); 62 OPENSSL_clear_free(ctx, sizeof(*ctx)); 63 } 64 65 #ifdef FIPS_MODULE 66 static int tdes_encrypt_check_approved(PROV_TDES_CTX *ctx, int enc) 67 { 68 /* Triple-DES encryption is not approved in FIPS 140-3 */ 69 if (enc && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, 70 ctx->base.libctx, 71 "Triple-DES", "Encryption", 72 ossl_fips_config_tdes_encrypt_disallowed)) 73 return 0; 74 return 1; 75 } 76 #endif 77 78 static int tdes_init(void *vctx, const unsigned char *key, size_t keylen, 79 const unsigned char *iv, size_t ivlen, 80 const OSSL_PARAM params[], int enc) 81 { 82 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 83 84 if (!ossl_prov_is_running()) 85 return 0; 86 87 ctx->num = 0; 88 ctx->bufsz = 0; 89 ctx->enc = enc; 90 91 if (iv != NULL) { 92 if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) 93 return 0; 94 } else if (ctx->iv_set 95 && (ctx->mode == EVP_CIPH_CBC_MODE 96 || ctx->mode == EVP_CIPH_CFB_MODE 97 || ctx->mode == EVP_CIPH_OFB_MODE)) { 98 /* reset IV to keep compatibility with 1.1.1 */ 99 memcpy(ctx->iv, ctx->oiv, ctx->ivlen); 100 } 101 102 if (key != NULL) { 103 if (keylen != ctx->keylen) { 104 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 105 return 0; 106 } 107 if (!ctx->hw->init(ctx, key, ctx->keylen)) 108 return 0; 109 ctx->key_set = 1; 110 } 111 if (!ossl_tdes_set_ctx_params(ctx, params)) 112 return 0; 113 #ifdef FIPS_MODULE 114 if (!tdes_encrypt_check_approved((PROV_TDES_CTX *)ctx, enc)) 115 return 0; 116 #endif 117 return 1; 118 } 119 120 int ossl_tdes_einit(void *vctx, const unsigned char *key, size_t keylen, 121 const unsigned char *iv, size_t ivlen, 122 const OSSL_PARAM params[]) 123 { 124 return tdes_init(vctx, key, keylen, iv, ivlen, params, 1); 125 } 126 127 int ossl_tdes_dinit(void *vctx, const unsigned char *key, size_t keylen, 128 const unsigned char *iv, size_t ivlen, 129 const OSSL_PARAM params[]) 130 { 131 return tdes_init(vctx, key, keylen, iv, ivlen, params, 0); 132 } 133 134 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_tdes) 135 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), 136 OSSL_FIPS_IND_GETTABLE_CTX_PARAM() 137 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_tdes) 138 139 static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) 140 { 141 DES_cblock *deskey = ptr; 142 size_t kl = ctx->keylen; 143 144 if (kl == 0 || RAND_priv_bytes_ex(ctx->libctx, ptr, kl, 0) <= 0) 145 return 0; 146 DES_set_odd_parity(deskey); 147 if (kl >= 16) { 148 DES_set_odd_parity(deskey + 1); 149 if (kl >= 24) 150 DES_set_odd_parity(deskey + 2); 151 } 152 return 1; 153 } 154 155 int ossl_tdes_get_ctx_params(void *vctx, OSSL_PARAM params[]) 156 { 157 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 158 OSSL_PARAM *p; 159 160 if (!ossl_cipher_generic_get_ctx_params(vctx, params)) 161 return 0; 162 163 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); 164 if (p != NULL && !tdes_generatekey(ctx, p->data)) { 165 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); 166 return 0; 167 } 168 if (!OSSL_FIPS_IND_GET_CTX_PARAM((PROV_TDES_CTX *)vctx, params)) 169 return 0; 170 return 1; 171 } 172 173 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_tdes) 174 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), 175 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), 176 OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK) 177 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_tdes) 178 179 int ossl_tdes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 180 { 181 if (!OSSL_FIPS_IND_SET_CTX_PARAM((PROV_TDES_CTX *)vctx, 182 OSSL_FIPS_IND_SETTABLE0, params, 183 OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK)) 184 return 0; 185 return ossl_cipher_generic_set_ctx_params(vctx, params); 186 } 187 188 int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, 189 size_t kbits, size_t blkbits, size_t ivbits) 190 { 191 #ifdef FIPS_MODULE 192 const int decrypt_only = 1; 193 #else 194 const int decrypt_only = 0; 195 #endif 196 OSSL_PARAM *p; 197 198 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_DECRYPT_ONLY); 199 if (p != NULL && !OSSL_PARAM_set_int(p, decrypt_only)) { 200 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 201 return 0; 202 } 203 204 return ossl_cipher_generic_get_params(params, md, flags, 205 kbits, blkbits, ivbits); 206 } 207