summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-02-04 10:43:48 +0000
committerDaiki Ueno <ueno@gnu.org>2020-02-04 10:43:48 +0000
commitee43a212b6bde870bf0800329972f3cab24715ec (patch)
tree5cb309ba4c194910e6d203751ac59bc35b5c243c
parente825a5ddbf604a2f9e7dfe69813c1819615edbfa (diff)
parente5876b0332070fa509c0936059a6d8d6e1af5b89 (diff)
downloadgnutls-ee43a212b6bde870bf0800329972f3cab24715ec.tar.gz
Merge branch 'tmp-kdf-api' into 'master'
crypto-api: add generic crypto functions for KDF Closes #851 and #813 See merge request gnutls/gnutls!1186
-rw-r--r--.gitignore1
-rw-r--r--NEWS9
-rw-r--r--devel/libgnutls-latest-x86_64.abi3
-rw-r--r--devel/symbols.last4
-rw-r--r--doc/Makefile.am6
-rw-r--r--doc/manpages/Makefile.am3
-rw-r--r--lib/crypto-api.c95
-rw-r--r--lib/crypto-backend.h16
-rw-r--r--lib/includes/gnutls/crypto.h18
-rw-r--r--lib/libgnutls.map8
-rw-r--r--lib/nettle/mac.c75
-rw-r--r--lib/secrets.c45
-rw-r--r--lib/x509/pkcs12.c38
-rw-r--r--lib/x509/pkcs7-crypt.c46
-rw-r--r--lib/x509/privkey_pkcs8.c1
-rw-r--r--tests/Makefile.am2
-rwxr-xr-xtests/cert-tests/pkcs12-gost5
-rw-r--r--tests/kdf-api.c160
18 files changed, 444 insertions, 91 deletions
diff --git a/.gitignore b/.gitignore
index 34d9af38a5..6c716933fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -436,6 +436,7 @@ tests/insecure_key
tests/iov
tests/ip-check
tests/ip-utils
+tests/kdf-api
tests/key-export-pkcs8
tests/key-id/Makefile
tests/key-id/Makefile.in
diff --git a/NEWS b/NEWS
index 2dcdfe049e..11c860e428 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,15 @@ Copyright (C) 2000-2016 Free Software Foundation, Inc.
Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
See the end for copying conditions.
+* Version 3.6.13 (unreleased)
+
+** libgnutls: Added new APIs to access KDF algorithms (#813).
+
+** API and ABI modifications:
+gnutls_hkdf_extract: Added
+gnutls_hkdf_expand: Added
+gnutls_pbkdf2: Added
+
* Version 3.6.12 (released 2020-02-01)
** libgnutls: Introduced TLS session flag (gnutls_session_get_flags())
diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi
index cab31da9a8..23d346aefa 100644
--- a/devel/libgnutls-latest-x86_64.abi
+++ b/devel/libgnutls-latest-x86_64.abi
@@ -319,6 +319,8 @@
<elf-symbol name='gnutls_hex_decode' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_hex_encode2' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_hex_encode' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_hkdf_expand' version='GNUTLS_3_6_13' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_hkdf_extract' version='GNUTLS_3_6_13' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_hmac' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_hmac_copy' version='GNUTLS_3_6_9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_hmac_deinit' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -465,6 +467,7 @@
<elf-symbol name='gnutls_openpgp_set_recv_key_function' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_packet_deinit' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_packet_get' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_pbkdf2' version='GNUTLS_3_6_13' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_pcert_deinit' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_pcert_export_openpgp' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_pcert_export_x509' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
diff --git a/devel/symbols.last b/devel/symbols.last
index 1e0e56d5c0..5159447705 100644
--- a/devel/symbols.last
+++ b/devel/symbols.last
@@ -2,6 +2,7 @@ GNUTLS_3_4@GNUTLS_3_4
GNUTLS_3_6_0@GNUTLS_3_6_0
GNUTLS_3_6_10@GNUTLS_3_6_10
GNUTLS_3_6_12@GNUTLS_3_6_12
+GNUTLS_3_6_13@GNUTLS_3_6_13
GNUTLS_3_6_2@GNUTLS_3_6_2
GNUTLS_3_6_3@GNUTLS_3_6_3
GNUTLS_3_6_4@GNUTLS_3_6_4
@@ -285,6 +286,8 @@ gnutls_hex_decode2@GNUTLS_3_4
gnutls_hex_decode@GNUTLS_3_4
gnutls_hex_encode2@GNUTLS_3_4
gnutls_hex_encode@GNUTLS_3_4
+gnutls_hkdf_expand@GNUTLS_3_6_13
+gnutls_hkdf_extract@GNUTLS_3_6_13
gnutls_hmac@GNUTLS_3_4
gnutls_hmac_copy@GNUTLS_3_6_9
gnutls_hmac_deinit@GNUTLS_3_4
@@ -431,6 +434,7 @@ gnutls_openpgp_send_cert@GNUTLS_3_4
gnutls_openpgp_set_recv_key_function@GNUTLS_3_4
gnutls_packet_deinit@GNUTLS_3_4
gnutls_packet_get@GNUTLS_3_4
+gnutls_pbkdf2@GNUTLS_3_6_13
gnutls_pcert_deinit@GNUTLS_3_4
gnutls_pcert_export_openpgp@GNUTLS_3_4
gnutls_pcert_export_x509@GNUTLS_3_4
diff --git a/doc/Makefile.am b/doc/Makefile.am
index aa3984ffe1..234cbf315d 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1121,6 +1121,10 @@ FUNCS += functions/gnutls_hex_encode
FUNCS += functions/gnutls_hex_encode.short
FUNCS += functions/gnutls_hex_encode2
FUNCS += functions/gnutls_hex_encode2.short
+FUNCS += functions/gnutls_hkdf_expand
+FUNCS += functions/gnutls_hkdf_expand.short
+FUNCS += functions/gnutls_hkdf_extract
+FUNCS += functions/gnutls_hkdf_extract.short
FUNCS += functions/gnutls_hmac
FUNCS += functions/gnutls_hmac.short
FUNCS += functions/gnutls_hmac_copy
@@ -1277,6 +1281,8 @@ FUNCS += functions/gnutls_packet_deinit
FUNCS += functions/gnutls_packet_deinit.short
FUNCS += functions/gnutls_packet_get
FUNCS += functions/gnutls_packet_get.short
+FUNCS += functions/gnutls_pbkdf2
+FUNCS += functions/gnutls_pbkdf2.short
FUNCS += functions/gnutls_pcert_deinit
FUNCS += functions/gnutls_pcert_deinit.short
FUNCS += functions/gnutls_pcert_export_openpgp
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index 85d0f7f0e4..f11b070fe0 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -362,6 +362,8 @@ APIMANS += gnutls_hex_decode.3
APIMANS += gnutls_hex_decode2.3
APIMANS += gnutls_hex_encode.3
APIMANS += gnutls_hex_encode2.3
+APIMANS += gnutls_hkdf_expand.3
+APIMANS += gnutls_hkdf_extract.3
APIMANS += gnutls_hmac.3
APIMANS += gnutls_hmac_copy.3
APIMANS += gnutls_hmac_deinit.3
@@ -440,6 +442,7 @@ APIMANS += gnutls_openpgp_privkey_sign_hash.3
APIMANS += gnutls_openpgp_send_cert.3
APIMANS += gnutls_packet_deinit.3
APIMANS += gnutls_packet_get.3
+APIMANS += gnutls_pbkdf2.3
APIMANS += gnutls_pcert_deinit.3
APIMANS += gnutls_pcert_export_openpgp.3
APIMANS += gnutls_pcert_export_x509.3
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 4db6812c29..45be64ed1f 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -1401,3 +1401,98 @@ void gnutls_aead_cipher_deinit(gnutls_aead_cipher_hd_t handle)
_gnutls_aead_cipher_deinit(handle);
gnutls_free(handle);
}
+
+extern gnutls_crypto_kdf_st _gnutls_kdf_ops;
+
+/**
+ * gnutls_hkdf_extract:
+ * @mac: the mac algorithm used internally
+ * @key: the initial keying material
+ * @salt: the optional salt
+ * @output: the output value of the extract operation
+ *
+ * This function will derive a fixed-size key using the HKDF-Extract
+ * function as defined in RFC 5869.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.6.13
+ */
+int
+gnutls_hkdf_extract(gnutls_mac_algorithm_t mac,
+ const gnutls_datum_t *key,
+ const gnutls_datum_t *salt,
+ void *output)
+{
+ /* MD5 is only allowed internally for TLS */
+ if (is_mac_algo_forbidden(mac))
+ return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
+
+ return _gnutls_kdf_ops.hkdf_extract(mac, key->data, key->size,
+ salt ? salt->data : NULL,
+ salt ? salt->size : 0,
+ output);
+}
+
+/**
+ * gnutls_hkdf_expand:
+ * @mac: the mac algorithm used internally
+ * @key: the pseudorandom key created with HKDF-Extract
+ * @info: the optional informational data
+ * @output: the output value of the expand operation
+ * @length: the desired length of the output key
+ *
+ * This function will derive a variable length keying material from
+ * the pseudorandom key using the HKDF-Expand function as defined in
+ * RFC 5869.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.6.13
+ */
+int
+gnutls_hkdf_expand(gnutls_mac_algorithm_t mac,
+ const gnutls_datum_t *key,
+ const gnutls_datum_t *info,
+ void *output, size_t length)
+{
+ /* MD5 is only allowed internally for TLS */
+ if (is_mac_algo_forbidden(mac))
+ return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
+
+ return _gnutls_kdf_ops.hkdf_expand(mac, key->data, key->size,
+ info->data, info->size,
+ output, length);
+}
+
+/**
+ * gnutls_pbkdf2:
+ * @mac: the mac algorithm used internally
+ * @key: the initial keying material
+ * @salt: the salt
+ * @iter_count: the iteration count
+ * @output: the output value
+ * @length: the desired length of the output key
+ *
+ * This function will derive a variable length keying material from
+ * a password according to PKCS #5 PBKDF2.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.6.13
+ */
+int
+gnutls_pbkdf2(gnutls_mac_algorithm_t mac,
+ const gnutls_datum_t *key,
+ const gnutls_datum_t *salt,
+ unsigned iter_count,
+ void *output, size_t length)
+{
+ /* MD5 is only allowed internally for TLS */
+ if (is_mac_algo_forbidden(mac))
+ return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
+
+ return _gnutls_kdf_ops.pbkdf2(mac, key->data, key->size,
+ salt->data, salt->size, iter_count,
+ output, length);
+}
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index c083b16498..33005e73dd 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -75,6 +75,22 @@ typedef struct {
int (*exists) (gnutls_digest_algorithm_t);
} gnutls_crypto_digest_st;
+typedef struct {
+ int (*hkdf_extract) (gnutls_mac_algorithm_t,
+ const void *key, size_t keysize,
+ const void *salt, size_t saltsize,
+ void *output);
+ int (*hkdf_expand) (gnutls_mac_algorithm_t,
+ const void *key, size_t keysize,
+ const void *info, size_t infosize,
+ void *output, size_t length);
+ int (*pbkdf2) (gnutls_mac_algorithm_t,
+ const void *key, size_t keysize,
+ const void *salt, size_t saltsize,
+ unsigned iter_count,
+ void *output, size_t length);
+} gnutls_crypto_kdf_st;
+
typedef struct gnutls_crypto_rnd {
int (*init) (void **ctx); /* called prior to first usage of randomness */
int (*rnd) (void *ctx, int level, void *data, size_t datasize);
diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h
index 685d9d5d29..c878d7dfac 100644
--- a/lib/includes/gnutls/crypto.h
+++ b/lib/includes/gnutls/crypto.h
@@ -139,6 +139,24 @@ int gnutls_hash_fast(gnutls_digest_algorithm_t algorithm,
const void *text, size_t textlen, void *digest);
gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle);
+/* KDF API */
+
+int gnutls_hkdf_extract(gnutls_mac_algorithm_t mac,
+ const gnutls_datum_t *key,
+ const gnutls_datum_t *salt,
+ void *output);
+
+int gnutls_hkdf_expand(gnutls_mac_algorithm_t mac,
+ const gnutls_datum_t *key,
+ const gnutls_datum_t *info,
+ void *output, size_t length);
+
+int gnutls_pbkdf2(gnutls_mac_algorithm_t mac,
+ const gnutls_datum_t *key,
+ const gnutls_datum_t *salt,
+ unsigned iter_count,
+ void *output, size_t length);
+
/* register ciphers */
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index e1878bb00c..bf8fff8bc3 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1309,6 +1309,14 @@ GNUTLS_3_6_12
gnutls_hmac_get_key_size;
} GNUTLS_3_6_10;
+GNUTLS_3_6_13
+{
+ global:
+ gnutls_hkdf_extract;
+ gnutls_hkdf_expand;
+ gnutls_pbkdf2;
+} GNUTLS_3_6_12;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c
index 25054dc267..f997cf3d46 100644
--- a/lib/nettle/mac.c
+++ b/lib/nettle/mac.c
@@ -32,6 +32,8 @@
#include <nettle/sha3.h>
#include <nettle/hmac.h>
#include <nettle/umac.h>
+#include <nettle/hkdf.h>
+#include <nettle/pbkdf2.h>
#if ENABLE_GOST
#include "gost/hmac-gost.h"
#ifndef HAVE_NETTLE_GOSTHASH94CP_UPDATE
@@ -825,6 +827,69 @@ wrap_nettle_hash_output(void *src_ctx, void *digest, size_t digestsize)
return 0;
}
+/* KDF functions based on MAC
+ */
+static int
+wrap_nettle_hkdf_extract (gnutls_mac_algorithm_t mac,
+ const void *key, size_t keysize,
+ const void *salt, size_t saltsize,
+ void *output)
+{
+ struct nettle_mac_ctx ctx;
+ int ret;
+
+ ret = _mac_ctx_init(mac, &ctx);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ctx.set_key(&ctx, saltsize, salt);
+ hkdf_extract(&ctx.ctx, ctx.update, ctx.digest, ctx.length,
+ keysize, key, output);
+
+ return 0;
+}
+
+static int
+wrap_nettle_hkdf_expand (gnutls_mac_algorithm_t mac,
+ const void *key, size_t keysize,
+ const void *info, size_t infosize,
+ void *output, size_t length)
+{
+ struct nettle_mac_ctx ctx;
+ int ret;
+
+ ret = _mac_ctx_init(mac, &ctx);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ctx.set_key(&ctx, keysize, key);
+ hkdf_expand(&ctx.ctx, ctx.update, ctx.digest, ctx.length,
+ infosize, info, length, output);
+
+ return 0;
+}
+
+static int
+wrap_nettle_pbkdf2 (gnutls_mac_algorithm_t mac,
+ const void *key, size_t keysize,
+ const void *salt, size_t saltsize,
+ unsigned iter_count,
+ void *output, size_t length)
+{
+ struct nettle_mac_ctx ctx;
+ int ret;
+
+ ret = _mac_ctx_init(mac, &ctx);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ctx.set_key(&ctx, keysize, key);
+ pbkdf2(&ctx.ctx, ctx.update, ctx.digest, ctx.length,
+ iter_count, saltsize, salt, length, output);
+
+ return 0;
+}
+
gnutls_crypto_mac_st _gnutls_mac_ops = {
.init = wrap_nettle_mac_init,
.setkey = wrap_nettle_mac_set_key,
@@ -846,3 +911,13 @@ gnutls_crypto_digest_st _gnutls_digest_ops = {
.exists = wrap_nettle_hash_exists,
.copy = wrap_nettle_hash_copy,
};
+
+/* These names are clashing with nettle's name mangling. */
+#undef hkdf_extract
+#undef hkdf_expand
+#undef pbkdf2
+gnutls_crypto_kdf_st _gnutls_kdf_ops = {
+ .hkdf_extract = wrap_nettle_hkdf_extract,
+ .hkdf_expand = wrap_nettle_hkdf_expand,
+ .pbkdf2 = wrap_nettle_pbkdf2,
+};
diff --git a/lib/secrets.c b/lib/secrets.c
index 94fc305640..7bd69bc7ef 100644
--- a/lib/secrets.c
+++ b/lib/secrets.c
@@ -25,8 +25,6 @@
#include <config.h>
#include "gnutls_int.h"
-#include <nettle/hkdf.h>
-#include <nettle/hmac.h>
#include "secrets.h"
/* HKDF-Extract(0,0) or HKDF-Extract(0, PSK) */
@@ -67,10 +65,17 @@ int _tls13_init_secret2(const mac_entry_st *prf,
/* HKDF-Extract(Prev-Secret, key) */
int _tls13_update_secret(gnutls_session_t session, const uint8_t *key, size_t key_size)
{
- return gnutls_hmac_fast(session->security_parameters.prf->id,
- session->key.proto.tls13.temp_secret, session->key.proto.tls13.temp_secret_size,
- key, key_size,
- session->key.proto.tls13.temp_secret);
+ gnutls_datum_t _key;
+ gnutls_datum_t salt;
+
+ _key.data = (void *)key;
+ _key.size = key_size;
+ salt.data = (void *)session->key.proto.tls13.temp_secret;
+ salt.size = session->key.proto.tls13.temp_secret_size;
+
+ return gnutls_hkdf_extract(session->security_parameters.prf->id,
+ &_key, &salt,
+ session->key.proto.tls13.temp_secret);
}
/* Derive-Secret(Secret, Label, Messages) */
@@ -123,6 +128,8 @@ int _tls13_expand_secret2(const mac_entry_st *prf,
{
uint8_t tmp[256] = "tls13 ";
gnutls_buffer_st str;
+ gnutls_datum_t key;
+ gnutls_datum_t info;
int ret;
if (unlikely(label_size >= sizeof(tmp)-6))
@@ -149,28 +156,14 @@ int _tls13_expand_secret2(const mac_entry_st *prf,
goto cleanup;
}
- switch (prf->id) {
- case GNUTLS_MAC_SHA256:{
- struct hmac_sha256_ctx ctx;
+ key.data = (void *)secret;
+ key.size =_gnutls_mac_get_algo_len(mac_to_entry(prf->id));
+ info.data = str.data;
+ info.size = str.length;
- hmac_sha256_set_key(&ctx, SHA256_DIGEST_SIZE, secret);
- hkdf_expand(&ctx, (nettle_hash_update_func*)hmac_sha256_update,
- (nettle_hash_digest_func*)hmac_sha256_digest, SHA256_DIGEST_SIZE,
- str.length, str.data, out_size, out);
- break;
- }
- case GNUTLS_MAC_SHA384:{
- struct hmac_sha384_ctx ctx;
-
- hmac_sha384_set_key(&ctx, SHA384_DIGEST_SIZE, secret);
- hkdf_expand(&ctx, (nettle_hash_update_func*)hmac_sha384_update,
- (nettle_hash_digest_func*)hmac_sha384_digest, SHA384_DIGEST_SIZE,
- str.length, str.data, out_size, out);
- break;
- }
- default:
+ ret = gnutls_hkdf_expand(prf->id, &key, &info, out, out_size);
+ if (ret < 0) {
gnutls_assert();
- ret = GNUTLS_E_INTERNAL_ERROR;
goto cleanup;
}
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index 6324fb25a3..cdb284026a 100644
--- a/lib/x509/pkcs12.c
+++ b/lib/x509/pkcs12.c
@@ -37,10 +37,6 @@
#include "x509_int.h"
#include "pkcs7_int.h"
#include <random.h>
-#include <nettle/pbkdf2.h>
-#if ENABLE_GOST
-#include "../nettle/gost/pbkdf2-gost.h"
-#endif
/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
@@ -865,32 +861,22 @@ _gnutls_pkcs12_gost_string_to_key(gnutls_mac_algorithm_t algo,
{
uint8_t temp[96];
size_t temp_len = sizeof(temp);
- unsigned int pass_len = 0;
+ gnutls_datum_t key;
+ gnutls_datum_t _salt;
+ int ret;
if (iter == 0)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- if (pass)
- pass_len = strlen(pass);
-
- if (algo == GNUTLS_MAC_GOSTR_94)
- pbkdf2_hmac_gosthash94cp(pass_len, (uint8_t *) pass,
- iter,
- salt_size,
- salt, temp_len, temp);
- else if (algo == GNUTLS_MAC_STREEBOG_256)
- pbkdf2_hmac_streebog256(pass_len, (uint8_t *) pass,
- iter,
- salt_size,
- salt, temp_len, temp);
- else if (algo == GNUTLS_MAC_STREEBOG_512)
- pbkdf2_hmac_streebog512(pass_len, (uint8_t *) pass,
- iter,
- salt_size,
- salt, temp_len, temp);
- else
- /* Should not reach here */
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ key.data = (void *)pass;
+ key.size = pass ? strlen(pass) : 0;
+
+ _salt.data = (void *)salt;
+ _salt.size = salt_size;
+
+ ret = gnutls_pbkdf2(algo, &key, &_salt, iter, temp, temp_len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
memcpy(keybuf, temp + temp_len - req_keylen, req_keylen);
diff --git a/lib/x509/pkcs7-crypt.c b/lib/x509/pkcs7-crypt.c
index 1a4f0370f3..274ac14248 100644
--- a/lib/x509/pkcs7-crypt.c
+++ b/lib/x509/pkcs7-crypt.c
@@ -36,10 +36,6 @@
#include <num.h>
#include <random.h>
#include <pk.h>
-#include <nettle/pbkdf2.h>
-#if ENABLE_GOST
-#include "../nettle/gost/pbkdf2-gost.h"
-#endif
#define PBES1_DES_MD5_OID "1.2.840.113549.1.5.3"
@@ -1112,40 +1108,16 @@ _gnutls_pbes2_string_to_key(unsigned int pass_len, const char *password,
const struct pbkdf2_params *kdf_params,
int key_size, uint8_t *key)
{
- int result = 0;
-
- if (kdf_params->mac == GNUTLS_MAC_SHA1)
- pbkdf2_hmac_sha1(pass_len, (uint8_t *) password,
- kdf_params->iter_count,
- kdf_params->salt_size,
- kdf_params->salt, key_size, key);
- else if (kdf_params->mac == GNUTLS_MAC_SHA256)
- pbkdf2_hmac_sha256(pass_len, (uint8_t *) password,
- kdf_params->iter_count,
- kdf_params->salt_size,
- kdf_params->salt, key_size, key);
-#if ENABLE_GOST
- else if (kdf_params->mac == GNUTLS_MAC_GOSTR_94)
- pbkdf2_hmac_gosthash94cp(pass_len, (uint8_t *) password,
- kdf_params->iter_count,
- kdf_params->salt_size,
- kdf_params->salt, key_size, key);
- else if (kdf_params->mac == GNUTLS_MAC_STREEBOG_256)
- pbkdf2_hmac_streebog256(pass_len, (uint8_t *) password,
- kdf_params->iter_count,
- kdf_params->salt_size,
- kdf_params->salt, key_size, key);
- else if (kdf_params->mac == GNUTLS_MAC_STREEBOG_512)
- pbkdf2_hmac_streebog512(pass_len, (uint8_t *) password,
- kdf_params->iter_count,
- kdf_params->salt_size,
- kdf_params->salt, key_size, key);
-#endif
- else
- result =
- gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
+ gnutls_datum_t _key;
+ gnutls_datum_t salt;
- return result;
+ _key.data = (void *)password;
+ _key.size = pass_len;
+ salt.data = (void *)kdf_params->salt;
+ salt.size = kdf_params->salt_size;
+
+ return gnutls_pbkdf2(kdf_params->mac, &_key, &salt,
+ kdf_params->iter_count, key, key_size);
}
int
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index f23008fbe5..4ffb219759 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -36,7 +36,6 @@
#include <num.h>
#include <random.h>
#include <pk.h>
-#include <nettle/pbkdf2.h>
#include "attributes.h"
#include "prov-seed.h"
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4e12bc802e..764db8c33a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -217,7 +217,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
tls-record-size-limit-asym dh-compute ecdh-compute sign-verify-data-newapi \
sign-verify-newapi sign-verify-deterministic iov aead-cipher-vec \
tls13-without-timeout-func buffer status-request-revoked \
- set_x509_ocsp_multi_cli
+ set_x509_ocsp_multi_cli kdf-api
if HAVE_SECCOMP_TESTS
ctests += dtls-with-seccomp tls-with-seccomp dtls-client-with-seccomp tls-client-with-seccomp
diff --git a/tests/cert-tests/pkcs12-gost b/tests/cert-tests/pkcs12-gost
index 2b5b6bfd79..f7c4bba52b 100755
--- a/tests/cert-tests/pkcs12-gost
+++ b/tests/cert-tests/pkcs12-gost
@@ -29,6 +29,11 @@ if ! test -x "${CERTTOOL}"; then
exit 77
fi
+if test "${GNUTLS_FORCE_FIPS_MODE}" = 1;then
+ echo "Cannot run in FIPS140-2 mode"
+ exit 77
+fi
+
if ! test -z "${VALGRIND}"; then
VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=1"
fi
diff --git a/tests/kdf-api.c b/tests/kdf-api.c
new file mode 100644
index 0000000000..ec74f44ce8
--- /dev/null
+++ b/tests/kdf-api.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2020 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ *
+ */
+
+#include "config.h"
+
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "utils.h"
+
+#define MAX_BUF 1024
+
+static void
+test_hkdf(gnutls_mac_algorithm_t mac,
+ const char *ikm_hex,
+ const char *salt_hex,
+ const char *info_hex,
+ size_t length,
+ const char *prk_hex,
+ const char *okm_hex)
+{
+ gnutls_datum_t hex;
+ gnutls_datum_t ikm;
+ gnutls_datum_t salt;
+ gnutls_datum_t info;
+ gnutls_datum_t prk;
+ gnutls_datum_t okm;
+ uint8_t buf[MAX_BUF];
+
+ success("HKDF test with %s\n", gnutls_mac_get_name(mac));
+
+ /* Test HKDF-Extract */
+ hex.data = (void *)ikm_hex;
+ hex.size = strlen(ikm_hex);
+ assert(gnutls_hex_decode2(&hex, &ikm) >= 0);
+
+ hex.data = (void *)salt_hex;
+ hex.size = strlen(salt_hex);
+ assert(gnutls_hex_decode2(&hex, &salt) >= 0);
+
+ assert(gnutls_hkdf_extract(mac, &ikm, &salt, buf) >= 0);
+ gnutls_free(ikm.data);
+ gnutls_free(salt.data);
+
+ prk.data = buf;
+ prk.size = strlen(prk_hex) / 2;
+ assert(gnutls_hex_encode2(&prk, &hex) >= 0);
+
+ if (strcmp((char *)hex.data, prk_hex))
+ fail("prk doesn't match: %s != %s\n",
+ (char *)hex.data, prk_hex);
+
+ gnutls_free(hex.data);
+
+ /* Test HKDF-Expand */
+ hex.data = (void *)info_hex;
+ hex.size = strlen(info_hex);
+ assert(gnutls_hex_decode2(&hex, &info) >= 0);
+
+ assert(gnutls_hkdf_expand(mac, &prk, &info, buf, length) >= 0);
+ gnutls_free(info.data);
+
+ okm.data = buf;
+ okm.size = strlen(okm_hex) / 2;
+ assert(gnutls_hex_encode2(&okm, &hex) >= 0);
+
+ if (strcmp((char *)hex.data, okm_hex))
+ fail("okm doesn't match: %s != %s\n",
+ (char *)hex.data, okm_hex);
+
+ gnutls_free(hex.data);
+}
+
+static void
+test_pbkdf2(gnutls_mac_algorithm_t mac,
+ const char *ikm_hex,
+ const char *salt_hex,
+ unsigned iter_count,
+ size_t length,
+ const char *okm_hex)
+{
+ gnutls_datum_t hex;
+ gnutls_datum_t ikm;
+ gnutls_datum_t salt;
+ gnutls_datum_t okm;
+ uint8_t buf[MAX_BUF];
+
+ success("PBKDF2 test with %s\n", gnutls_mac_get_name(mac));
+
+ hex.data = (void *)ikm_hex;
+ hex.size = strlen(ikm_hex);
+ assert(gnutls_hex_decode2(&hex, &ikm) >= 0);
+
+ hex.data = (void *)salt_hex;
+ hex.size = strlen(salt_hex);
+ assert(gnutls_hex_decode2(&hex, &salt) >= 0);
+
+ assert(gnutls_pbkdf2(mac, &ikm, &salt, iter_count, buf, length) >= 0);
+ gnutls_free(ikm.data);
+ gnutls_free(salt.data);
+
+ okm.data = buf;
+ okm.size = length;
+ assert(gnutls_hex_encode2(&okm, &hex) >= 0);
+
+ if (strcmp((char *)hex.data, okm_hex))
+ fail("okm doesn't match: %s != %s\n",
+ (char *)hex.data, okm_hex);
+
+ gnutls_free(hex.data);
+}
+
+void
+doit(void)
+{
+ /* Test vector from RFC 5869. More thorough testing is done
+ * in nettle. */
+ test_hkdf(GNUTLS_MAC_SHA256,
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+ "0b0b0b0b0b0b",
+ "000102030405060708090a0b0c",
+ "f0f1f2f3f4f5f6f7f8f9",
+ 42,
+ "077709362c2e32df0ddc3f0dc47bba63"
+ "90b6c73bb50f9c3122ec844ad7c2b3e5",
+ "3cb25f25faacd57a90434f64d0362f2a"
+ "2d2d0a90cf1a5a4c5db02d56ecc4c5bf"
+ "34007208d5b887185865");
+
+ /* Test vector from RFC 6070. More thorough testing is done
+ * in nettle. */
+ test_pbkdf2(GNUTLS_MAC_SHA1,
+ "70617373776f7264", /* "password" */
+ "73616c74", /* "salt" */
+ 4096,
+ 20,
+ "4b007901b765489abead49d926f721d065a429c1");
+}