1 /* 2 * Copyright 2018-2022 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. We access the DES_set_odd_parity(3) function here. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdlib.h> 17 #include <stdarg.h> 18 #include <string.h> 19 20 #include <openssl/core_names.h> 21 #include <openssl/des.h> 22 #include <openssl/evp.h> 23 #include <openssl/kdf.h> 24 #include <openssl/proverr.h> 25 26 #include "internal/cryptlib.h" 27 #include "crypto/evp.h" 28 #include "internal/numbers.h" 29 #include "prov/implementations.h" 30 #include "prov/provider_ctx.h" 31 #include "prov/provider_util.h" 32 #include "prov/providercommon.h" 33 34 /* KRB5 KDF defined in RFC 3961, Section 5.1 */ 35 36 static OSSL_FUNC_kdf_newctx_fn krb5kdf_new; 37 static OSSL_FUNC_kdf_freectx_fn krb5kdf_free; 38 static OSSL_FUNC_kdf_reset_fn krb5kdf_reset; 39 static OSSL_FUNC_kdf_derive_fn krb5kdf_derive; 40 static OSSL_FUNC_kdf_settable_ctx_params_fn krb5kdf_settable_ctx_params; 41 static OSSL_FUNC_kdf_set_ctx_params_fn krb5kdf_set_ctx_params; 42 static OSSL_FUNC_kdf_gettable_ctx_params_fn krb5kdf_gettable_ctx_params; 43 static OSSL_FUNC_kdf_get_ctx_params_fn krb5kdf_get_ctx_params; 44 45 static int KRB5KDF(const EVP_CIPHER *cipher, ENGINE *engine, 46 const unsigned char *key, size_t key_len, 47 const unsigned char *constant, size_t constant_len, 48 unsigned char *okey, size_t okey_len); 49 50 typedef struct { 51 void *provctx; 52 PROV_CIPHER cipher; 53 unsigned char *key; 54 size_t key_len; 55 unsigned char *constant; 56 size_t constant_len; 57 } KRB5KDF_CTX; 58 59 static void *krb5kdf_new(void *provctx) 60 { 61 KRB5KDF_CTX *ctx; 62 63 if (!ossl_prov_is_running()) 64 return NULL; 65 66 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 67 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 68 return NULL; 69 } 70 ctx->provctx = provctx; 71 return ctx; 72 } 73 74 static void krb5kdf_free(void *vctx) 75 { 76 KRB5KDF_CTX *ctx = (KRB5KDF_CTX *)vctx; 77 78 if (ctx != NULL) { 79 krb5kdf_reset(ctx); 80 OPENSSL_free(ctx); 81 } 82 } 83 84 static void krb5kdf_reset(void *vctx) 85 { 86 KRB5KDF_CTX *ctx = (KRB5KDF_CTX *)vctx; 87 void *provctx = ctx->provctx; 88 89 ossl_prov_cipher_reset(&ctx->cipher); 90 OPENSSL_clear_free(ctx->key, ctx->key_len); 91 OPENSSL_clear_free(ctx->constant, ctx->constant_len); 92 memset(ctx, 0, sizeof(*ctx)); 93 ctx->provctx = provctx; 94 } 95 96 static int krb5kdf_set_membuf(unsigned char **dst, size_t *dst_len, 97 const OSSL_PARAM *p) 98 { 99 OPENSSL_clear_free(*dst, *dst_len); 100 *dst = NULL; 101 *dst_len = 0; 102 return OSSL_PARAM_get_octet_string(p, (void **)dst, 0, dst_len); 103 } 104 105 static int krb5kdf_derive(void *vctx, unsigned char *key, size_t keylen, 106 const OSSL_PARAM params[]) 107 { 108 KRB5KDF_CTX *ctx = (KRB5KDF_CTX *)vctx; 109 const EVP_CIPHER *cipher; 110 ENGINE *engine; 111 112 if (!ossl_prov_is_running() || !krb5kdf_set_ctx_params(ctx, params)) 113 return 0; 114 115 cipher = ossl_prov_cipher_cipher(&ctx->cipher); 116 if (cipher == NULL) { 117 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER); 118 return 0; 119 } 120 if (ctx->key == NULL) { 121 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); 122 return 0; 123 } 124 if (ctx->constant == NULL) { 125 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONSTANT); 126 return 0; 127 } 128 engine = ossl_prov_cipher_engine(&ctx->cipher); 129 return KRB5KDF(cipher, engine, ctx->key, ctx->key_len, 130 ctx->constant, ctx->constant_len, 131 key, keylen); 132 } 133 134 static int krb5kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 135 { 136 const OSSL_PARAM *p; 137 KRB5KDF_CTX *ctx = vctx; 138 OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); 139 140 if (params == NULL) 141 return 1; 142 143 if (!ossl_prov_cipher_load_from_params(&ctx->cipher, params, provctx)) 144 return 0; 145 146 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) 147 if (!krb5kdf_set_membuf(&ctx->key, &ctx->key_len, p)) 148 return 0; 149 150 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CONSTANT)) 151 != NULL) 152 if (!krb5kdf_set_membuf(&ctx->constant, &ctx->constant_len, p)) 153 return 0; 154 155 return 1; 156 } 157 158 static const OSSL_PARAM *krb5kdf_settable_ctx_params(ossl_unused void *ctx, 159 ossl_unused void *provctx) 160 { 161 static const OSSL_PARAM known_settable_ctx_params[] = { 162 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), 163 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CIPHER, NULL, 0), 164 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), 165 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_CONSTANT, NULL, 0), 166 OSSL_PARAM_END 167 }; 168 return known_settable_ctx_params; 169 } 170 171 static int krb5kdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) 172 { 173 KRB5KDF_CTX *ctx = (KRB5KDF_CTX *)vctx; 174 const EVP_CIPHER *cipher; 175 size_t len; 176 OSSL_PARAM *p; 177 178 cipher = ossl_prov_cipher_cipher(&ctx->cipher); 179 if (cipher) 180 len = EVP_CIPHER_get_key_length(cipher); 181 else 182 len = EVP_MAX_KEY_LENGTH; 183 184 if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) 185 return OSSL_PARAM_set_size_t(p, len); 186 return -2; 187 } 188 189 static const OSSL_PARAM *krb5kdf_gettable_ctx_params(ossl_unused void *ctx, 190 ossl_unused void *provctx) 191 { 192 static const OSSL_PARAM known_gettable_ctx_params[] = { 193 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), 194 OSSL_PARAM_END 195 }; 196 return known_gettable_ctx_params; 197 } 198 199 const OSSL_DISPATCH ossl_kdf_krb5kdf_functions[] = { 200 { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))krb5kdf_new }, 201 { OSSL_FUNC_KDF_FREECTX, (void(*)(void))krb5kdf_free }, 202 { OSSL_FUNC_KDF_RESET, (void(*)(void))krb5kdf_reset }, 203 { OSSL_FUNC_KDF_DERIVE, (void(*)(void))krb5kdf_derive }, 204 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, 205 (void(*)(void))krb5kdf_settable_ctx_params }, 206 { OSSL_FUNC_KDF_SET_CTX_PARAMS, 207 (void(*)(void))krb5kdf_set_ctx_params }, 208 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, 209 (void(*)(void))krb5kdf_gettable_ctx_params }, 210 { OSSL_FUNC_KDF_GET_CTX_PARAMS, 211 (void(*)(void))krb5kdf_get_ctx_params }, 212 { 0, NULL } 213 }; 214 215 #ifndef OPENSSL_NO_DES 216 /* 217 * DES3 is a special case, it requires a random-to-key function and its 218 * input truncated to 21 bytes of the 24 produced by the cipher. 219 * See RFC3961 6.3.1 220 */ 221 static int fixup_des3_key(unsigned char *key) 222 { 223 unsigned char *cblock; 224 int i, j; 225 226 for (i = 2; i >= 0; i--) { 227 cblock = &key[i * 8]; 228 memmove(cblock, &key[i * 7], 7); 229 cblock[7] = 0; 230 for (j = 0; j < 7; j++) 231 cblock[7] |= (cblock[j] & 1) << (j + 1); 232 DES_set_odd_parity((DES_cblock *)cblock); 233 } 234 235 /* fail if keys are such that triple des degrades to single des */ 236 if (CRYPTO_memcmp(&key[0], &key[8], 8) == 0 || 237 CRYPTO_memcmp(&key[8], &key[16], 8) == 0) { 238 return 0; 239 } 240 241 return 1; 242 } 243 #endif 244 245 /* 246 * N-fold(K) where blocksize is N, and constant_len is K 247 * Note: Here |= denotes concatenation 248 * 249 * L = lcm(N,K) 250 * R = L/K 251 * 252 * for r: 1 -> R 253 * s |= constant rot 13*(r-1)) 254 * 255 * block = 0 256 * for k: 1 -> K 257 * block += s[N(k-1)..(N-1)k] (one's complement addition) 258 * 259 * Optimizing for space we compute: 260 * for each l in L-1 -> 0: 261 * s[l] = (constant rot 13*(l/K))[l%k] 262 * block[l % N] += s[l] (with carry) 263 * finally add carry if any 264 */ 265 static void n_fold(unsigned char *block, unsigned int blocksize, 266 const unsigned char *constant, size_t constant_len) 267 { 268 unsigned int tmp, gcd, remainder, lcm, carry; 269 int b, l; 270 271 if (constant_len == blocksize) { 272 memcpy(block, constant, constant_len); 273 return; 274 } 275 276 /* Least Common Multiple of lengths: LCM(a,b)*/ 277 gcd = blocksize; 278 remainder = constant_len; 279 /* Calculate Great Common Divisor first GCD(a,b) */ 280 while (remainder != 0) { 281 tmp = gcd % remainder; 282 gcd = remainder; 283 remainder = tmp; 284 } 285 /* resulting a is the GCD, LCM(a,b) = |a*b|/GCD(a,b) */ 286 lcm = blocksize * constant_len / gcd; 287 288 /* now spread out the bits */ 289 memset(block, 0, blocksize); 290 291 /* last to first to be able to bring carry forward */ 292 carry = 0; 293 for (l = lcm - 1; l >= 0; l--) { 294 unsigned int rotbits, rshift, rbyte; 295 296 /* destination byte in block is l % N */ 297 b = l % blocksize; 298 /* Our virtual s buffer is R = L/K long (K = constant_len) */ 299 /* So we rotate backwards from R-1 to 0 (none) rotations */ 300 rotbits = 13 * (l / constant_len); 301 /* find the byte on s where rotbits falls onto */ 302 rbyte = l - (rotbits / 8); 303 /* calculate how much shift on that byte */ 304 rshift = rotbits & 0x07; 305 /* rbyte % constant_len gives us the unrotated byte in the 306 * constant buffer, get also the previous byte then 307 * appropriately shift them to get the rotated byte we need */ 308 tmp = (constant[(rbyte-1) % constant_len] << (8 - rshift) 309 | constant[rbyte % constant_len] >> rshift) 310 & 0xff; 311 /* add with carry to any value placed by previous passes */ 312 tmp += carry + block[b]; 313 block[b] = tmp & 0xff; 314 /* save any carry that may be left */ 315 carry = tmp >> 8; 316 } 317 318 /* if any carry is left at the end, add it through the number */ 319 for (b = blocksize - 1; b >= 0 && carry != 0; b--) { 320 carry += block[b]; 321 block[b] = carry & 0xff; 322 carry >>= 8; 323 } 324 } 325 326 static int cipher_init(EVP_CIPHER_CTX *ctx, 327 const EVP_CIPHER *cipher, ENGINE *engine, 328 const unsigned char *key, size_t key_len) 329 { 330 int klen, ret; 331 332 ret = EVP_EncryptInit_ex(ctx, cipher, engine, key, NULL); 333 if (!ret) 334 goto out; 335 /* set the key len for the odd variable key len cipher */ 336 klen = EVP_CIPHER_CTX_get_key_length(ctx); 337 if (key_len != (size_t)klen) { 338 ret = EVP_CIPHER_CTX_set_key_length(ctx, key_len); 339 if (ret <= 0) { 340 ret = 0; 341 goto out; 342 } 343 } 344 /* we never want padding, either the length requested is a multiple of 345 * the cipher block size or we are passed a cipher that can cope with 346 * partial blocks via techniques like cipher text stealing */ 347 ret = EVP_CIPHER_CTX_set_padding(ctx, 0); 348 if (!ret) 349 goto out; 350 351 out: 352 return ret; 353 } 354 355 static int KRB5KDF(const EVP_CIPHER *cipher, ENGINE *engine, 356 const unsigned char *key, size_t key_len, 357 const unsigned char *constant, size_t constant_len, 358 unsigned char *okey, size_t okey_len) 359 { 360 EVP_CIPHER_CTX *ctx = NULL; 361 unsigned char block[EVP_MAX_BLOCK_LENGTH * 2]; 362 unsigned char *plainblock, *cipherblock; 363 size_t blocksize; 364 size_t cipherlen; 365 size_t osize; 366 #ifndef OPENSSL_NO_DES 367 int des3_no_fixup = 0; 368 #endif 369 int ret; 370 371 if (key_len != okey_len) { 372 #ifndef OPENSSL_NO_DES 373 /* special case for 3des, where the caller may be requesting 374 * the random raw key, instead of the fixed up key */ 375 if (EVP_CIPHER_get_nid(cipher) == NID_des_ede3_cbc && 376 key_len == 24 && okey_len == 21) { 377 des3_no_fixup = 1; 378 } else { 379 #endif 380 ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE); 381 return 0; 382 #ifndef OPENSSL_NO_DES 383 } 384 #endif 385 } 386 387 ctx = EVP_CIPHER_CTX_new(); 388 if (ctx == NULL) 389 return 0; 390 391 ret = cipher_init(ctx, cipher, engine, key, key_len); 392 if (!ret) 393 goto out; 394 395 /* Initialize input block */ 396 blocksize = EVP_CIPHER_CTX_get_block_size(ctx); 397 398 if (constant_len > blocksize) { 399 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONSTANT_LENGTH); 400 ret = 0; 401 goto out; 402 } 403 404 n_fold(block, blocksize, constant, constant_len); 405 plainblock = block; 406 cipherblock = block + EVP_MAX_BLOCK_LENGTH; 407 408 for (osize = 0; osize < okey_len; osize += cipherlen) { 409 int olen; 410 411 ret = EVP_EncryptUpdate(ctx, cipherblock, &olen, 412 plainblock, blocksize); 413 if (!ret) 414 goto out; 415 cipherlen = olen; 416 ret = EVP_EncryptFinal_ex(ctx, cipherblock, &olen); 417 if (!ret) 418 goto out; 419 if (olen != 0) { 420 ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); 421 ret = 0; 422 goto out; 423 } 424 425 /* write cipherblock out */ 426 if (cipherlen > okey_len - osize) 427 cipherlen = okey_len - osize; 428 memcpy(okey + osize, cipherblock, cipherlen); 429 430 if (okey_len > osize + cipherlen) { 431 /* we need to reinitialize cipher context per spec */ 432 ret = EVP_CIPHER_CTX_reset(ctx); 433 if (!ret) 434 goto out; 435 ret = cipher_init(ctx, cipher, engine, key, key_len); 436 if (!ret) 437 goto out; 438 439 /* also swap block offsets so last ciphertext becomes new 440 * plaintext */ 441 plainblock = cipherblock; 442 if (cipherblock == block) { 443 cipherblock += EVP_MAX_BLOCK_LENGTH; 444 } else { 445 cipherblock = block; 446 } 447 } 448 } 449 450 #ifndef OPENSSL_NO_DES 451 if (EVP_CIPHER_get_nid(cipher) == NID_des_ede3_cbc && !des3_no_fixup) { 452 ret = fixup_des3_key(okey); 453 if (!ret) { 454 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); 455 goto out; 456 } 457 } 458 #endif 459 460 ret = 1; 461 462 out: 463 EVP_CIPHER_CTX_free(ctx); 464 OPENSSL_cleanse(block, EVP_MAX_BLOCK_LENGTH * 2); 465 return ret; 466 } 467 468