zeroize_key(&sk, sizeof(sk));
return ret;
}
-#else
+
+#ifdef HAVE_LC_DILITHIUM_PK_FROM_SK
+static int ml_dsa_privkey_to_pubkey(gnutls_pk_algorithm_t algo,
+ const gnutls_datum_t *raw_priv,
+ gnutls_datum_t *raw_pub)
+{
+ int ret;
+ enum lc_dilithium_type type;
+ struct lc_dilithium_sk sk;
+ struct lc_dilithium_pk pk;
+ gnutls_datum_t tmp_raw_pub = { NULL, 0 };
+ uint8_t *ptr;
+ size_t len;
+
+ type = ml_dsa_pk_to_lc_dilithium_type(algo);
+ if (type == LC_DILITHIUM_UNKNOWN)
+ return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
+
+ ret = lc_dilithium_sk_load(&sk, raw_priv->data, raw_priv->size);
+ if (ret < 0 || lc_dilithium_sk_type(&sk) != type) {
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ goto cleanup;
+ }
+
+ ret = lc_dilithium_pk_from_sk(&pk, &sk);
+ if (ret < 0) {
+ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ goto cleanup;
+ }
+
+ ret = lc_dilithium_pk_ptr(&ptr, &len, &pk);
+ if (ret < 0) {
+ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ goto cleanup;
+ }
+
+ ret = _gnutls_set_datum(&tmp_raw_pub, ptr, len);
+ if (ret < 0) {
+ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ goto cleanup;
+ }
+
+ *raw_pub = _gnutls_take_datum(&tmp_raw_pub);
+
+ ret = 0;
+
+cleanup:
+ _gnutls_free_key_datum(&tmp_raw_pub);
+ zeroize_key(&pk, sizeof(pk));
+ zeroize_key(&sk, sizeof(sk));
+ return ret;
+}
+#else /* !HAVE_LC_DILITHIUM_PK_FROM_SK */
+static int ml_dsa_privkey_to_pubkey(gnutls_pk_algorithm_t algo MAYBE_UNUSED,
+ const gnutls_datum_t *raw_priv MAYBE_UNUSED,
+ gnutls_datum_t *raw_pub MAYBE_UNUSED)
+{
+ return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
+}
+#endif
+#else /* !HAVE_LEANCRYPTO */
static int ml_dsa_exists(gnutls_pk_algorithm_t algo MAYBE_UNUSED)
{
return 0;
{
return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
}
+
+static int ml_dsa_privkey_to_pubkey(gnutls_pk_algorithm_t algo MAYBE_UNUSED,
+ const gnutls_datum_t *raw_priv MAYBE_UNUSED,
+ gnutls_datum_t *raw_pub MAYBE_UNUSED)
+{
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
+}
#endif
/* This is the lower-level part of privkey_sign_raw_data().
}
break;
+ case GNUTLS_PK_MLDSA44:
+ case GNUTLS_PK_MLDSA65:
+ case GNUTLS_PK_MLDSA87:
+ if (params->raw_pub.data == NULL) {
+ ret = ml_dsa_privkey_to_pubkey(algo, ¶ms->raw_priv,
+ ¶ms->raw_pub);
+ if (ret < 0) {
+ if (ret == GNUTLS_E_UNIMPLEMENTED_FEATURE) {
+ _gnutls_debug_log(
+ "Deriving public key from an ML-DSA private key is not implemented; ignoring the request\n");
+ return 0;
+ }
+ return gnutls_assert_val(ret);
+ }
+ }
+ break;
+
#ifdef ENABLE_DSA
case GNUTLS_PK_DSA:
if (params->params[DSA_Y] == NULL) {
for format in seed expanded both; do
echo "Testing ML-DSA-$variant ($format)"
- # Check default
- TMPKEYDEFAULT=$testdir/key-$algo-$format-default
TMPKEY=$testdir/key-$algo-$format
- ${VALGRIND} "${CERTTOOL}" -k --no-text --infile "$srcdir/data/key-$algo-$format.pem" >"$TMPKEYDEFAULT"
- if [ $? != 0 ]; then
- cat "$TMPKEYDEFAULT"
- exit 1
- fi
- # The "expandedKey" format doesn't have public key part
- if [ "$format" = seed ] || [ "$format" = both ]; then
- if ! "${DIFF}" "$TMPKEYDEFAULT" "$srcdir/data/key-$algo-both.pem"; then
- exit 1
- fi
- fi
+ # Check certtool --key-info would result in the same output as
+ # "both" for "seed and "both" formats.
+ #
+ # As for "expandedKey" format, it is not possible to recover a
+ # seed, so compare the textual information about public key.
+ case "$format" in
+ seed | both)
+ TMPKEYBODY=$testdir/key-$algo-$format-default
+ ${VALGRIND} "${CERTTOOL}" -k --no-text --infile "$srcdir/data/key-$algo-$format.pem" >"$TMPKEYBODY"
+ if [ $? != 0 ]; then
+ cat "$TMPKEYBODY"
+ exit 1
+ fi
+
+ if ! "${DIFF}" "$TMPKEYBODY" "$srcdir/data/key-$algo-both.pem"; then
+ exit 1
+ fi
+ ;;
+ expandedKey)
+ TMPKEYTEXT=$testdir/key-$algo-$format-text
+ ${VALGRIND} "${CERTTOOL}" -k --infile "$srcdir/data/key-$algo-$format.pem" | sed -n '1,/^-----BEGIN/p' | head -n-1 >"$TMPKEYTEXT"
+ if [ $? != 0 ]; then
+ cat "$TMPKEYTEXT"
+ exit 1
+ fi
+
+ TMPKEYTEXT2=$testdir/key-$algo-both-text
+ ${VALGRIND} "${CERTTOOL}" -k --infile "$srcdir/data/key-$algo-both.pem" | sed -n '1,/^-----BEGIN/p' | head -n-1 >"$TMPKEYTEXT2"
+ if [ $? != 0 ]; then
+ cat "$TMPKEYTEXT2"
+ exit 1
+ fi
+
+ if ! "${DIFF}" "$TMPKEYTEXT" "$TMPKEYTEXT2"; then
+ exit 1
+ fi
+ ;;
+ esac
# Check roundtrip with --key-format
${VALGRIND} "${CERTTOOL}" -k --no-text --key-format "$format" --infile "$srcdir/data/key-$algo-$format.pem" >"$TMPKEY"