ENUMS += enums/gnutls_openpgp_crt_status_t
ENUMS += enums/gnutls_params_type_t
ENUMS += enums/gnutls_pin_flag_t
-ENUMS += enums/gnutls_pk_algorithm_t
ENUMS += enums/gnutls_pkcs11_obj_flags
ENUMS += enums/gnutls_pkcs11_obj_info_t
ENUMS += enums/gnutls_pkcs11_obj_type_t
ENUMS += enums/gnutls_sec_param_t
ENUMS += enums/gnutls_server_name_type_t
ENUMS += enums/gnutls_session_flags_t
-ENUMS += enums/gnutls_sign_algorithm_t
ENUMS += enums/gnutls_srtp_profile_t
ENUMS += enums/gnutls_supplemental_data_format_type_t
ENUMS += enums/gnutls_tpmkey_fmt_t
#define IS_KEM(x) \
(((x) == GNUTLS_PK_MLKEM768) || ((x) == GNUTLS_PK_EXP_KYBER768))
+#ifdef HAVE_LIBOQS
+#define IS_DILITHIUM(x) \
+ (((x) == GNUTLS_PK_EXP_DILITHIUM2) || \
+ ((x) == GNUTLS_PK_EXP_DILITHIUM3) || \
+ ((x) == GNUTLS_PK_EXP_DILITHIUM5))
+
+#define IS_FALCON(x) \
+ (((x) == GNUTLS_PK_EXP_FALCON512) || ((x) == GNUTLS_PK_EXP_FALCON1024))
+
+#define IS_SIMPLE_SPHINCS(x) \
+ (((x) == GNUTLS_PK_EXP_SPHINCS_SHA2_128S) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHA2_192S) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHA2_256S) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHAKE_128S) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHAKE_192S) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHAKE_256S))
+
+#define IS_FAST_SPHINCS(x) \
+ (((x) == GNUTLS_PK_EXP_SPHINCS_SHA2_128F) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHA2_192F) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHA2_256F) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHAKE_128F) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHAKE_192F) || \
+ ((x) == GNUTLS_PK_EXP_SPHINCS_SHAKE_256F))
+
+#define IS_SPHINCS(x) (IS_SIMPLE_SPHINCS(x) || IS_FAST_SPHINCS(x))
+#endif
+
#define SIG_SEM_PRE_TLS12 (1 << 1)
#define SIG_SEM_TLS13 (1 << 2)
#define SIG_SEM_DEFAULT (SIG_SEM_PRE_TLS12 | SIG_SEM_TLS13)
.oid = NULL,
.id = GNUTLS_PK_EXP_KYBER768,
.curve = GNUTLS_ECC_CURVE_INVALID },
+ { .name = "Dilithium2",
+ .oid = DILITHIUM2_OID,
+ .id = GNUTLS_PK_EXP_DILITHIUM2,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Dilithium3",
+ .oid = DILITHIUM3_OID,
+ .id = GNUTLS_PK_EXP_DILITHIUM3,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Dilithium5",
+ .oid = DILITHIUM5_OID,
+ .id = GNUTLS_PK_EXP_DILITHIUM5,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Falcon512",
+ .oid = FALCON512_OID,
+ .id = GNUTLS_PK_EXP_FALCON512,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Falcon1024",
+ .oid = FALCON1024_OID,
+ .id = GNUTLS_PK_EXP_FALCON1024,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Falcon512",
+ .oid = FALCON512_OID,
+ .id = GNUTLS_PK_EXP_FALCON512,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Falcon1024",
+ .oid = FALCON1024_OID,
+ .id = GNUTLS_PK_EXP_FALCON1024,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHA2 128F",
+ .oid = SPHINCS_SHA2_128F_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHA2_128F,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHA2 128S",
+ .oid = SPHINCS_SHA2_128S_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHA2_128S,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHA2 192F",
+ .oid = SPHINCS_SHA2_192F_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHA2_192F,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHA2 192S",
+ .oid = SPHINCS_SHA2_192S_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHA2_192S,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHA2 256F",
+ .oid = SPHINCS_SHA2_256F_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHA2_256F,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHA2 256S",
+ .oid = SPHINCS_SHA2_256S_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHA2_256S,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHAKE 128F",
+ .oid = SPHINCS_SHAKE_128F_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHAKE_128F,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHAKE 128S",
+ .oid = SPHINCS_SHAKE_128S_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHAKE_128S,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHAKE 192F",
+ .oid = SPHINCS_SHAKE_192F_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHAKE_192F,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHAKE 192S",
+ .oid = SPHINCS_SHAKE_192S_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHAKE_192S,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHAKE 256F",
+ .oid = SPHINCS_SHAKE_256F_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHAKE_256F,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
+ { .name = "Sphincs SHAKE 256S",
+ .oid = SPHINCS_SHAKE_256S_OID,
+ .id = GNUTLS_PK_EXP_SPHINCS_SHAKE_256S,
+ .curve = GNUTLS_ECC_CURVE_INVALID,
+ .no_prehashed = 1 },
#endif
{ .name = "UNKNOWN",
.oid = NULL,
*/
unsigned int subgroup_bits; /* subgroup bits */
unsigned int ecc_bits; /* bits for ECC keys */
+#ifdef HAVE_LIBOQS
+ unsigned int dilithium_bits;
+ unsigned int falcon_bits;
+ unsigned int sphincs_bits;
+#endif
} gnutls_sec_params_entry;
static const gnutls_sec_params_entry sec_params[] = {
- { "Insecure", GNUTLS_SEC_PARAM_INSECURE, 0, 0, 0, 0, 0 },
- { "Export", GNUTLS_SEC_PARAM_EXPORT, 42, 512, 0, 84, 0 },
- { "Very weak", GNUTLS_SEC_PARAM_VERY_WEAK, 64, 767, 0, 128, 0 },
- { "Weak", GNUTLS_SEC_PARAM_WEAK, 72, 1008, 1008, 160, 160 },
+ { "Insecure", GNUTLS_SEC_PARAM_INSECURE, 0, 0, 0, 0, 0,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ },
+ { "Export", GNUTLS_SEC_PARAM_EXPORT, 42, 512, 0, 84, 0,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ },
+ { "Very weak", GNUTLS_SEC_PARAM_VERY_WEAK, 64, 767, 0, 128, 0,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ },
+ { "Weak", GNUTLS_SEC_PARAM_WEAK, 72, 1008, 1008, 160, 160,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ },
#ifdef ENABLE_FIPS140
- { "Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160 },
- { "Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1024, 1024, 192, 192 },
- { "Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 224, 224 },
- { "High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256 },
+ { "Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ },
+ { "Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1024, 1024, 192, 192,
+#ifdef HAVE_LIBOQS
+ 0, 897, 32
+#endif
+ },
+ { "Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 224, 224,
+#ifdef HAVE_LIBOQS
+ 1312, 0, 0
+#endif
+ },
+ { "High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256,
+#ifdef HAVE_LIBOQS
+ 0, 0, 48
+#endif
+ },
#else
- { "Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160,
- 160 }, /* ENISA-LEGACY */
- { "Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1776, 2048, 192, 192 },
- { "Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 256, 224 },
- { "High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256 },
-#endif
- { "Ultra", GNUTLS_SEC_PARAM_ULTRA, 192, 8192, 8192, 384, 384 },
- { "Future", GNUTLS_SEC_PARAM_FUTURE, 256, 15360, 15360, 512, 512 },
- { NULL, 0, 0, 0, 0, 0 }
+ { "Low", GNUTLS_SEC_PARAM_LOW, 80, 1024, 1024, 160, 160,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ }, /* ENISA-LEGACY */
+ { "Legacy", GNUTLS_SEC_PARAM_LEGACY, 96, 1776, 2048, 192, 192,
+#ifdef HAVE_LIBOQS
+ 0, 897, 32
+#endif
+ },
+ { "Medium", GNUTLS_SEC_PARAM_MEDIUM, 112, 2048, 2048, 256, 224,
+#ifdef HAVE_LIBOQS
+ 1312, 0, 0
+#endif
+ },
+ { "High", GNUTLS_SEC_PARAM_HIGH, 128, 3072, 3072, 256, 256,
+#ifdef HAVE_LIBOQS
+ 0, 0, 48
+#endif
+ },
+#endif
+ { "Ultra", GNUTLS_SEC_PARAM_ULTRA, 192, 8192, 8192, 384, 384,
+#ifdef HAVE_LIBOQS
+ 1952, 0, 0
+#endif
+ },
+ { "Future", GNUTLS_SEC_PARAM_FUTURE, 256, 15360, 15360, 512, 512,
+#ifdef HAVE_LIBOQS
+ 2592, 1793, 64
+#endif
+ },
+ { NULL, 0, 0, 0, 0,
+#ifdef HAVE_LIBOQS
+ 0, 0, 0
+#endif
+ }
};
/**
ret = p->dsa_bits;
else if (IS_EC(algo) || IS_GOSTEC(algo))
ret = p->ecc_bits;
+#ifdef HAVE_LIBOQS
+ else if (IS_DILITHIUM(algo))
+ ret = p->dilithium_bits;
+ else if (IS_FALCON(algo))
+ ret = p->falcon_bits;
+ else if (IS_SPHINCS(algo))
+ ret = p->sphincs_bits;
+#endif
else
ret = p->pk_bits;
break;
break;
ret = p->sec_param;
}
+#ifdef HAVE_LIBOQS
+ } else if (IS_DILITHIUM(algo)) {
+ for (p = sec_params; p->name; p++) {
+ if (p->dilithium_bits > bits)
+ break;
+ ret = p->sec_param;
+ }
+ } else if (IS_FALCON(algo)) {
+ for (p = sec_params; p->name; p++) {
+ if (p->falcon_bits > bits)
+ break;
+ ret = p->sec_param;
+ }
+ } else if (IS_SPHINCS(algo)) {
+ for (p = sec_params; p->name; p++) {
+ if (p->sphincs_bits > bits)
+ break;
+ ret = p->sec_param;
+ }
+#endif
} else {
for (p = sec_params; p->name; p++) {
if (p->pk_bits > bits)
.pk = GNUTLS_PK_DSA,
.hash = GNUTLS_DIG_SHA512,
.aid = TLS_SIGN_AID_UNKNOWN },
-
+#ifdef HAVE_LIBOQS
+ { .name = "Dilithium2",
+ .oid = DILITHIUM2_OID,
+ .id = GNUTLS_SIGN_EXP_DILITHIUM2,
+ .pk = GNUTLS_PK_EXP_DILITHIUM2,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Dilithium3",
+ .oid = DILITHIUM3_OID,
+ .id = GNUTLS_SIGN_EXP_DILITHIUM3,
+ .pk = GNUTLS_PK_EXP_DILITHIUM3,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Dilithium5",
+ .oid = DILITHIUM5_OID,
+ .id = GNUTLS_SIGN_EXP_DILITHIUM5,
+ .pk = GNUTLS_PK_EXP_DILITHIUM5,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Falcon512",
+ .oid = FALCON512_OID,
+ .id = GNUTLS_SIGN_EXP_FALCON512,
+ .pk = GNUTLS_PK_EXP_FALCON512,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Falcon1024",
+ .oid = FALCON1024_OID,
+ .id = GNUTLS_SIGN_EXP_FALCON1024,
+ .pk = GNUTLS_PK_EXP_FALCON1024,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHA2-128F",
+ .oid = SPHINCS_SHA2_128F_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHA2_128F,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHA2_128F,
+ .hash = GNUTLS_DIG_SHA256, //
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHA2-128S",
+ .oid = SPHINCS_SHA2_128S_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHA2_128S,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHA2_128S,
+ .hash = GNUTLS_DIG_SHA256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHA2-192F",
+ .oid = SPHINCS_SHA2_192F_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHA2_192F,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHA2_192F,
+ .hash = GNUTLS_DIG_SHA256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHA2-192S",
+ .oid = SPHINCS_SHA2_192S_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHA2_192S,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHA2_192S,
+ .hash = GNUTLS_DIG_SHA256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHA2-256F",
+ .oid = SPHINCS_SHA2_256F_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHA2_256F,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHA2_256F,
+ .hash = GNUTLS_DIG_SHA256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHA2-256S",
+ .oid = SPHINCS_SHA2_256S_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHA2_256S,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHA2_256S,
+ .hash = GNUTLS_DIG_SHA256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHAKE-128F",
+ .oid = SPHINCS_SHAKE_128F_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_128F,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHAKE_128F,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHAKE-128S",
+ .oid = SPHINCS_SHAKE_128S_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_128S,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHAKE_128S,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHAKE-192F",
+ .oid = SPHINCS_SHAKE_192F_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_192F,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHAKE_192F,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHAKE-192S",
+ .oid = SPHINCS_SHAKE_192S_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_192S,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHAKE_192S,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHAKE-256F",
+ .oid = SPHINCS_SHAKE_256F_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_256F,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHAKE_256F,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+ { .name = "Sphincs-SHAKE-256S",
+ .oid = SPHINCS_SHAKE_256S_OID,
+ .id = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_256S,
+ .pk = GNUTLS_PK_EXP_SPHINCS_SHAKE_256S,
+ .hash = GNUTLS_DIG_SHAKE_256,
+ .aid = TLS_SIGN_AID_UNKNOWN },
+#endif
{ .name = 0,
.oid = 0,
.id = 0,
#define RSA_PRIVATE_PARAMS 8
#define ECC_PRIVATE_PARAMS 3
#define GOST_PRIVATE_PARAMS 3
+#ifdef HAVE_LIBOQS
+#define DILITHIUM_PRIVATE_PARAMS 4
+#define FALCON_PRIVATE_PARAMS 4
+#define SPHINCS_PRIVATE_PARAMS 4
+#endif
#if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
#error INCREASE MAX_PRIV_PARAMS
VOID_FUNC(void, OQS_SHA2_set_callbacks, (struct OQS_SHA2_callbacks *new_callbacks), (new_callbacks))
VOID_FUNC(void, OQS_SHA3_set_callbacks, (struct OQS_SHA3_callbacks *new_callbacks), (new_callbacks))
VOID_FUNC(void, OQS_SHA3_x4_set_callbacks, (struct OQS_SHA3_x4_callbacks *new_callbacks), (new_callbacks))
+FUNC(const char *, OQS_version, (void), ())
+FUNC(OQS_SIG *, OQS_SIG_new, (const char *method_name), (method_name))
+FUNC(OQS_STATUS, OQS_SIG_keypair, (const OQS_SIG* sig, uint8_t* public_key, uint8_t *secret_key), (sig, public_key, secret_key))
+FUNC(OQS_STATUS, OQS_SIG_sign, (const OQS_SIG* sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t* secret_key), (sig, signature, signature_len, message, message_len, secret_key))
+FUNC(OQS_STATUS, OQS_SIG_verify, (const OQS_SIG* sig, const uint8_t *message, size_t message_len, uint8_t *signature, size_t signature_len, const uint8_t* public_key), (sig, message, message_len, signature, signature_len, public_key))
+VOID_FUNC(void, OQS_SIG_free, (OQS_SIG *sig), (sig))
privkey OCTET STRING
}
+DilithiumPrivateKey ::= SEQUENCE {
+ version INTEGER,
+ privateKeyAlgorithm AlgorithmIdentifier,
+ privateKey OCTET STRING,
+ publicKey [1] OCTET STRING OPTIONAL
+}
+
+FalconPrivateKey ::= SEQUENCE {
+ version INTEGER,
+ privateKeyAlgorithm AlgorithmIdentifier,
+ privateKey OCTET STRING,
+ publicKey [1] OCTET STRING OPTIONAL
+}
+
+SphincsPrivateKey ::= SEQUENCE {
+ version INTEGER,
+ privateKeyAlgorithm AlgorithmIdentifier,
+ privateKey OCTET STRING,
+ publicKey [1] OCTET STRING OPTIONAL
+}
+
END
GNUTLS_PK_MAX = GNUTLS_PK_MLKEM768,
/* Experimental algorithms */
- GNUTLS_PK_EXP_KYBER768 = 256,
- GNUTLS_PK_EXP_MIN = GNUTLS_PK_EXP_KYBER768,
- GNUTLS_PK_EXP_MAX = GNUTLS_PK_EXP_KYBER768
+ GNUTLS_PK_EXP_MIN = 256,
+ GNUTLS_PK_EXP_KYBER768 = GNUTLS_PK_EXP_MIN + 0,
+ GNUTLS_PK_EXP_DILITHIUM2 = GNUTLS_PK_EXP_MIN + 1,
+ GNUTLS_PK_EXP_DILITHIUM3 = GNUTLS_PK_EXP_MIN + 2,
+ GNUTLS_PK_EXP_DILITHIUM5 = GNUTLS_PK_EXP_MIN + 3,
+ GNUTLS_PK_EXP_FALCON512 = GNUTLS_PK_EXP_MIN + 4,
+ GNUTLS_PK_EXP_FALCON1024 = GNUTLS_PK_EXP_MIN + 5,
+ GNUTLS_PK_EXP_SPHINCS_SHA2_128F = GNUTLS_PK_EXP_MIN + 6,
+ GNUTLS_PK_EXP_SPHINCS_SHA2_128S = GNUTLS_PK_EXP_MIN + 7,
+ GNUTLS_PK_EXP_SPHINCS_SHA2_192F = GNUTLS_PK_EXP_MIN + 8,
+ GNUTLS_PK_EXP_SPHINCS_SHA2_192S = GNUTLS_PK_EXP_MIN + 9,
+ GNUTLS_PK_EXP_SPHINCS_SHA2_256F = GNUTLS_PK_EXP_MIN + 10,
+ GNUTLS_PK_EXP_SPHINCS_SHA2_256S = GNUTLS_PK_EXP_MIN + 11,
+ GNUTLS_PK_EXP_SPHINCS_SHAKE_128F = GNUTLS_PK_EXP_MIN + 12,
+ GNUTLS_PK_EXP_SPHINCS_SHAKE_128S = GNUTLS_PK_EXP_MIN + 13,
+ GNUTLS_PK_EXP_SPHINCS_SHAKE_192F = GNUTLS_PK_EXP_MIN + 14,
+ GNUTLS_PK_EXP_SPHINCS_SHAKE_192S = GNUTLS_PK_EXP_MIN + 15,
+ GNUTLS_PK_EXP_SPHINCS_SHAKE_256F = GNUTLS_PK_EXP_MIN + 16,
+ GNUTLS_PK_EXP_SPHINCS_SHAKE_256S = GNUTLS_PK_EXP_MIN + 17,
+ GNUTLS_PK_EXP_MAX = GNUTLS_PK_EXP_SPHINCS_SHAKE_256S
} gnutls_pk_algorithm_t;
const char *gnutls_pk_algorithm_get_name(gnutls_pk_algorithm_t algorithm);
GNUTLS_SIGN_GOST_256 = 44,
GNUTLS_SIGN_GOST_512 = 45,
GNUTLS_SIGN_EDDSA_ED448 = 46,
- GNUTLS_SIGN_MAX = GNUTLS_SIGN_EDDSA_ED448
+ GNUTLS_SIGN_MAX = GNUTLS_SIGN_EDDSA_ED448,
+
+ GNUTLS_SIGN_EXP_MIN = 256,
+ GNUTLS_SIGN_EXP_DILITHIUM2 = GNUTLS_SIGN_EXP_MIN + 0,
+ GNUTLS_SIGN_EXP_DILITHIUM3 = GNUTLS_SIGN_EXP_MIN + 1,
+ GNUTLS_SIGN_EXP_DILITHIUM5 = GNUTLS_SIGN_EXP_MIN + 2,
+ GNUTLS_SIGN_EXP_FALCON512 = GNUTLS_SIGN_EXP_MIN + 3,
+ GNUTLS_SIGN_EXP_FALCON1024 = GNUTLS_SIGN_EXP_MIN + 4,
+ GNUTLS_SIGN_EXP_SPHINCS_SHA2_128F = GNUTLS_SIGN_EXP_MIN + 5,
+ GNUTLS_SIGN_EXP_SPHINCS_SHA2_128S = GNUTLS_SIGN_EXP_MIN + 6,
+ GNUTLS_SIGN_EXP_SPHINCS_SHA2_192F = GNUTLS_SIGN_EXP_MIN + 7,
+ GNUTLS_SIGN_EXP_SPHINCS_SHA2_192S = GNUTLS_SIGN_EXP_MIN + 8,
+ GNUTLS_SIGN_EXP_SPHINCS_SHA2_256F = GNUTLS_SIGN_EXP_MIN + 9,
+ GNUTLS_SIGN_EXP_SPHINCS_SHA2_256S = GNUTLS_SIGN_EXP_MIN + 10,
+ GNUTLS_SIGN_EXP_SPHINCS_SHAKE_128F = GNUTLS_SIGN_EXP_MIN + 11,
+ GNUTLS_SIGN_EXP_SPHINCS_SHAKE_128S = GNUTLS_SIGN_EXP_MIN + 12,
+ GNUTLS_SIGN_EXP_SPHINCS_SHAKE_192F = GNUTLS_SIGN_EXP_MIN + 13,
+ GNUTLS_SIGN_EXP_SPHINCS_SHAKE_192S = GNUTLS_SIGN_EXP_MIN + 14,
+ GNUTLS_SIGN_EXP_SPHINCS_SHAKE_256F = GNUTLS_SIGN_EXP_MIN + 15,
+ GNUTLS_SIGN_EXP_SPHINCS_SHAKE_256S = GNUTLS_SIGN_EXP_MIN + 16,
+ GNUTLS_SIGN_EXP_MAX = GNUTLS_SIGN_EXP_SPHINCS_SHAKE_256S,
} gnutls_sign_algorithm_t;
/**
}
}
+#ifdef HAVE_LIBOQS
+static inline const char *convert_to_oqs_alg(gnutls_pk_algorithm_t algo)
+{
+ switch (algo) {
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ return OQS_SIG_alg_dilithium_2;
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ return OQS_SIG_alg_dilithium_3;
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ return OQS_SIG_alg_dilithium_5;
+ case GNUTLS_PK_EXP_FALCON512:
+ return OQS_SIG_alg_falcon_512;
+ case GNUTLS_PK_EXP_FALCON1024:
+ return OQS_SIG_alg_falcon_1024;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ return OQS_SIG_alg_sphincs_sha2_128f_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ return OQS_SIG_alg_sphincs_sha2_128s_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ return OQS_SIG_alg_sphincs_sha2_192f_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ return OQS_SIG_alg_sphincs_sha2_192s_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ return OQS_SIG_alg_sphincs_sha2_256f_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ return OQS_SIG_alg_sphincs_sha2_256s_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ return OQS_SIG_alg_sphincs_shake_128f_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ return OQS_SIG_alg_sphincs_shake_128s_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ return OQS_SIG_alg_sphincs_shake_192f_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ return OQS_SIG_alg_sphincs_shake_192s_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ return OQS_SIG_alg_sphincs_shake_256f_simple;
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ return OQS_SIG_alg_sphincs_shake_256s_simple;
+ default:
+ gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
+ return "";
+ }
+}
+#endif
+
/* This is the lower-level part of privkey_sign_raw_data().
*
* It accepts data in the appropriate hash form, i.e., DigestInfo
break;
}
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S: {
+ OQS_SIG *sig;
+ OQS_STATUS rc;
+ size_t size;
+
+ sig = GNUTLS_OQS_FUNC(OQS_SIG_new)(convert_to_oqs_alg(algo));
+ if (sig == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto oqs_fail;
+ }
+
+ size = sig->length_signature;
+ signature->data = gnutls_malloc(size);
+
+ rc = GNUTLS_OQS_FUNC(OQS_SIG_sign)(sig, signature->data, &size,
+ vdata->data, vdata->size,
+ pk_params->raw_priv.data);
+ if (rc != OQS_SUCCESS) {
+ ret = gnutls_assert_val(GNUTLS_E_PK_SIGN_FAILED);
+ goto oqs_fail;
+ }
+
+ signature->size = size;
+
+ ret = GNUTLS_E_SUCCESS;
+
+ oqs_fail:
+ GNUTLS_OQS_FUNC(OQS_SIG_free)(sig);
+ if (ret < 0)
+ goto cleanup;
+ break;
+ }
+#endif
default:
gnutls_assert();
ret = GNUTLS_E_INTERNAL_ERROR;
break;
}
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S: {
+ OQS_SIG *sig;
+ OQS_STATUS rc;
+
+ sig = GNUTLS_OQS_FUNC(OQS_SIG_new)(convert_to_oqs_alg(algo));
+ if (sig == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto oqs_fail;
+ }
+
+ rc = GNUTLS_OQS_FUNC(OQS_SIG_verify)(
+ sig, vdata->data, vdata->size, signature->data,
+ signature->size, pk_params->raw_pub.data);
+ if (rc != OQS_SUCCESS) {
+ ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
+ goto oqs_fail;
+ }
+
+ ret = GNUTLS_E_SUCCESS;
+
+ oqs_fail:
+ GNUTLS_OQS_FUNC(OQS_SIG_free)(sig);
+ if (ret < 0)
+ goto cleanup;
+ break;
+ }
+#endif
default:
gnutls_assert();
ret = GNUTLS_E_INTERNAL_ERROR;
case GNUTLS_PK_GOST_12_512:
#endif
case GNUTLS_PK_MLKEM768:
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
break;
default:
gnutls_assert();
return ret;
}
+#ifdef HAVE_LIBOQS
+static inline int pqc_alg_prepare_key_containers(OQS_SIG *sig,
+ gnutls_pk_params_st *params)
+{
+ params->raw_priv.size = sig->length_secret_key;
+ params->raw_priv.data =
+ gnutls_malloc(params->raw_priv.size + sig->length_public_key);
+
+ if (params->raw_priv.data == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ params->raw_pub.size = sig->length_public_key;
+ params->raw_pub.data = gnutls_malloc(params->raw_pub.size);
+
+ if (params->raw_pub.data == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ return GNUTLS_E_SUCCESS;
+}
+#endif
+
/* To generate a DH key either q must be set in the params or
* level should be set to the number of required bits.
*/
ret = 0;
break;
}
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ if (params->pkflags & GNUTLS_PK_FLAG_PROVABLE)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ {
+ OQS_SIG *sig = NULL;
+ OQS_STATUS rc;
+
+ if (_gnutls_liboqs_ensure() < 0) {
+ ret = gnutls_assert_val(
+ GNUTLS_E_UNKNOWN_PK_ALGORITHM);
+ goto cleanup;
+ }
+
+ not_approved = true;
+
+ sig = GNUTLS_OQS_FUNC(OQS_SIG_new)(
+ convert_to_oqs_alg(algo));
+ if (sig == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto cleanup;
+ }
+
+ ret = pqc_alg_prepare_key_containers(sig, params);
+ if (ret < 0)
+ goto oqs_fail;
+
+ rc = GNUTLS_OQS_FUNC(
+ OQS_SIG_keypair)(sig, params->raw_pub.data,
+ params->raw_priv.data);
+ if (rc != OQS_SUCCESS) {
+ ret = gnutls_assert_val(
+ GNUTLS_E_INTERNAL_ERROR);
+ goto oqs_fail;
+ }
+
+ memcpy(¶ms->raw_priv.data[sig->length_secret_key],
+ params->raw_pub.data, sig->length_public_key);
+
+ ret = GNUTLS_E_SUCCESS;
+
+ oqs_fail:
+ GNUTLS_OQS_FUNC(OQS_SIG_free)(sig);
+
+ if (ret < 0)
+ goto cleanup;
+
+ break;
+ }
#endif
default:
gnutls_assert();
ret = 0;
break;
}
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ ret = 0;
+ break;
#endif
#if ENABLE_GOST
case GNUTLS_PK_GOST_01:
case GNUTLS_PK_EDDSA_ED448:
case GNUTLS_PK_ECDH_X25519:
case GNUTLS_PK_ECDH_X448:
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+#endif
ret = _gnutls_set_datum(&pub->raw_pub, priv->raw_pub.data,
priv->raw_pub.size);
if (ret < 0)
#include "urls.h"
#include "ecc.h"
+#ifdef HAVE_LIBOQS
+#include <oqs/oqs.h>
+#endif
+
static int pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
const mac_entry_st *me,
const gnutls_datum_t *hash,
static int pubkey_supports_sig(gnutls_pubkey_t pubkey,
const gnutls_sign_entry_st *se);
+#ifdef HAVE_LIBOQS
+struct OQS_alg_pubkey_bits {
+ gnutls_pk_algorithm_t algorithm;
+ int pubkey_bits;
+};
+
+struct OQS_alg_pubkey_bits pqc_pubkey_bits[] = {
+#if defined(GNUTLS_PK_EXP_DILITHIUM2) && \
+ defined(OQS_SIG_dilithium_2_length_public_key)
+ { GNUTLS_PK_EXP_DILITHIUM2, OQS_SIG_dilithium_2_length_public_key },
+#endif
+#if defined(GNUTLS_PK_EXP_DILITHIUM3) && \
+ defined(OQS_SIG_dilithium_3_length_public_key)
+ { GNUTLS_PK_EXP_DILITHIUM3, OQS_SIG_dilithium_3_length_public_key },
+#endif
+#if defined(GNUTLS_PK_EXP_DILITHIUM5) && \
+ defined(OQS_SIG_dilithium_5_length_public_key)
+ { GNUTLS_PK_EXP_DILITHIUM5, OQS_SIG_dilithium_5_length_public_key },
+#endif
+ { GNUTLS_PK_EXP_FALCON512, OQS_SIG_falcon_512_length_public_key },
+ { GNUTLS_PK_EXP_FALCON1024, OQS_SIG_falcon_1024_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_128F,
+ OQS_SIG_sphincs_sha2_128f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_128S,
+ OQS_SIG_sphincs_sha2_128s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_192F,
+ OQS_SIG_sphincs_sha2_192f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_192S,
+ OQS_SIG_sphincs_sha2_192s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_256F,
+ OQS_SIG_sphincs_sha2_256f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_256S,
+ OQS_SIG_sphincs_sha2_256s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_128F,
+ OQS_SIG_sphincs_shake_128f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_128S,
+ OQS_SIG_sphincs_shake_128s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_192F,
+ OQS_SIG_sphincs_shake_192f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_192S,
+ OQS_SIG_sphincs_shake_192s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_256F,
+ OQS_SIG_sphincs_shake_256f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_256S,
+ OQS_SIG_sphincs_shake_256s_simple_length_public_key },
+
+ { GNUTLS_PK_UNKNOWN, 0 }
+};
+
+static int pqc_pubkey_to_bits(gnutls_pk_algorithm_t algo)
+{
+ struct OQS_alg_pubkey_bits *pubkey_to_bits = pqc_pubkey_bits;
+ while (pubkey_to_bits->algorithm != algo &&
+ pubkey_to_bits->algorithm != GNUTLS_PK_UNKNOWN)
+ pubkey_to_bits++;
+
+ if (pubkey_to_bits->algorithm == GNUTLS_PK_UNKNOWN)
+ gnutls_assert();
+
+ return pubkey_to_bits->pubkey_bits;
+}
+#endif
+
unsigned pubkey_to_bits(const gnutls_pk_params_st *params)
{
switch (params->algo) {
case GNUTLS_PK_GOST_12_256:
case GNUTLS_PK_GOST_12_512:
return gnutls_ecc_curve_get_size(params->curve) * 8;
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ return pqc_pubkey_to_bits(params->algo);
+#endif
default:
return 0;
}
pubkey_to_bits(&key->params));
ret = 0;
break;
-
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ if (hash)
+ *hash = GNUTLS_DIG_SHAKE_256;
+ ret = 0;
+ break;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ if (hash)
+ *hash = GNUTLS_DIG_SHA256;
+ ret = 0;
+ break;
+#endif
default:
gnutls_assert();
ret = GNUTLS_E_INTERNAL_ERROR;
case GNUTLS_PK_EDDSA_ED25519:
case GNUTLS_PK_EDDSA_ED448:
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+#endif
if (_gnutls_pk_verify(se->pk, data, signature, params,
sign_params) != 0) {
gnutls_assert();
#define GOST28147_89_CPC_OID "1.2.643.2.2.31.3"
#define GOST28147_89_CPD_OID "1.2.643.2.2.31.4"
+#ifdef HAVE_LIBOQS
+#define DILITHIUM2_OID "1.3.6.1.4.1.2.267.7.4.4"
+#define DILITHIUM3_OID "1.3.6.1.4.1.2.267.7.5.4"
+#define DILITHIUM5_OID "1.3.6.1.4.1.2.267.7.6.4"
+
+#define FALCON512_OID "1.3.9999.3.1"
+#define FALCON1024_OID "1.3.9999.3.4"
+
+#define SPHINCS_SHA2_128F_OID "1.3.9999.6.4.1"
+#define SPHINCS_SHA2_128S_OID "1.3.9999.6.4.2"
+#define SPHINCS_SHA2_192F_OID "1.3.9999.6.5.1"
+#define SPHINCS_SHA2_192S_OID "1.3.9999.6.5.2"
+#define SPHINCS_SHA2_256F_OID "1.3.9999.6.6.1"
+#define SPHINCS_SHA2_256S_OID "1.3.9999.6.6.2"
+#define SPHINCS_SHAKE_128F_OID "1.3.9999.6.7.1"
+#define SPHINCS_SHAKE_128S_OID "1.3.9999.6.7.2"
+#define SPHINCS_SHAKE_192F_OID "1.3.9999.6.8.1"
+#define SPHINCS_SHAKE_192S_OID "1.3.9999.6.8.2"
+#define SPHINCS_SHAKE_256F_OID "1.3.9999.6.9.1"
+#define SPHINCS_SHAKE_256S_OID "1.3.9999.6.9.2"
+#endif
+
#define ASN1_NULL "\x05\x00"
#define ASN1_NULL_SIZE 2
params->params_nr = GOST_PUBLIC_PARAMS;
}
break;
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ ret = _gnutls_set_datum(¶ms->raw_pub, der, dersize);
+ break;
+#endif
default:
ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
break;
case GNUTLS_PK_GOST_01:
case GNUTLS_PK_GOST_12_256:
case GNUTLS_PK_GOST_12_512:
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+#endif
return 0;
default:
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
return ret;
}
+#ifdef HAVE_LIBOQS
+static int _gnutls_x509_write_pqc_alg_pubkey(const gnutls_pk_params_st *params,
+ gnutls_datum_t *raw)
+{
+ int ret;
+
+ raw->data = NULL;
+ raw->size = 0;
+
+ if (params->raw_pub.size == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret = _gnutls_set_datum(raw, params->raw_pub.data,
+ params->raw_pub.size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return 0;
+}
+#endif
+
int _gnutls_x509_write_pubkey_params(const gnutls_pk_params_st *params,
gnutls_datum_t *der)
{
case GNUTLS_PK_EDDSA_ED448:
case GNUTLS_PK_ECDH_X25519:
case GNUTLS_PK_ECDH_X448:
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+#endif
der->data = NULL;
der->size = 0;
case GNUTLS_PK_GOST_12_256:
case GNUTLS_PK_GOST_12_512:
return _gnutls_x509_write_gost_pubkey(params, der);
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ return _gnutls_x509_write_pqc_alg_pubkey(params, der);
+#endif
default:
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
}
return ret;
}
+#ifdef HAVE_LIBOQS
+static int _gnutls_asn1_encode_pqc_alg(asn1_node *c2,
+ gnutls_pk_params_st *params,
+ const char *oid, uint8_t version)
+{
+ int ret;
+
+ if ((ret = asn1_write_value(*c2, "version", &version, 1)) !=
+ ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(ret);
+ }
+
+ if ((ret = asn1_write_value(*c2, "privateKeyAlgorithm.algorithm", oid,
+ 1)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(ret);
+ }
+
+ if ((ret = asn1_write_value(*c2, "privateKeyAlgorithm.parameters", NULL,
+ 0)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(ret);
+ }
+
+ if (params->raw_pub.size == 0 || params->raw_priv.size == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret = asn1_write_value(*c2, "privateKey", params->raw_priv.data,
+ params->raw_priv.size);
+ if (ret != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(ret);
+ }
+
+ ret = asn1_write_value(*c2, "publicKey", params->raw_pub.data,
+ params->raw_pub.size);
+ if (ret != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(ret);
+ }
+
+ return GNUTLS_E_SUCCESS;
+}
+
+static uint8_t _gnutls_get_pqc_alg_version(gnutls_pk_params_st *params)
+{
+ switch (params->algo) {
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ return '\x02';
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ return '\x03';
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ return '\x05';
+ case GNUTLS_PK_EXP_FALCON512:
+ return '\x01';
+ case GNUTLS_PK_EXP_FALCON1024:
+ return '\x02';
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ return '\x01';
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ return '\x02';
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ return '\x03';
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ return '\x04';
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ return '\x05';
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ return '\x06';
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ return '\x07';
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ return '\x08';
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ return '\x09';
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ return '\x0a';
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ return '\x0b';
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ return '\x0c';
+ default:
+ return '\x00';
+ }
+}
+
+static int _gnutls_asn1_encode_dilithium(asn1_node *c2,
+ gnutls_pk_params_st *params)
+{
+ int ret;
+ const char *oid;
+
+ oid = gnutls_pk_get_oid(params->algo);
+ if (oid == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ /* first make sure that no previously allocated data are leaked */
+ if (*c2 != NULL) {
+ asn1_delete_structure(c2);
+ *c2 = NULL;
+ }
+
+ if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.DilithiumPrivateKey", c2)) !=
+ ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+ }
+
+ ret = _gnutls_asn1_encode_pqc_alg(c2, params, oid,
+ _gnutls_get_pqc_alg_version(params));
+ if (ret < 0)
+ goto cleanup;
+
+ return GNUTLS_E_SUCCESS;
+
+cleanup:
+ asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
+
+ return ret;
+}
+
+static int _gnutls_asn1_encode_falcon(asn1_node *c2,
+ gnutls_pk_params_st *params)
+{
+ int ret;
+ const char *oid;
+
+ oid = gnutls_pk_get_oid(params->algo);
+ if (oid == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ /* first make sure that no previously allocated data are leaked */
+ if (*c2 != NULL) {
+ asn1_delete_structure(c2);
+ *c2 = NULL;
+ }
+
+ if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.FalconPrivateKey", c2)) !=
+ ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+
+ ret = _gnutls_asn1_encode_pqc_alg(
+ c2, params, oid, _gnutls_get_pqc_alg_version(params));
+ if (ret < 0)
+ goto cleanup;
+
+ return GNUTLS_E_SUCCESS;
+ }
+
+cleanup:
+ asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
+
+ return ret;
+}
+
+static int _gnutls_asn1_encode_sphincs(asn1_node *c2,
+ gnutls_pk_params_st *params)
+{
+ int ret;
+ const char *oid;
+
+ oid = gnutls_pk_get_oid(params->algo);
+ if (oid == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ /* first make sure that no previously allocated data are leaked */
+ if (*c2 != NULL) {
+ asn1_delete_structure(c2);
+ *c2 = NULL;
+ }
+
+ if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.SphincsPrivateKey", c2)) !=
+ ASN1_SUCCESS) {
+ gnutls_assert();
+ ret = _gnutls_asn2err(ret);
+ goto cleanup;
+ }
+
+ ret = _gnutls_asn1_encode_pqc_alg(c2, params, oid,
+ _gnutls_get_pqc_alg_version(params));
+ if (ret < 0)
+ goto cleanup;
+
+ return GNUTLS_E_SUCCESS;
+
+cleanup:
+ asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
+
+ return ret;
+}
+#endif
+
int _gnutls_asn1_encode_privkey(asn1_node *c2, gnutls_pk_params_st *params)
{
switch (params->algo) {
case GNUTLS_PK_DH:
/* DH keys are only exportable in PKCS#8 format */
return GNUTLS_E_INVALID_REQUEST;
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ return _gnutls_asn1_encode_dilithium(c2, params);
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ return _gnutls_asn1_encode_falcon(c2, params);
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ return _gnutls_asn1_encode_sphincs(c2, params);
+#endif
default:
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
pk_algorithm != GNUTLS_PK_EDDSA_ED25519 &&
pk_algorithm != GNUTLS_PK_ECDH_X25519 &&
pk_algorithm != GNUTLS_PK_EDDSA_ED448 &&
- pk_algorithm != GNUTLS_PK_ECDH_X448) {
- /* RSA and EdDSA do not use parameters */
+ pk_algorithm != GNUTLS_PK_ECDH_X448
+#ifdef HAVE_LIBOQS
+ && pk_algorithm != GNUTLS_PK_EXP_DILITHIUM2 &&
+ pk_algorithm != GNUTLS_PK_EXP_DILITHIUM3 &&
+ pk_algorithm != GNUTLS_PK_EXP_DILITHIUM5 &&
+ pk_algorithm != GNUTLS_PK_EXP_FALCON512 &&
+ pk_algorithm != GNUTLS_PK_EXP_FALCON1024 &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHA2_128F &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHA2_128S &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHA2_192F &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHA2_192S &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHA2_256F &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHA2_256S &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHAKE_128F &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHAKE_128S &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHAKE_192F &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHAKE_192S &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHAKE_256F &&
+ pk_algorithm != GNUTLS_PK_EXP_SPHINCS_SHAKE_256S
+#endif
+ ) {
+ /* RSA, EdDSA and PQC algorithms do not use parameters */
result = _gnutls_x509_read_value(asn, name, &tmp);
if (pk_algorithm == GNUTLS_PK_RSA_PSS &&
(result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
#include "ecc.h"
#include "pin.h"
+#ifdef HAVE_LIBOQS
+#include <oqs/oqs.h>
+#endif
/**
* gnutls_x509_privkey_init:
* @key: A pointer to the type to be initialized
return ret;
}
+#ifdef HAVE_LIBOQS
+struct PQCAlgorithmVersion {
+ uint8_t version;
+ gnutls_pk_algorithm_t algorithm;
+ int secret_key_length;
+ int public_key_length;
+};
+
+int _gnutls_decode_pqc_keys(asn1_node *pkey_asn, const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey, uint8_t *version)
+{
+ int result;
+ unsigned int _version;
+
+ result = _asn1_strict_der_decode(pkey_asn, raw_key->data, raw_key->size,
+ NULL);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ return result;
+ }
+
+ result = _gnutls_x509_read_uint(*pkey_asn, "version", &_version);
+ *version = _version;
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
+
+ result = _gnutls_x509_read_value(*pkey_asn, "privateKey",
+ &pkey->params.raw_priv);
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
+
+ result = _gnutls_x509_read_value(*pkey_asn, "publicKey",
+ &pkey->params.raw_pub);
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
+
+ return GNUTLS_E_SUCCESS;
+}
+
+struct PQCAlgorithmVersion dilithium_versions[] = {
+#if defined(GNUTLS_PK_EXP_DILITHIUM2) && \
+ defined(OQS_SIG_dilithium_2_length_secret_key) && \
+ defined(OQS_SIG_dilithium_2_length_public_key)
+ { '\x02', GNUTLS_PK_EXP_DILITHIUM2,
+ OQS_SIG_dilithium_2_length_secret_key,
+ OQS_SIG_dilithium_2_length_public_key },
+#endif
+#if defined(GNUTLS_PK_EXP_DILITHIUM3) && \
+ defined(OQS_SIG_dilithium_3_length_secret_key) && \
+ defined(OQS_SIG_dilithium_3_length_public_key)
+ { '\x03', GNUTLS_PK_EXP_DILITHIUM3,
+ OQS_SIG_dilithium_3_length_secret_key,
+ OQS_SIG_dilithium_3_length_public_key },
+#endif
+#if defined(GNUTLS_PK_EXP_DILITHIUM5) && \
+ defined(OQS_SIG_dilithium_5_length_secret_key) && \
+ defined(OQS_SIG_dilithium_5_length_public_key)
+ { '\x05', GNUTLS_PK_EXP_DILITHIUM5,
+ OQS_SIG_dilithium_5_length_secret_key,
+ OQS_SIG_dilithium_5_length_public_key },
+#endif
+
+ { '\x00', GNUTLS_PK_UNKNOWN, 0, 0 }
+};
+
+static int _gnutls_set_dilithium_params(const uint8_t *version,
+ gnutls_x509_privkey_t pkey)
+{
+ struct PQCAlgorithmVersion *v = dilithium_versions;
+ while (v->algorithm != GNUTLS_PK_UNKNOWN && v->version != *version)
+ v++;
+
+ pkey->params.raw_priv.size = v->secret_key_length;
+ pkey->params.raw_pub.size = v->public_key_length;
+ pkey->params.params_nr = DILITHIUM_PRIVATE_PARAMS;
+ pkey->params.algo = v->algorithm;
+
+ if (v->algorithm == GNUTLS_PK_UNKNOWN)
+ return GNUTLS_E_UNKNOWN_ALGORITHM;
+
+ return 0;
+}
+
+int _gnutls_privkey_decode_dilithium_key(asn1_node *pkey_asn,
+ const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey)
+{
+ int result;
+ uint8_t version;
+
+ gnutls_pk_params_init(&pkey->params);
+
+ if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.DilithiumPrivateKey",
+ pkey_asn)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ result = _gnutls_decode_pqc_keys(pkey_asn, raw_key, pkey, &version);
+ if (result < 0)
+ goto error;
+
+ result = _gnutls_set_dilithium_params(&version, pkey);
+ if (result < 0)
+ goto error;
+
+ return 0;
+
+error:
+ asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
+ gnutls_pk_params_clear(&pkey->params);
+ gnutls_pk_params_release(&pkey->params);
+ return result;
+}
+
+struct PQCAlgorithmVersion falcon_versions[] = {
+ { '\x01', GNUTLS_PK_EXP_FALCON512, OQS_SIG_falcon_512_length_secret_key,
+ OQS_SIG_falcon_512_length_public_key },
+ { '\x02', GNUTLS_PK_EXP_FALCON1024,
+ OQS_SIG_falcon_1024_length_secret_key,
+ OQS_SIG_falcon_1024_length_public_key },
+
+ { '\x00', GNUTLS_PK_UNKNOWN, 0, 0 }
+};
+
+static int _gnutls_set_falcon_params(const uint8_t *version,
+ gnutls_x509_privkey_t pkey)
+{
+ struct PQCAlgorithmVersion *v = falcon_versions;
+ while (v->algorithm != GNUTLS_PK_UNKNOWN && v->version != *version)
+ v++;
+
+ pkey->params.raw_priv.size = v->secret_key_length;
+ pkey->params.raw_pub.size = v->public_key_length;
+ pkey->params.params_nr = FALCON_PRIVATE_PARAMS;
+ pkey->params.algo = v->algorithm;
+
+ if (v->algorithm == GNUTLS_PK_UNKNOWN)
+ return GNUTLS_E_UNKNOWN_ALGORITHM;
+
+ return 0;
+}
+
+int _gnutls_privkey_decode_falcon_key(asn1_node *pkey_asn,
+ const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey)
+{
+ int result;
+ uint8_t version;
+
+ gnutls_pk_params_init(&pkey->params);
+
+ if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.FalconPrivateKey",
+ pkey_asn)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ result = _gnutls_decode_pqc_keys(pkey_asn, raw_key, pkey, &version);
+ if (result < 0)
+ goto error;
+
+ result = _gnutls_set_falcon_params(&version, pkey);
+ if (result < 0)
+ goto error;
+
+ return 0;
+
+error:
+ asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
+ gnutls_pk_params_clear(&pkey->params);
+ gnutls_pk_params_release(&pkey->params);
+ return result;
+}
+
+struct PQCAlgorithmVersion sphincs_versions[] = {
+ { '\x01', GNUTLS_PK_EXP_SPHINCS_SHA2_128F,
+ OQS_SIG_sphincs_sha2_128f_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_128f_simple_length_public_key },
+ { '\x02', GNUTLS_PK_EXP_SPHINCS_SHA2_128S,
+ OQS_SIG_sphincs_sha2_128s_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_128s_simple_length_public_key },
+ { '\x03', GNUTLS_PK_EXP_SPHINCS_SHA2_192F,
+ OQS_SIG_sphincs_sha2_192f_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_192f_simple_length_public_key },
+ { '\x04', GNUTLS_PK_EXP_SPHINCS_SHA2_192S,
+ OQS_SIG_sphincs_sha2_192s_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_192s_simple_length_public_key },
+ { '\x05', GNUTLS_PK_EXP_SPHINCS_SHA2_256F,
+ OQS_SIG_sphincs_sha2_256f_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_256f_simple_length_public_key },
+ { '\x06', GNUTLS_PK_EXP_SPHINCS_SHA2_256S,
+ OQS_SIG_sphincs_sha2_256s_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_256s_simple_length_public_key },
+ { '\x07', GNUTLS_PK_EXP_SPHINCS_SHAKE_128F,
+ OQS_SIG_sphincs_shake_128f_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_128f_simple_length_public_key },
+ { '\x08', GNUTLS_PK_EXP_SPHINCS_SHAKE_128S,
+ OQS_SIG_sphincs_shake_128s_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_128s_simple_length_public_key },
+ { '\x09', GNUTLS_PK_EXP_SPHINCS_SHAKE_192F,
+ OQS_SIG_sphincs_shake_192f_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_192f_simple_length_public_key },
+ { '\x0a', GNUTLS_PK_EXP_SPHINCS_SHAKE_192S,
+ OQS_SIG_sphincs_shake_192s_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_192s_simple_length_public_key },
+ { '\x0b', GNUTLS_PK_EXP_SPHINCS_SHAKE_256F,
+ OQS_SIG_sphincs_shake_256f_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_256f_simple_length_public_key },
+ { '\x0c', GNUTLS_PK_EXP_SPHINCS_SHAKE_256S,
+ OQS_SIG_sphincs_shake_256s_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_256s_simple_length_public_key },
+
+ { '\x00', GNUTLS_PK_UNKNOWN, 0, 0 }
+};
+
+static int _gnutls_set_sphincs_params(const uint8_t *version,
+ gnutls_x509_privkey_t pkey)
+{
+ struct PQCAlgorithmVersion *v = sphincs_versions;
+ while (v->algorithm != GNUTLS_PK_UNKNOWN && v->version != *version)
+ v++;
+
+ pkey->params.raw_priv.size = v->secret_key_length;
+ pkey->params.raw_pub.size = v->public_key_length;
+ pkey->params.params_nr = SPHINCS_PRIVATE_PARAMS;
+ pkey->params.algo = v->algorithm;
+
+ if (v->algorithm == GNUTLS_PK_UNKNOWN)
+ return GNUTLS_E_UNKNOWN_ALGORITHM;
+
+ return 0;
+}
+
+int _gnutls_privkey_decode_sphincs_key(asn1_node *pkey_asn,
+ const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey)
+{
+ int result;
+ uint8_t version;
+
+ gnutls_pk_params_init(&pkey->params);
+
+ if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.SphincsPrivateKey",
+ pkey_asn)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ result = _gnutls_decode_pqc_keys(pkey_asn, raw_key, pkey, &version);
+ if (result < 0)
+ goto error;
+
+ result = _gnutls_set_sphincs_params(&version, pkey);
+ if (result < 0)
+ goto error;
+
+ return 0;
+
+error:
+ asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
+ gnutls_pk_params_clear(&pkey->params);
+ gnutls_pk_params_release(&pkey->params);
+ return result;
+}
+#endif
+
static asn1_node decode_dsa_key(const gnutls_datum_t *raw_key,
gnutls_x509_privkey_t pkey)
{
#define PEM_KEY_DSA "DSA PRIVATE KEY"
#define PEM_KEY_RSA "RSA PRIVATE KEY"
#define PEM_KEY_ECC "EC PRIVATE KEY"
+#ifdef HAVE_LIBOQS
+#define PEM_KEY_DILITHIUM "DILITHIUM PRIVATE KEY"
+#define PEM_KEY_FALCON "FALCON PRIVATE KEY"
+#define PEM_KEY_SPHINCS "SPHINCS PRIVATE KEY"
+#endif
#define PEM_KEY_PKCS8 "PRIVATE KEY"
#define MAX_PEM_HEADER_SIZE 25
if (result >= 0)
key->params.algo =
GNUTLS_PK_DSA;
+#ifdef HAVE_LIBOQS
+ } else if (left > sizeof(PEM_KEY_DILITHIUM) &&
+ memcmp(ptr, PEM_KEY_DILITHIUM,
+ sizeof(PEM_KEY_DILITHIUM) -
+ 1) == 0) {
+ result = _gnutls_fbase64_decode(
+ PEM_KEY_DILITHIUM, begin_ptr,
+ left, &_data);
+ if (result >= 0) {
+ key->params.algo =
+ GNUTLS_PK_EXP_DILITHIUM2;
+ }
+ } else if (left > sizeof(PEM_KEY_FALCON) &&
+ memcmp(ptr, PEM_KEY_FALCON,
+ sizeof(PEM_KEY_FALCON) - 1) ==
+ 0) {
+ result = _gnutls_fbase64_decode(
+ PEM_KEY_FALCON, begin_ptr, left,
+ &_data);
+ if (result >= 0) {
+ key->params.algo =
+ GNUTLS_PK_EXP_FALCON512;
+ }
+ } else if (left > sizeof(PEM_KEY_SPHINCS) &&
+ memcmp(ptr, PEM_KEY_SPHINCS,
+ sizeof(PEM_KEY_SPHINCS) -
+ 1) == 0) {
+ result = _gnutls_fbase64_decode(
+ PEM_KEY_SPHINCS, begin_ptr,
+ left, &_data);
+ if (result >= 0) {
+ key->params.algo =
+ GNUTLS_PK_EXP_SPHINCS_SHA2_128F;
+ }
+#endif
}
if (key->params.algo == GNUTLS_PK_UNKNOWN &&
gnutls_assert();
key->key = NULL;
}
+#ifdef HAVE_LIBOQS
+ } else if (key->params.algo == GNUTLS_PK_EXP_DILITHIUM2) {
+ result = _gnutls_privkey_decode_dilithium_key(&key->key, &_data,
+ key);
+
+ if (result < 0) {
+ gnutls_assert();
+ key->key = NULL;
+ }
+ } else if (key->params.algo == GNUTLS_PK_EXP_FALCON512) {
+ result = _gnutls_privkey_decode_falcon_key(&key->key, &_data,
+ key);
+
+ if (result < 0) {
+ gnutls_assert();
+ key->key = NULL;
+ }
+ } else if (key->params.algo == GNUTLS_PK_EXP_SPHINCS_SHA2_128F) {
+ result = _gnutls_privkey_decode_sphincs_key(&key->key, &_data,
+ key);
+
+ if (result < 0) {
+ gnutls_assert();
+ key->key = NULL;
+ }
+#endif
} else {
/* Try decoding each of the keys, and accept the one that
* succeeds.
return ret;
}
+#ifdef HAVE_LIBOQS
+#define MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER 21
+#define MAX_PEM_KEY_SIZE PEM_KEY_DILITHIUM
+#else
+#define MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER 15
+#define MAX_PEM_KEY_SIZE PEM_KEY_RSA
+#endif
+
/**
* gnutls_x509_privkey_import2:
* @key: The data to store the parsed key
left = data->size -
((ptrdiff_t)ptr - (ptrdiff_t)data->data);
- if (data->size - left > 15) {
- ptr -= 15;
- left += 15;
+ if (data->size - left >
+ MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER) {
+ ptr -= MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER;
+ left += MAX_ALGORITHM_NAME_SIZE_IN_PEM_HEADER;
} else {
ptr = (char *)data->data;
left = data->size;
((ptrdiff_t)ptr - (ptrdiff_t)data->data);
}
- if (ptr != NULL && left > sizeof(PEM_KEY_RSA)) {
+ if (ptr != NULL && left > sizeof(MAX_PEM_KEY_SIZE)) {
if (memcmp(ptr, PEM_KEY_RSA,
sizeof(PEM_KEY_RSA) - 1) == 0 ||
memcmp(ptr, PEM_KEY_ECC,
sizeof(PEM_KEY_ECC) - 1) == 0 ||
memcmp(ptr, PEM_KEY_DSA,
- sizeof(PEM_KEY_DSA) - 1) == 0) {
+ sizeof(PEM_KEY_DSA) - 1) == 0
+#ifdef HAVE_LIBOQS
+ || memcmp(ptr, PEM_KEY_DILITHIUM,
+ sizeof(PEM_KEY_DILITHIUM) - 1) ==
+ 0 ||
+ memcmp(ptr, PEM_KEY_FALCON,
+ sizeof(PEM_KEY_FALCON) - 1) == 0 ||
+ memcmp(ptr, PEM_KEY_SPHINCS,
+ sizeof(PEM_KEY_SPHINCS) - 1) == 0
+#endif
+ ) {
head_enc = 0;
}
}
static const char *set_msg(gnutls_x509_privkey_t key)
{
- if (GNUTLS_PK_IS_RSA(key->params.algo)) {
+ switch (key->params.algo) {
+ case GNUTLS_PK_RSA:
+ case GNUTLS_PK_RSA_PSS:
return PEM_KEY_RSA;
- } else if (key->params.algo == GNUTLS_PK_DSA) {
+ case GNUTLS_PK_DSA:
return PEM_KEY_DSA;
- } else if (key->params.algo == GNUTLS_PK_EC)
+ case GNUTLS_PK_EC:
return PEM_KEY_ECC;
- else
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ return PEM_KEY_DILITHIUM;
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ return PEM_KEY_FALCON;
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ return PEM_KEY_SPHINCS;
+#endif
+ default:
return "UNKNOWN";
+ }
}
/**
#include "attributes.h"
#include "prov-seed.h"
+#ifdef HAVE_LIBOQS
+#include <oqs/oqs.h>
+#endif
+
static int _decode_pkcs8_ecc_key(asn1_node pkcs8_asn,
gnutls_x509_privkey_t pkey);
static int pkcs8_key_info(const gnutls_datum_t *raw_key,
if (ret < 0)
gnutls_assert();
return ret;
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ // Dilithium public key is appended to private key
+ ret = _gnutls_x509_encode_string(
+ ASN1_ETYPE_OCTET_STRING, pkey->params.raw_priv.data,
+ pkey->params.raw_priv.size + pkey->params.raw_pub.size,
+ raw);
+ if (ret < 0)
+ gnutls_assert();
+ return ret;
+#endif
case GNUTLS_PK_GOST_01:
case GNUTLS_PK_GOST_12_256:
return ret;
}
+#ifdef HAVE_LIBOQS
+struct pqc_key_length_st {
+ gnutls_pk_algorithm_t algorithm;
+ int secret_key_length;
+ int public_key_length;
+};
+
+struct pqc_key_length_st pqc_key_lengths[] = {
+#ifdef defined(GNUTLS_PK_EXP_DILITHIUM2) && \
+ defined(OQS_SIG_dilithium_2_length_secret_key) && \
+ defined(OQS_SIG_dilithium_2_length_public_key)
+ { GNUTLS_PK_EXP_DILITHIUM2, OQS_SIG_dilithium_2_length_secret_key,
+ OQS_SIG_dilithium_2_length_public_key },
+#endif
+#ifdef defined(GNUTLS_PK_EXP_DILITHIUM3) && \
+ defined(OQS_SIG_dilithium_3_length_secret_key) && \
+ defined(OQS_SIG_dilithium_3_length_public_key)
+ { GNUTLS_PK_EXP_DILITHIUM3, OQS_SIG_dilithium_3_length_secret_key,
+ OQS_SIG_dilithium_3_length_public_key },
+#endif
+#ifdef defined(GNUTLS_PK_EXP_DILITHIUM5) && \
+ defined(OQS_SIG_dilithium_5_length_secret_key) && \
+ defined(OQS_SIG_dilithium_5_length_public_key)
+ { GNUTLS_PK_EXP_DILITHIUM5, OQS_SIG_dilithium_5_length_secret_key,
+ OQS_SIG_dilithium_5_length_public_key },
+#endif
+ { GNUTLS_PK_EXP_FALCON512, OQS_SIG_falcon_512_length_secret_key,
+ OQS_SIG_falcon_512_length_public_key },
+ { GNUTLS_PK_EXP_FALCON1024, OQS_SIG_falcon_1024_length_secret_key,
+ OQS_SIG_falcon_1024_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_128F,
+ OQS_SIG_sphincs_sha2_128f_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_128f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_128S,
+ OQS_SIG_sphincs_sha2_128s_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_128s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_192F,
+ OQS_SIG_sphincs_sha2_192f_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_192f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_192S,
+ OQS_SIG_sphincs_sha2_192s_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_192s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_256F,
+ OQS_SIG_sphincs_sha2_256f_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_256f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHA2_256S,
+ OQS_SIG_sphincs_sha2_256s_simple_length_secret_key,
+ OQS_SIG_sphincs_sha2_256s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_128F,
+ OQS_SIG_sphincs_shake_128f_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_128f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_128S,
+ OQS_SIG_sphincs_shake_128s_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_128s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_192F,
+ OQS_SIG_sphincs_shake_192f_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_192f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_192S,
+ OQS_SIG_sphincs_shake_192s_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_192s_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_256F,
+ OQS_SIG_sphincs_shake_256f_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_256f_simple_length_public_key },
+ { GNUTLS_PK_EXP_SPHINCS_SHAKE_256S,
+ OQS_SIG_sphincs_shake_256s_simple_length_secret_key,
+ OQS_SIG_sphincs_shake_256s_simple_length_public_key },
+
+ { GNUTLS_PK_UNKNOWN, 0, 0 }
+};
+
+static int _get_pqc_keys_length(gnutls_pk_algorithm_t algo,
+ int *pqc_alg_secret_key_length,
+ int *pqc_alg_public_key_length)
+{
+ struct pqc_key_length_st *pqc_key_length = pqc_key_lengths;
+ while (pqc_key_length->algorithm != algo &&
+ pqc_key_length->algorithm != GNUTLS_PK_UNKNOWN)
+ pqc_key_length++;
+
+ if (pqc_key_length->algorithm == GNUTLS_PK_UNKNOWN)
+ return GNUTLS_E_UNKNOWN_ALGORITHM;
+
+ *pqc_alg_secret_key_length = pqc_key_length->secret_key_length;
+ *pqc_alg_public_key_length = pqc_key_length->public_key_length;
+
+ return 0;
+}
+
+static int _decode_pkcs8_pqc_alg_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey,
+ const char *oid)
+{
+ int ret;
+ gnutls_datum_t private_key;
+ gnutls_pk_algorithm_t algo = pkey->params.algo;
+ int pqc_alg_secret_key_length;
+ int pqc_alg_public_key_length;
+
+ ret = _get_pqc_keys_length(pkey->params.algo,
+ &pqc_alg_secret_key_length,
+ &pqc_alg_public_key_length);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ /* TODO: support OneAsymmetricKey to read public key from a
+ * separate field
+ */
+
+ gnutls_pk_params_init(&pkey->params);
+
+ ret = _gnutls_x509_read_string(pkcs8_asn, "privateKey", &private_key,
+ ASN1_ETYPE_OCTET_STRING, 1);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
+
+ pkey->params.algo = algo;
+ pkey->params.raw_priv.data = private_key.data;
+ pkey->params.raw_priv.size = pqc_alg_secret_key_length;
+
+ pkey->params.raw_pub.data = gnutls_malloc(pqc_alg_public_key_length);
+ memcpy(pkey->params.raw_pub.data,
+ &private_key.data[pqc_alg_secret_key_length],
+ pqc_alg_public_key_length);
+ pkey->params.raw_pub.size = pqc_alg_public_key_length;
+
+ private_key.data = NULL;
+
+ return GNUTLS_E_SUCCESS;
+
+error:
+ gnutls_free(pkey->params.raw_priv.data);
+ gnutls_pk_params_clear(&pkey->params);
+ gnutls_pk_params_release(&pkey->params);
+
+ return ret;
+}
+#endif
+
static int decode_private_key_info(const gnutls_datum_t *der,
gnutls_x509_privkey_t pkey)
{
result = _decode_pkcs8_gost_key(pkcs8_asn, pkey,
pkey->params.algo);
break;
+#ifdef HAVE_LIBOQS
+ case GNUTLS_PK_EXP_DILITHIUM2:
+ case GNUTLS_PK_EXP_DILITHIUM3:
+ case GNUTLS_PK_EXP_DILITHIUM5:
+ case GNUTLS_PK_EXP_FALCON512:
+ case GNUTLS_PK_EXP_FALCON1024:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHA2_256S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_128S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_192S:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256F:
+ case GNUTLS_PK_EXP_SPHINCS_SHAKE_256S:
+ result = _decode_pkcs8_pqc_alg_key(pkcs8_asn, pkey, oid);
+ break;
+#endif
default:
result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
goto error;
gnutls_x509_privkey_t pkey,
gnutls_ecc_curve_t curve);
+#ifdef HAVE_LIBOQS
+int _gnutls_decode_pqc_keys(asn1_node *pkey_asn, const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey, uint8_t *version);
+
+int _gnutls_privkey_decode_dilithium_key(asn1_node *pkey_asn,
+ const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey);
+
+int _gnutls_privkey_decode_falcon_key(asn1_node *pkey_asn,
+ const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey);
+
+int _gnutls_privkey_decode_sphincs_key(asn1_node *pkey_asn,
+ const gnutls_datum_t *raw_key,
+ gnutls_x509_privkey_t pkey);
+#endif
+
int _gnutls_privkey_decode_eddsa_key(asn1_node *pkey_asn,
const gnutls_datum_t *raw_key,
gnutls_x509_privkey_t pkey,
continue;
#endif
}
-
+#ifndef HAVE_LIBOQS
+ if (algorithm == GNUTLS_PK_EXP_DILITHIUM2 ||
+ algorithm == GNUTLS_PK_EXP_DILITHIUM3 ||
+ algorithm == GNUTLS_PK_EXP_DILITHIUM5 ||
+ algorithm == GNUTLS_PK_EXP_FALCON512 ||
+ algorithm == GNUTLS_PK_EXP_FALCON1024 ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHA2_128F ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHA2_128S ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHA2_192F ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHA2_192S ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHA2_256F ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHA2_256S ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHAKE_128F ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHAKE_128S ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHAKE_192F ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHAKE_192S ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHAKE_256F ||
+ algorithm == GNUTLS_PK_EXP_SPHINCS_SHAKE_256S)
+ continue;
+#endif
ret = gnutls_x509_privkey_init(&pkey);
if (ret < 0) {
fail("gnutls_x509_privkey_init: %d\n", ret);