diff options
Diffstat (limited to 'providers/common/kdfs/sshkdf.c')
-rw-r--r-- | providers/common/kdfs/sshkdf.c | 292 |
1 files changed, 0 insertions, 292 deletions
diff --git a/providers/common/kdfs/sshkdf.c b/providers/common/kdfs/sshkdf.c deleted file mode 100644 index 4701c9cad1..0000000000 --- a/providers/common/kdfs/sshkdf.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2018-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <openssl/evp.h> -#include <openssl/kdf.h> -#include "internal/cryptlib.h" -#include "internal/numbers.h" -#include "internal/evp_int.h" -#include "kdf_local.h" - -/* See RFC 4253, Section 7.2 */ - -static void kdf_sshkdf_reset(EVP_KDF_IMPL *impl); -static int SSHKDF(const EVP_MD *evp_md, - const unsigned char *key, size_t key_len, - const unsigned char *xcghash, size_t xcghash_len, - const unsigned char *session_id, size_t session_id_len, - char type, unsigned char *okey, size_t okey_len); - -struct evp_kdf_impl_st { - const EVP_MD *md; - unsigned char *key; /* K */ - size_t key_len; - unsigned char *xcghash; /* H */ - size_t xcghash_len; - char type; /* X */ - unsigned char *session_id; - size_t session_id_len; -}; - -static EVP_KDF_IMPL *kdf_sshkdf_new(void) -{ - EVP_KDF_IMPL *impl; - - if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL) - KDFerr(KDF_F_KDF_SSHKDF_NEW, ERR_R_MALLOC_FAILURE); - return impl; -} - -static void kdf_sshkdf_free(EVP_KDF_IMPL *impl) -{ - kdf_sshkdf_reset(impl); - OPENSSL_free(impl); -} - -static void kdf_sshkdf_reset(EVP_KDF_IMPL *impl) -{ - OPENSSL_clear_free(impl->key, impl->key_len); - OPENSSL_clear_free(impl->xcghash, impl->xcghash_len); - OPENSSL_clear_free(impl->session_id, impl->session_id_len); - memset(impl, 0, sizeof(*impl)); -} - -static int kdf_sshkdf_parse_buffer_arg(unsigned char **dst, size_t *dst_len, - va_list args) -{ - const unsigned char *p; - size_t len; - - p = va_arg(args, const unsigned char *); - len = va_arg(args, size_t); - OPENSSL_clear_free(*dst, *dst_len); - *dst = OPENSSL_memdup(p, len); - if (*dst == NULL) - return 0; - - *dst_len = len; - return 1; -} - -static int kdf_sshkdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) -{ - int t; - - switch (cmd) { - case EVP_KDF_CTRL_SET_MD: - impl->md = va_arg(args, const EVP_MD *); - if (impl->md == NULL) - return 0; - - return 1; - - case EVP_KDF_CTRL_SET_KEY: - return kdf_sshkdf_parse_buffer_arg(&impl->key, - &impl->key_len, args); - - case EVP_KDF_CTRL_SET_SSHKDF_XCGHASH: - return kdf_sshkdf_parse_buffer_arg(&impl->xcghash, - &impl->xcghash_len, args); - - case EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID: - return kdf_sshkdf_parse_buffer_arg(&impl->session_id, - &impl->session_id_len, args); - - case EVP_KDF_CTRL_SET_SSHKDF_TYPE: - t = va_arg(args, int); - if (t < 65 || t > 70) { - KDFerr(KDF_F_KDF_SSHKDF_CTRL, KDF_R_VALUE_ERROR); - return 0; - } - - impl->type = (char)t; - return 1; - - default: - return -2; - - } -} - -static int kdf_sshkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type, - const char *value) -{ - if (value == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_CTRL_STR, KDF_R_VALUE_MISSING); - return 0; - } - - if (strcmp(type, "digest") == 0) - return kdf_md2ctrl(impl, kdf_sshkdf_ctrl, EVP_KDF_CTRL_SET_MD, value); - /* alias, for historical reasons */ - if (strcmp(type, "md") == 0) - return kdf_md2ctrl(impl, kdf_sshkdf_ctrl, EVP_KDF_CTRL_SET_MD, value); - - if (strcmp(type, "key") == 0) - return kdf_str2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_KEY, value); - - if (strcmp(type, "hexkey") == 0) - return kdf_hex2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_KEY, value); - - if (strcmp(type, "xcghash") == 0) - return kdf_str2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, value); - - if (strcmp(type, "hexxcghash") == 0) - return kdf_hex2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, value); - - if (strcmp(type, "session_id") == 0) - return kdf_str2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, value); - - if (strcmp(type, "hexsession_id") == 0) - return kdf_hex2ctrl(impl, kdf_sshkdf_ctrl, - EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, value); - - if (strcmp(type, "type") == 0) { - if (strlen(value) != 1) { - KDFerr(KDF_F_KDF_SSHKDF_CTRL_STR, KDF_R_VALUE_ERROR); - return 0; - } - - return call_ctrl(kdf_sshkdf_ctrl, impl, EVP_KDF_CTRL_SET_SSHKDF_TYPE, - (int)value[0]); - } - - KDFerr(KDF_F_KDF_SSHKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); - return -2; -} - -static size_t kdf_sshkdf_size(EVP_KDF_IMPL *impl) -{ - return SIZE_MAX; -} - -static int kdf_sshkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, - size_t keylen) -{ - if (impl->md == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); - return 0; - } - if (impl->key == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_KEY); - return 0; - } - if (impl->xcghash == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_XCGHASH); - return 0; - } - if (impl->session_id == NULL) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_SESSION_ID); - return 0; - } - if (impl->type == 0) { - KDFerr(KDF_F_KDF_SSHKDF_DERIVE, KDF_R_MISSING_TYPE); - return 0; - } - return SSHKDF(impl->md, impl->key, impl->key_len, - impl->xcghash, impl->xcghash_len, - impl->session_id, impl->session_id_len, - impl->type, key, keylen); -} - -const EVP_KDF sshkdf_kdf_meth = { - EVP_KDF_SSHKDF, - kdf_sshkdf_new, - kdf_sshkdf_free, - kdf_sshkdf_reset, - kdf_sshkdf_ctrl, - kdf_sshkdf_ctrl_str, - kdf_sshkdf_size, - kdf_sshkdf_derive, -}; - -static int SSHKDF(const EVP_MD *evp_md, - const unsigned char *key, size_t key_len, - const unsigned char *xcghash, size_t xcghash_len, - const unsigned char *session_id, size_t session_id_len, - char type, unsigned char *okey, size_t okey_len) -{ - EVP_MD_CTX *md = NULL; - unsigned char digest[EVP_MAX_MD_SIZE]; - unsigned int dsize = 0; - size_t cursize = 0; - int ret = 0; - - md = EVP_MD_CTX_new(); - if (md == NULL) - return 0; - - if (!EVP_DigestInit_ex(md, evp_md, NULL)) - goto out; - - if (!EVP_DigestUpdate(md, key, key_len)) - goto out; - - if (!EVP_DigestUpdate(md, xcghash, xcghash_len)) - goto out; - - if (!EVP_DigestUpdate(md, &type, 1)) - goto out; - - if (!EVP_DigestUpdate(md, session_id, session_id_len)) - goto out; - - if (!EVP_DigestFinal_ex(md, digest, &dsize)) - goto out; - - if (okey_len < dsize) { - memcpy(okey, digest, okey_len); - ret = 1; - goto out; - } - - memcpy(okey, digest, dsize); - - for (cursize = dsize; cursize < okey_len; cursize += dsize) { - - if (!EVP_DigestInit_ex(md, evp_md, NULL)) - goto out; - - if (!EVP_DigestUpdate(md, key, key_len)) - goto out; - - if (!EVP_DigestUpdate(md, xcghash, xcghash_len)) - goto out; - - if (!EVP_DigestUpdate(md, okey, cursize)) - goto out; - - if (!EVP_DigestFinal_ex(md, digest, &dsize)) - goto out; - - if (okey_len < cursize + dsize) { - memcpy(okey + cursize, digest, okey_len - cursize); - ret = 1; - goto out; - } - - memcpy(okey + cursize, digest, dsize); - } - - ret = 1; - -out: - EVP_MD_CTX_free(md); - OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE); - return ret; -} - |