forked from wolfSSL/wolfssl
added generic curve25519 encode/decode functions that can handle combined keypairs
This commit is contained in:
@ -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 */
|
||||
|
||||
|
||||
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
Reference in New Issue
Block a user