mirror of
https://github.com/libtom/libtomcrypt
synced 2026-08-25 20:26:07 -04:00
add real pkcs#8 import of Curve25519 private keys
This commit is contained in:
parent
8ea0fb1195
commit
e3766e16ca
9 changed files with 254 additions and 103 deletions
|
|
@ -359,6 +359,9 @@ int ed25519_export( unsigned char *out, unsigned long *outlen,
|
|||
|
||||
int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
|
||||
int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
|
||||
int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const void *pwd, unsigned long pwdlen,
|
||||
curve25519_key *key);
|
||||
|
||||
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
|
||||
unsigned char *sig, unsigned long *siglen,
|
||||
|
|
@ -381,6 +384,9 @@ int x25519_export( unsigned char *out, unsigned long *outlen,
|
|||
|
||||
int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
|
||||
int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
|
||||
int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const void *pwd, unsigned long pwdlen,
|
||||
curve25519_key *key);
|
||||
|
||||
int x25519_shared_secret(const curve25519_key *private_key,
|
||||
const curve25519_key *public_key,
|
||||
|
|
|
|||
|
|
@ -315,6 +315,12 @@ int crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
|
|||
int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
|
||||
int crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
|
||||
|
||||
typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
|
||||
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const void *pwd, unsigned long pwdlen,
|
||||
enum ltc_oid_id id, sk_to_pk fp,
|
||||
curve25519_key *key);
|
||||
|
||||
#endif /* LTC_CURVE25519 */
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
|
|
|||
97
src/pk/ec25519/ec25519_import_pkcs8.c
Normal file
97
src/pk/ec25519/ec25519_import_pkcs8.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ec25519_import_pkcs8.c
|
||||
Generic import of a Curve/Ed25519 private key in PKCS#8 format, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_CURVE25519
|
||||
|
||||
/**
|
||||
Generic import of a Curve/Ed25519 private key in PKCS#8 format
|
||||
@param in The DER-encoded PKCS#8-formatted private key
|
||||
@param inlen The length of the input data
|
||||
@param passwd The password to decrypt the private key
|
||||
@param passwdlen Password's length (octets)
|
||||
@param key [out] Where to import the key to
|
||||
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
||||
*/
|
||||
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const void *pwd, unsigned long pwdlen,
|
||||
enum ltc_oid_id id, sk_to_pk fp,
|
||||
curve25519_key *key)
|
||||
{
|
||||
int err = CRYPT_INVALID_ARG;
|
||||
ltc_asn1_list *l = NULL;
|
||||
const char *oid;
|
||||
ltc_asn1_list alg_id[1];
|
||||
unsigned char private_key[34];
|
||||
unsigned long version, key_len;
|
||||
unsigned long tmpoid[16];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(fp != NULL);
|
||||
|
||||
if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {
|
||||
|
||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid) / sizeof(tmpoid[0]));
|
||||
|
||||
key_len = sizeof(private_key);
|
||||
if ((err = der_decode_sequence_multi(l->data, l->size,
|
||||
LTC_ASN1_SHORT_INTEGER, 1uL, &version,
|
||||
LTC_ASN1_SEQUENCE, 1uL, alg_id,
|
||||
LTC_ASN1_OCTET_STRING, key_len, private_key,
|
||||
LTC_ASN1_EOL, 0uL, NULL))
|
||||
!= CRYPT_OK) {
|
||||
/* If there are attributes added after the private_key it is tagged with version 1 and
|
||||
* we get an 'input too long' error but the rest is already decoded and can be
|
||||
* handled the same as for version 0
|
||||
*/
|
||||
if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
|
||||
version = 0;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = pk_get_oid(id, &oid)) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
key_len = sizeof(key->priv);
|
||||
if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
|
||||
fp(key->pub, key->priv);
|
||||
key->type = PK_PRIVATE;
|
||||
key->algo = id;
|
||||
}
|
||||
} else {
|
||||
err = CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (l) der_free_sequence_flexi(l);
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(private_key, sizeof(private_key));
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
#ifdef LTC_CURVE25519
|
||||
|
||||
/**
|
||||
Import a Ed25519 key from a binary packet
|
||||
Import an Ed25519 public key
|
||||
@param in The packet to read
|
||||
@param inlen The length of the input packet
|
||||
@param key [out] Where to import the key to
|
||||
|
|
@ -25,72 +25,19 @@
|
|||
int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
|
||||
{
|
||||
int err;
|
||||
const char* oid;
|
||||
ltc_asn1_list alg_id[1];
|
||||
unsigned char private_key[34];
|
||||
unsigned long version, key_len;
|
||||
unsigned long tmpoid[16];
|
||||
unsigned long key_len;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* There's only one case where the inlen is equal to the pubkey-size
|
||||
* and that's a raw pubkey, so let's just do a raw import.
|
||||
*/
|
||||
if (inlen == sizeof(key->pub)) {
|
||||
XMEMCPY(key->pub, in, sizeof(key->pub));
|
||||
key->type = PK_PUBLIC;
|
||||
key->algo = PKA_ED25519;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
key_len = sizeof(key->pub);
|
||||
if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
|
||||
key->type = PK_PUBLIC;
|
||||
key->algo = PKA_ED25519;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
|
||||
|
||||
key_len = sizeof(private_key);
|
||||
err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1uL, &version,
|
||||
LTC_ASN1_SEQUENCE, 1uL, alg_id,
|
||||
LTC_ASN1_OCTET_STRING, key_len, private_key,
|
||||
LTC_ASN1_EOL, 0uL, NULL);
|
||||
if (err != CRYPT_OK) {
|
||||
if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
|
||||
version = 0;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = pk_get_oid(PKA_ED25519, &oid)) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
key_len = sizeof(key->priv);
|
||||
if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
|
||||
crypto_sk_to_pk(key->pub, key->priv);
|
||||
key->type = PK_PRIVATE;
|
||||
key->algo = PKA_ED25519;
|
||||
}
|
||||
} else {
|
||||
err = CRYPT_PK_INVALID_TYPE;
|
||||
return err;
|
||||
}
|
||||
|
||||
out:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(private_key, sizeof(private_key));
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
38
src/pk/ed25519/ed25519_import_pkcs8.c
Normal file
38
src/pk/ed25519/ed25519_import_pkcs8.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ed25519_import_pkcs8.c
|
||||
Import a Ed25519 key in PKCS#8 format, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_CURVE25519
|
||||
|
||||
/**
|
||||
Import a Ed25519 private key in PKCS#8 format
|
||||
@param in The DER-encoded PKCS#8-formatted private key
|
||||
@param inlen The length of the input data
|
||||
@param passwd The password to decrypt the private key
|
||||
@param passwdlen Password's length (octets)
|
||||
@param key [out] Where to import the key to
|
||||
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
||||
*/
|
||||
int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const void *pwd, unsigned long pwdlen,
|
||||
curve25519_key *key)
|
||||
{
|
||||
return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_ED25519, crypto_sk_to_pk, key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
||||
|
|
@ -25,11 +25,7 @@
|
|||
int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
|
||||
{
|
||||
int err;
|
||||
const char *oid;
|
||||
ltc_asn1_list alg_id[1];
|
||||
unsigned char private_key[34];
|
||||
unsigned long version, key_len;
|
||||
unsigned long tmpoid[16];
|
||||
unsigned long key_len;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
|
@ -49,43 +45,9 @@ int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *
|
|||
key->type = PK_PUBLIC;
|
||||
key->algo = PKA_X25519;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
|
||||
|
||||
key_len = sizeof(private_key);
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1uL, &version,
|
||||
LTC_ASN1_SEQUENCE, 1uL, alg_id,
|
||||
LTC_ASN1_OCTET_STRING, key_len, private_key,
|
||||
LTC_ASN1_EOL, 0uL, NULL)) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((err = pk_get_oid(PKA_X25519, &oid)) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
key_len = sizeof(key->priv);
|
||||
if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
|
||||
crypto_scalarmult_base(key->pub, key->priv);
|
||||
key->type = PK_PRIVATE;
|
||||
key->algo = PKA_X25519;
|
||||
}
|
||||
} else {
|
||||
err = CRYPT_PK_INVALID_TYPE;
|
||||
return err;
|
||||
}
|
||||
|
||||
out:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(private_key, sizeof(private_key));
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
38
src/pk/x25519/x25519_import_pkcs8.c
Normal file
38
src/pk/x25519/x25519_import_pkcs8.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file x25519_import_pkcs8.c
|
||||
Import a X25519 key in PKCS#8 format, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_CURVE25519
|
||||
|
||||
/**
|
||||
Import a X25519 private key in PKCS#8 format
|
||||
@param in The DER-encoded PKCS#8-formatted private key
|
||||
@param inlen The length of the input data
|
||||
@param passwd The password to decrypt the private key
|
||||
@param passwdlen Password's length (octets)
|
||||
@param key [out] Where to import the key to
|
||||
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
||||
*/
|
||||
int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const void *pwd, unsigned long pwdlen,
|
||||
curve25519_key *key)
|
||||
{
|
||||
return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_X25519, crypto_scalarmult_base, key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
||||
|
|
@ -43,6 +43,13 @@ static int _rfc_8410_10_test(void)
|
|||
{ "MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC"
|
||||
"oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB"
|
||||
"Z9w7lshQhqowtrbLDFw4rXAxZuE=", -1 },
|
||||
/* Another self-created testvector.
|
||||
* `openssl genpkey -algorithm ed25519 -pass stdin -aes128`
|
||||
*/
|
||||
{ "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAiFflnrBOdwjwICCAAw"
|
||||
"DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEMzFYoqiT6gxwFx2EA55MUYEQFD1"
|
||||
"ZLxPNhm4YAsMZaxu5qpLjiZbkWsTHxURb6WhSW8GAbNbTwxeOaA02sUhJg8rx44/"
|
||||
"N9PzN2QGzIQ1Yv/vHqQ=", -1 },
|
||||
};
|
||||
unsigned n;
|
||||
curve25519_key key;
|
||||
|
|
@ -52,10 +59,22 @@ static int _rfc_8410_10_test(void)
|
|||
for (n = 0; n < sizeof(rfc_8410_10)/sizeof(rfc_8410_10[0]); ++n) {
|
||||
buflen = sizeof(buf);
|
||||
DO(base64_decode(rfc_8410_10[n].b64, strlen(rfc_8410_10[n].b64), buf, &buflen));
|
||||
if (rfc_8410_10[n].type == -2) {
|
||||
DO(ed25519_import_x509(buf, buflen, &key));
|
||||
} else {
|
||||
DO(ed25519_import(buf, buflen, &key));
|
||||
switch (n) {
|
||||
case 0:
|
||||
DO(ed25519_import(buf, buflen, &key));
|
||||
break;
|
||||
case 1:
|
||||
DO(ed25519_import_x509(buf, buflen, &key));
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
DO(ed25519_import_pkcs8(buf, buflen, NULL, 0, &key));
|
||||
break;
|
||||
case 4:
|
||||
DO(ed25519_import_pkcs8(buf, buflen, "123456", 6, &key));
|
||||
break;
|
||||
default:
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
zeromem(buf, sizeof(buf));
|
||||
if (rfc_8410_10[n].type > 0) {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ static int _rfc_7748_6_test(void)
|
|||
static int _rfc_8410_10_test(void)
|
||||
{
|
||||
const struct {
|
||||
const char* b64;
|
||||
const char *b64;
|
||||
} rfc_8410_10[] = {
|
||||
/* RFC 8410 - 10.2. Example X25519 Certificate */
|
||||
{ "MIIBLDCB36ADAgECAghWAUdKKo3DMDAFBgMrZXAwGTEXMBUGA1UEAwwOSUVURiBUZX"
|
||||
|
|
@ -129,7 +129,8 @@ static int _rfc_8410_10_test(void)
|
|||
"ga9OukqY6qm05qo0UwQzAPBgNVHRMBAf8EBTADAQEAMA4GA1UdDwEBAAQEAwIDCDAg"
|
||||
"BgNVHQ4BAQAEFgQUmx9e7e0EM4Xk97xiPFl1uQvIuzswBQYDK2VwA0EAryMB/t3J5v"
|
||||
"/BzKc9dNZIpDmAgs3babFOTQbs+BolzlDUwsPrdGxO3YNGhW7Ibz3OGhhlxXrCe1Cg"
|
||||
"w1AH9efZBw==" },
|
||||
"w1AH9efZBw=="
|
||||
},
|
||||
};
|
||||
unsigned n;
|
||||
curve25519_key key;
|
||||
|
|
@ -144,6 +145,40 @@ static int _rfc_8410_10_test(void)
|
|||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static int _x25519_pkcs8_test(void)
|
||||
{
|
||||
const struct {
|
||||
const char *b64, *pass;
|
||||
} _x25519_pkcs8[] = {
|
||||
/* `openssl genpkey -algorithm x25519 -pass stdin -aes128` */
|
||||
{
|
||||
"MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjG5kRkEihOvQICCAAw"
|
||||
"DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEHPLHLoCvesRyeToyMtGHWcEQM1+"
|
||||
"FMpSO5DplX3d+YGTAvf0WxWaBff1q4bfKDn/7IoWQT1e4Fe6Psj62Vy9T69o3+Uy"
|
||||
"VM6mdIOXGOkAtaMSsSk=",
|
||||
"123456"
|
||||
},
|
||||
/* `openssl genpkey -algorithm x25519 -pass stdin` */
|
||||
{
|
||||
"MC4CAQAwBQYDK2VuBCIEIEAInaUdx+fQFfghpCzw/WdItRT3+FnPSkrU9TcIZTZW",
|
||||
NULL
|
||||
},
|
||||
};
|
||||
unsigned n;
|
||||
curve25519_key key;
|
||||
unsigned char buf[1024];
|
||||
unsigned long buflen, passlen;
|
||||
for (n = 0; n < sizeof(_x25519_pkcs8)/sizeof(_x25519_pkcs8[0]); ++n) {
|
||||
buflen = sizeof(buf);
|
||||
DO(base64_decode(_x25519_pkcs8[n].b64, strlen(_x25519_pkcs8[n].b64), buf, &buflen));
|
||||
if (_x25519_pkcs8[n].pass != NULL) passlen = strlen(_x25519_pkcs8[n].pass);
|
||||
else passlen = 0;
|
||||
DO(x25519_import_pkcs8(buf, buflen, _x25519_pkcs8[n].pass, passlen, &key));
|
||||
zeromem(buf, sizeof(buf));
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static int _x25519_compat_test(void)
|
||||
{
|
||||
curve25519_key priv, pub, imported;
|
||||
|
|
@ -158,7 +193,7 @@ static int _x25519_compat_test(void)
|
|||
DO(x25519_make_key(&yarrow_prng, prng_idx, &priv));
|
||||
|
||||
DO(x25519_export(buf, &buflen, PK_PRIVATE, &priv));
|
||||
DO(x25519_import(buf, buflen, &imported));
|
||||
DO(x25519_import_pkcs8(buf, buflen, NULL, 0, &imported));
|
||||
DO(do_compare_testvector(&priv, sizeof(priv), &imported, sizeof(imported), "priv after ex-&import", __LINE__));
|
||||
XMEMSET(&imported, 0, sizeof(imported));
|
||||
|
||||
|
|
@ -201,6 +236,9 @@ int x25519_test(void)
|
|||
if ((ret = _rfc_8410_10_test()) != CRYPT_OK) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = _x25519_pkcs8_test()) != CRYPT_OK) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = _x25519_compat_test()) != CRYPT_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue