2 * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
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
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.
14 #include "internal/deprecated.h"
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>
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"
34 /* KRB5 KDF defined in RFC 3961, Section 5.1 */
36 static OSSL_FUNC_kdf_newctx_fn krb5kdf_new
;
37 static OSSL_FUNC_kdf_dupctx_fn krb5kdf_dup
;
38 static OSSL_FUNC_kdf_freectx_fn krb5kdf_free
;
39 static OSSL_FUNC_kdf_reset_fn krb5kdf_reset
;
40 static OSSL_FUNC_kdf_derive_fn krb5kdf_derive
;
41 static OSSL_FUNC_kdf_settable_ctx_params_fn krb5kdf_settable_ctx_params
;
42 static OSSL_FUNC_kdf_set_ctx_params_fn krb5kdf_set_ctx_params
;
43 static OSSL_FUNC_kdf_gettable_ctx_params_fn krb5kdf_gettable_ctx_params
;
44 static OSSL_FUNC_kdf_get_ctx_params_fn krb5kdf_get_ctx_params
;
46 static int KRB5KDF(const EVP_CIPHER
*cipher
, ENGINE
*engine
,
47 const unsigned char *key
, size_t key_len
,
48 const unsigned char *constant
, size_t constant_len
,
49 unsigned char *okey
, size_t okey_len
);
56 unsigned char *constant
;
60 static void *krb5kdf_new(void *provctx
)
64 if (!ossl_prov_is_running())
67 if ((ctx
= OPENSSL_zalloc(sizeof(*ctx
))) == NULL
)
69 ctx
->provctx
= provctx
;
73 static void krb5kdf_free(void *vctx
)
75 KRB5KDF_CTX
*ctx
= (KRB5KDF_CTX
*)vctx
;
83 static void krb5kdf_reset(void *vctx
)
85 KRB5KDF_CTX
*ctx
= (KRB5KDF_CTX
*)vctx
;
86 void *provctx
= ctx
->provctx
;
88 ossl_prov_cipher_reset(&ctx
->cipher
);
89 OPENSSL_clear_free(ctx
->key
, ctx
->key_len
);
90 OPENSSL_clear_free(ctx
->constant
, ctx
->constant_len
);
91 memset(ctx
, 0, sizeof(*ctx
));
92 ctx
->provctx
= provctx
;
95 static int krb5kdf_set_membuf(unsigned char **dst
, size_t *dst_len
,
98 OPENSSL_clear_free(*dst
, *dst_len
);
101 return OSSL_PARAM_get_octet_string(p
, (void **)dst
, 0, dst_len
);
104 static void *krb5kdf_dup(void *vctx
)
106 const KRB5KDF_CTX
*src
= (const KRB5KDF_CTX
*)vctx
;
109 dest
= krb5kdf_new(src
->provctx
);
111 if (!ossl_prov_memdup(src
->key
, src
->key_len
,
112 &dest
->key
, &dest
->key_len
)
113 || !ossl_prov_memdup(src
->constant
, src
->constant_len
,
114 &dest
->constant
, &dest
->constant_len
)
115 || !ossl_prov_cipher_copy(&dest
->cipher
, &src
->cipher
))
125 static int krb5kdf_derive(void *vctx
, unsigned char *key
, size_t keylen
,
126 const OSSL_PARAM params
[])
128 KRB5KDF_CTX
*ctx
= (KRB5KDF_CTX
*)vctx
;
129 const EVP_CIPHER
*cipher
;
132 if (!ossl_prov_is_running() || !krb5kdf_set_ctx_params(ctx
, params
))
135 cipher
= ossl_prov_cipher_cipher(&ctx
->cipher
);
136 if (cipher
== NULL
) {
137 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_CIPHER
);
140 if (ctx
->key
== NULL
) {
141 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_KEY
);
144 if (ctx
->constant
== NULL
) {
145 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_CONSTANT
);
148 engine
= ossl_prov_cipher_engine(&ctx
->cipher
);
149 return KRB5KDF(cipher
, engine
, ctx
->key
, ctx
->key_len
,
150 ctx
->constant
, ctx
->constant_len
,
154 static int krb5kdf_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
157 KRB5KDF_CTX
*ctx
= vctx
;
158 OSSL_LIB_CTX
*provctx
= PROV_LIBCTX_OF(ctx
->provctx
);
163 if (!ossl_prov_cipher_load_from_params(&ctx
->cipher
, params
, provctx
))
166 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_KEY
)) != NULL
)
167 if (!krb5kdf_set_membuf(&ctx
->key
, &ctx
->key_len
, p
))
170 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_CONSTANT
))
172 if (!krb5kdf_set_membuf(&ctx
->constant
, &ctx
->constant_len
, p
))
178 static const OSSL_PARAM
*krb5kdf_settable_ctx_params(ossl_unused
void *ctx
,
179 ossl_unused
void *provctx
)
181 static const OSSL_PARAM known_settable_ctx_params
[] = {
182 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
183 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CIPHER
, NULL
, 0),
184 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY
, NULL
, 0),
185 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_CONSTANT
, NULL
, 0),
188 return known_settable_ctx_params
;
191 static int krb5kdf_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
193 KRB5KDF_CTX
*ctx
= (KRB5KDF_CTX
*)vctx
;
194 const EVP_CIPHER
*cipher
;
198 cipher
= ossl_prov_cipher_cipher(&ctx
->cipher
);
200 len
= EVP_CIPHER_get_key_length(cipher
);
202 len
= EVP_MAX_KEY_LENGTH
;
204 if ((p
= OSSL_PARAM_locate(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
)
205 return OSSL_PARAM_set_size_t(p
, len
);
209 static const OSSL_PARAM
*krb5kdf_gettable_ctx_params(ossl_unused
void *ctx
,
210 ossl_unused
void *provctx
)
212 static const OSSL_PARAM known_gettable_ctx_params
[] = {
213 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE
, NULL
),
216 return known_gettable_ctx_params
;
219 const OSSL_DISPATCH ossl_kdf_krb5kdf_functions
[] = {
220 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))krb5kdf_new
},
221 { OSSL_FUNC_KDF_DUPCTX
, (void(*)(void))krb5kdf_dup
},
222 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))krb5kdf_free
},
223 { OSSL_FUNC_KDF_RESET
, (void(*)(void))krb5kdf_reset
},
224 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))krb5kdf_derive
},
225 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
226 (void(*)(void))krb5kdf_settable_ctx_params
},
227 { OSSL_FUNC_KDF_SET_CTX_PARAMS
,
228 (void(*)(void))krb5kdf_set_ctx_params
},
229 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
230 (void(*)(void))krb5kdf_gettable_ctx_params
},
231 { OSSL_FUNC_KDF_GET_CTX_PARAMS
,
232 (void(*)(void))krb5kdf_get_ctx_params
},
236 #ifndef OPENSSL_NO_DES
238 * DES3 is a special case, it requires a random-to-key function and its
239 * input truncated to 21 bytes of the 24 produced by the cipher.
242 static int fixup_des3_key(unsigned char *key
)
244 unsigned char *cblock
;
247 for (i
= 2; i
>= 0; i
--) {
248 cblock
= &key
[i
* 8];
249 memmove(cblock
, &key
[i
* 7], 7);
251 for (j
= 0; j
< 7; j
++)
252 cblock
[7] |= (cblock
[j
] & 1) << (j
+ 1);
253 DES_set_odd_parity((DES_cblock
*)cblock
);
256 /* fail if keys are such that triple des degrades to single des */
257 if (CRYPTO_memcmp(&key
[0], &key
[8], 8) == 0 ||
258 CRYPTO_memcmp(&key
[8], &key
[16], 8) == 0) {
267 * N-fold(K) where blocksize is N, and constant_len is K
268 * Note: Here |= denotes concatenation
274 * s |= constant rot 13*(r-1))
278 * block += s[N(k-1)..(N-1)k] (one's complement addition)
280 * Optimizing for space we compute:
281 * for each l in L-1 -> 0:
282 * s[l] = (constant rot 13*(l/K))[l%k]
283 * block[l % N] += s[l] (with carry)
284 * finally add carry if any
286 static void n_fold(unsigned char *block
, unsigned int blocksize
,
287 const unsigned char *constant
, size_t constant_len
)
289 unsigned int tmp
, gcd
, remainder
, lcm
, carry
;
292 if (constant_len
== blocksize
) {
293 memcpy(block
, constant
, constant_len
);
297 /* Least Common Multiple of lengths: LCM(a,b)*/
299 remainder
= constant_len
;
300 /* Calculate Great Common Divisor first GCD(a,b) */
301 while (remainder
!= 0) {
302 tmp
= gcd
% remainder
;
306 /* resulting a is the GCD, LCM(a,b) = |a*b|/GCD(a,b) */
307 lcm
= blocksize
* constant_len
/ gcd
;
309 /* now spread out the bits */
310 memset(block
, 0, blocksize
);
312 /* last to first to be able to bring carry forward */
314 for (l
= lcm
- 1; l
>= 0; l
--) {
315 unsigned int rotbits
, rshift
, rbyte
;
317 /* destination byte in block is l % N */
319 /* Our virtual s buffer is R = L/K long (K = constant_len) */
320 /* So we rotate backwards from R-1 to 0 (none) rotations */
321 rotbits
= 13 * (l
/ constant_len
);
322 /* find the byte on s where rotbits falls onto */
323 rbyte
= l
- (rotbits
/ 8);
324 /* calculate how much shift on that byte */
325 rshift
= rotbits
& 0x07;
326 /* rbyte % constant_len gives us the unrotated byte in the
327 * constant buffer, get also the previous byte then
328 * appropriately shift them to get the rotated byte we need */
329 tmp
= (constant
[(rbyte
-1) % constant_len
] << (8 - rshift
)
330 | constant
[rbyte
% constant_len
] >> rshift
)
332 /* add with carry to any value placed by previous passes */
333 tmp
+= carry
+ block
[b
];
334 block
[b
] = tmp
& 0xff;
335 /* save any carry that may be left */
339 /* if any carry is left at the end, add it through the number */
340 for (b
= blocksize
- 1; b
>= 0 && carry
!= 0; b
--) {
342 block
[b
] = carry
& 0xff;
347 static int cipher_init(EVP_CIPHER_CTX
*ctx
,
348 const EVP_CIPHER
*cipher
, ENGINE
*engine
,
349 const unsigned char *key
, size_t key_len
)
353 ret
= EVP_EncryptInit_ex(ctx
, cipher
, engine
, key
, NULL
);
356 /* set the key len for the odd variable key len cipher */
357 klen
= EVP_CIPHER_CTX_get_key_length(ctx
);
358 if (key_len
!= (size_t)klen
) {
359 ret
= EVP_CIPHER_CTX_set_key_length(ctx
, key_len
);
365 /* we never want padding, either the length requested is a multiple of
366 * the cipher block size or we are passed a cipher that can cope with
367 * partial blocks via techniques like cipher text stealing */
368 ret
= EVP_CIPHER_CTX_set_padding(ctx
, 0);
376 static int KRB5KDF(const EVP_CIPHER
*cipher
, ENGINE
*engine
,
377 const unsigned char *key
, size_t key_len
,
378 const unsigned char *constant
, size_t constant_len
,
379 unsigned char *okey
, size_t okey_len
)
381 EVP_CIPHER_CTX
*ctx
= NULL
;
382 unsigned char block
[EVP_MAX_BLOCK_LENGTH
* 2];
383 unsigned char *plainblock
, *cipherblock
;
387 #ifndef OPENSSL_NO_DES
388 int des3_no_fixup
= 0;
392 if (key_len
!= okey_len
) {
393 #ifndef OPENSSL_NO_DES
394 /* special case for 3des, where the caller may be requesting
395 * the random raw key, instead of the fixed up key */
396 if (EVP_CIPHER_get_nid(cipher
) == NID_des_ede3_cbc
&&
397 key_len
== 24 && okey_len
== 21) {
401 ERR_raise(ERR_LIB_PROV
, PROV_R_WRONG_OUTPUT_BUFFER_SIZE
);
403 #ifndef OPENSSL_NO_DES
408 ctx
= EVP_CIPHER_CTX_new();
412 ret
= cipher_init(ctx
, cipher
, engine
, key
, key_len
);
416 /* Initialize input block */
417 blocksize
= EVP_CIPHER_CTX_get_block_size(ctx
);
419 if (constant_len
> blocksize
) {
420 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_CONSTANT_LENGTH
);
425 n_fold(block
, blocksize
, constant
, constant_len
);
427 cipherblock
= block
+ EVP_MAX_BLOCK_LENGTH
;
429 for (osize
= 0; osize
< okey_len
; osize
+= cipherlen
) {
432 ret
= EVP_EncryptUpdate(ctx
, cipherblock
, &olen
,
433 plainblock
, blocksize
);
437 ret
= EVP_EncryptFinal_ex(ctx
, cipherblock
, &olen
);
441 ERR_raise(ERR_LIB_PROV
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
446 /* write cipherblock out */
447 if (cipherlen
> okey_len
- osize
)
448 cipherlen
= okey_len
- osize
;
449 memcpy(okey
+ osize
, cipherblock
, cipherlen
);
451 if (okey_len
> osize
+ cipherlen
) {
452 /* we need to reinitialize cipher context per spec */
453 ret
= EVP_CIPHER_CTX_reset(ctx
);
456 ret
= cipher_init(ctx
, cipher
, engine
, key
, key_len
);
460 /* also swap block offsets so last ciphertext becomes new
462 plainblock
= cipherblock
;
463 if (cipherblock
== block
) {
464 cipherblock
+= EVP_MAX_BLOCK_LENGTH
;
471 #ifndef OPENSSL_NO_DES
472 if (EVP_CIPHER_get_nid(cipher
) == NID_des_ede3_cbc
&& !des3_no_fixup
) {
473 ret
= fixup_des3_key(okey
);
475 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GENERATE_KEY
);
484 EVP_CIPHER_CTX_free(ctx
);
485 OPENSSL_cleanse(block
, EVP_MAX_BLOCK_LENGTH
* 2);