Skip to content

Commit

Permalink
added generic curve25519 encode/decode functions that can handle comb…
Browse files Browse the repository at this point in the history
…ined keypairs
  • Loading branch information
bigbrett committed Oct 30, 2024
1 parent bdd6231 commit 97a370e
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
106 changes: 106 additions & 0 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -35661,6 +35661,55 @@ int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
}
return ret;
}

/* Decode Curve25519 key from DER format - can handle private only,
* public only, or private+public key pairs.
* return 0 on success, negative on error */
int wc_Curve25519KeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz)
{
int ret;
byte privKey[CURVE25519_KEYSIZE];
byte pubKey[CURVE25519_KEYSIZE];
word32 privKeyLen = CURVE25519_KEYSIZE;
word32 pubKeyLen = CURVE25519_KEYSIZE;

/* sanity check */
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
return BAD_FUNC_ARG;
}

/* Try to decode as private key first (may include public) */
ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
pubKey, &pubKeyLen, X25519k);

if (ret == 0) {
/* Successfully decoded private key */
if (pubKeyLen > 0) {
/* Have both private and public */
ret = wc_curve25519_import_private_raw(privKey, privKeyLen,
pubKey, pubKeyLen, key);
}
else {
/* Private only */
ret = wc_curve25519_import_private(privKey, privKeyLen, key);
}
}
else {
/* Try decoding as public key */
*inOutIdx = 0; /* Reset index */
pubKeyLen = CURVE25519_KEYSIZE;
ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
pubKey, &pubKeyLen, X25519k);
if (ret == 0) {
/* Successfully decoded public key */
ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
}
}

return ret;
}

#endif /* HAVE_CURVE25519 && HAVE_ED25519_KEY_IMPORT */


Expand Down Expand Up @@ -35868,6 +35917,63 @@ int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
}
return ret;
}

/* Export Curve25519 key to DER format - handles private only, public only,
* or private+public key pairs based on what's set in the key structure.
* Returns length written on success, negative on error */
int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen, int withAlg)
{
int ret;
byte privKey[CURVE25519_KEYSIZE];
byte pubKey[CURVE25519_KEYSIZE];
word32 privKeyLen = CURVE25519_KEYSIZE;
word32 pubKeyLen = CURVE25519_KEYSIZE;

if (key == NULL) {
return BAD_FUNC_ARG;
}

/* Check what we have in the key structure */
if (key->privSet) {
/* Export private key to buffer */
ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
if (ret != 0) {
return ret;
}

if (key->pubSet) {
/* Export public key if available */
ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
if (ret != 0) {
return ret;
}
/* Export both private and public */
ret = SetAsymKeyDer(privKey, privKeyLen,
pubKey, pubKeyLen,
output, inLen, X25519k);
}
else {
/* Export private only */
ret = SetAsymKeyDer(privKey, privKeyLen,
NULL, 0,
output, inLen, X25519k);
}
}
else if (key->pubSet) {
/* Export public key only */
ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
if (ret == 0) {
ret = SetAsymKeyDerPublic(pubKey, pubKeyLen,
output, inLen, X25519k, withAlg);
}
}
else {
/* Neither public nor private key is set */
ret = BAD_FUNC_ARG;
}

return ret;
}
#endif /* HAVE_CURVE25519 && HAVE_CURVE25519_KEY_EXPORT */

#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
Expand Down
56 changes: 56 additions & 0 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -35042,6 +35042,62 @@ static wc_test_ret_t curve255519_der_test(void)
ret = WC_TEST_RET_ENC_NC;
}


/* Test decode/encode of Curve25519 private key (only) using generic API */
if (ret == 0) {
/* clear key, since generic API will try to decode all fields */
XMEMSET(&key, 0, sizeof(key));

idx = 0;
ret = wc_Curve25519KeyDecode(kCurve25519PrivDer, &idx, &key,
(word32)sizeof(kCurve25519PrivDer));
if (ret < 0) {
ret = WC_TEST_RET_ENC_EC(ret);
}
}
if (ret == 0) {
outputSz = (word32)sizeof(output);
ret = wc_Curve25519KeyToDer(&key, output, outputSz, 1);
if (ret >= 0) {
outputSz = (word32)ret;
ret = 0;
}
else {
ret = WC_TEST_RET_ENC_EC(ret);
}
}
if (ret == 0 && (outputSz != (word32)sizeof(kCurve25519PrivDer) ||
XMEMCMP(output, kCurve25519PrivDer, outputSz) != 0)) {
ret = WC_TEST_RET_ENC_NC;
}

/* Test decode/encode of Curve25519 public key (only) using generic API */
if (ret == 0) {
/* clear key, since generic API will try to decode all fields */
XMEMSET(&key, 0, sizeof(key));
idx = 0;
ret = wc_Curve25519KeyDecode(kCurve25519PubDer, &idx, &key,
(word32)sizeof(kCurve25519PubDer));
if (ret < 0) {
ret = WC_TEST_RET_ENC_EC(ret);
}
}
if (ret == 0) {
outputSz = (word32)sizeof(output);
ret = wc_Curve25519KeyToDer(&key, output, outputSz, 1);
if (ret >= 0) {
outputSz = (word32)ret;
ret = 0;
}
else {
ret = WC_TEST_RET_ENC_EC(ret);
}
}
if (ret == 0 && (outputSz != (word32)sizeof(kCurve25519PubDer) ||
XMEMCMP(output, kCurve25519PubDer, outputSz) != 0)) {
ret = WC_TEST_RET_ENC_NC;
}

wc_curve25519_free(&key);

return ret;
Expand Down
4 changes: 4 additions & 0 deletions wolfssl/wolfcrypt/asn_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -841,12 +841,16 @@ WOLFSSL_API int wc_Curve25519PrivateKeyDecode(
const byte* input, word32* inOutIdx, curve25519_key* key, word32 inSz);
WOLFSSL_API int wc_Curve25519PublicKeyDecode(
const byte* input, word32* inOutIdx, curve25519_key* key, word32 inSz);
WOLFSSL_API int wc_Curve25519KeyDecode(const byte *input, word32 *inOutIdx,
curve25519_key *key, word32 inSz);
#endif
#ifdef HAVE_CURVE25519_KEY_EXPORT
WOLFSSL_API int wc_Curve25519PrivateKeyToDer(
curve25519_key* key, byte* output, word32 inLen);
WOLFSSL_API int wc_Curve25519PublicKeyToDer(
curve25519_key* key, byte* output, word32 inLen, int withAlg);
WOLFSSL_API int wc_Curve25519KeyToDer(curve25519_key* key, byte* output,
word32 inLen, int withAlg);
#endif
#endif /* HAVE_CURVE25519 */

Expand Down

0 comments on commit 97a370e

Please sign in to comment.