Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,25 @@ AS_IF([test "x$with_gnutls" != "xno"],
[with_gnutls=no]
)
AS_IF([test "x$with_gnutls" != "xno"],[with_gnutls="yes"])
AS_IF([test "x$with_gnutls" = "xyes"],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <gnutls/gnutls.h>
#include <stdio.h>
]],
[[
printf("%d", GNUTLS_PK_MLDSA44);
]]
)],
[
AC_MSG_RESULT("GnuTLS has ML-DSA support")
AC_DEFINE_UNQUOTED([GNUTLS_SUPPORTS_MLDSA], 1,
[whether GnuTLS support ML-DSA signing algorithm])
],
[AC_MSG_RESULT("GnuTLS has no ML-DSA support")],
)]
)
]
)

Expand Down
29 changes: 25 additions & 4 deletions src/swtpm_cert/ek-cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
* in section 3.5
*/

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Expand Down Expand Up @@ -984,6 +986,26 @@ static char *get_password(const char *password)
return result;
}

/*
* Get the hash algorithm for signing. TPM 1.2 used SHA1 and TPM 2 SHA256.
* For an ML-DSA signing key only shake-256 is allowed.
*/
static int get_signing_hashalgo(int flags, gnutls_x509_privkey_t sigkey)
{
if (flags & CERT_TYPE_TPM2_F) {
#ifdef GNUTLS_SUPPORTS_MLDSA
int keyalgo = gnutls_x509_privkey_get_pk_algorithm2(sigkey, NULL);

if (keyalgo == GNUTLS_PK_MLDSA44 ||
keyalgo == GNUTLS_PK_MLDSA65 ||
keyalgo == GNUTLS_PK_MLDSA87)
return GNUTLS_DIG_SHAKE_256;
#endif
return GNUTLS_DIG_SHA256;
}
return GNUTLS_DIG_SHA1;
}

static void capabilities_print_json(void)
{
fprintf(stdout,
Expand Down Expand Up @@ -1018,7 +1040,7 @@ main(int argc, char *argv[])
int ecc_y_len = 0;
const char *ecc_curveid = NULL;
gnutls_datum_t datum = { NULL, 0}, out = { NULL, 0};
gnutls_digest_algorithm_t hashAlgo = GNUTLS_DIG_SHA1;
gnutls_digest_algorithm_t hashAlgo;
mpz_t serial;
time_t now;
int err;
Expand Down Expand Up @@ -1261,9 +1283,6 @@ main(int argc, char *argv[])
}
}

if (flags & CERT_TYPE_TPM2_F)
hashAlgo = GNUTLS_DIG_SHA256;

if ((mpz_sizeinbase(serial, 2) + 7) / 8 > sizeof(ser_number) - 1) {
fprintf(stderr, "Serial number is too large.\n");
goto cleanup;
Expand Down Expand Up @@ -1704,6 +1723,8 @@ if (_err != GNUTLS_E_SUCCESS) { \
CHECK_GNUTLS_ERROR(err, "Could not set public EK on CRT: %s\n",
gnutls_strerror(err))

hashAlgo = get_signing_hashalgo(flags, sigkey);

/* sign cert */
if (sigkey) {
err = gnutls_x509_crt_sign2(crt, sigcert, sigkey, hashAlgo, 0);
Expand Down