Skip to content

Commit

Permalink
Merge pull request wolfSSL#8129 from bigbrett/curve25519-generic-keyp…
Browse files Browse the repository at this point in the history
…arsing

Curve25519 generic keyparsing
  • Loading branch information
SparkiDev authored Oct 31, 2024
2 parents 76e421b + 3252217 commit 24003b2
Show file tree
Hide file tree
Showing 4 changed files with 479 additions and 0 deletions.
213 changes: 213 additions & 0 deletions doc/dox_comments/header_files/asn_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,219 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output,
int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output,
word32 inLen, int with_AlgCurve, int comp);


/*!
\ingroup ASN
\brief This function decodes a Curve25519 private key (only) from a DER
encoded buffer
\return 0 Success
\return BAD_FUNC_ARG Returns if input, inOutIdx or key is null
\return ASN_PARSE_E Returns if there is an error parsing the DER encoded
data
\return ECC_BAD_ARG_E Returns if the key length is not CURVE25519_KEYSIZE or
the DER key contains other issues despite being properly formatted.
\return BUFFER_E Returns if the input buffer is too small to contain a
valid DER encoded key.
\param input Pointer to buffer containing DER encoded private key
\param inOutIdx Index to start reading input buffer from. On output,
index is set to last position parsed of input buffer.
\param key Pointer to curve25519_key structure to store decoded key
\param inSz Size of input DER buffer
\sa wc_Curve25519KeyDecode
\sa wc_Curve25519PublicKeyDecode
_Example_
\code
byte der[] = { // DER encoded key };
word32 idx = 0;
curve25519_key key;
wc_curve25519_init(&key);
if (wc_Curve25519PrivateKeyDecode(der, &idx, &key, sizeof(der)) != 0) {
// Error decoding private key
}
\endcode
*/
int wc_Curve25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz);

/*!
\ingroup ASN
\brief This function decodes a Curve25519 public key (only) from a DER
encoded buffer.
\return 0 Success
\return BAD_FUNC_ARG Returns if input, inOutIdx or key is null
\return ASN_PARSE_E Returns if there is an error parsing the DER encoded
data
\return ECC_BAD_ARG_E Returns if the key length is not CURVE25519_KEYSIZE or
the DER key contains other issues despite being properly formatted.
\return BUFFER_E Returns if the input buffer is too small to contain a
valid DER encoded key.
\param input Pointer to buffer containing DER encoded public key
\param inOutIdx Index to start reading input buffer from. On output,
index is set to last position parsed of input buffer.
\param key Pointer to curve25519_key structure to store decoded key
\param inSz Size of input DER buffer
\sa wc_Curve25519KeyDecode
\sa wc_Curve25519PrivateKeyDecode
_Example_
\code
byte der[] = { // DER encoded key };
word32 idx = 0;
curve25519_key key;
wc_curve25519_init(&key);
if (wc_Curve25519PublicKeyDecode(der, &idx, &key, sizeof(der)) != 0) {
// Error decoding public key
}
\endcode
*/
int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz);

/*!
\ingroup ASN
\brief This function decodes a Curve25519 key from a DER encoded buffer. It
can decode either a private key, a public key, or both.
\return 0 Success
\return BAD_FUNC_ARG Returns if input, inOutIdx or key is null
\return ASN_PARSE_E Returns if there is an error parsing the DER encoded
data
\return ECC_BAD_ARG_E Returns if the key length is not CURVE25519_KEYSIZE or
the DER key contains other issues despite being properly formatted.
\return BUFFER_E Returns if the input buffer is too small to contain a
valid DER encoded key.
\param input Pointer to buffer containing DER encoded key
\param inOutIdx Index to start reading input buffer from. On output,
index is set to last position parsed of input buffer.
\param key Pointer to curve25519_key structure to store decoded key
\param inSz Size of input DER buffer
\sa wc_Curve25519PrivateKeyDecode
\sa wc_Curve25519PublicKeyDecode
_Example_
\code
byte der[] = { // DER encoded key };
word32 idx = 0;
curve25519_key key;
wc_curve25519_init(&key);
if (wc_Curve25519KeyDecode(der, &idx, &key, sizeof(der)) != 0) {
// Error decoding key
}
\endcode
*/
int wc_Curve25519KeyDecode(const byte* input, word32* inOutIdx,
curve25519_key* key, word32 inSz);

/*!
\ingroup ASN
\brief This function encodes a Curve25519 private key to DER format. If the
input key structure contains a public key, it will be ignored.
\return >0 Success, length of DER encoding
\return BAD_FUNC_ARG Returns if key or output is null
\return MEMORY_E Returns if there is an allocation failure
\return BUFFER_E Returns if output buffer is too small
\param key Pointer to curve25519_key structure containing private key to
encode
\param output Buffer to hold DER encoding
\param inLen Size of output buffer
\sa wc_Curve25519KeyToDer
\sa wc_Curve25519PublicKeyToDer
_Example_
\code
curve25519_key key;
wc_curve25519_init(&key);
...
int derSz = 128; // Some appropriate size for output DER
byte der[derSz];
wc_Curve25519PrivateKeyToDer(&key, der, derSz);
\endcode
*/
int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output,
word32 inLen);

/*!
\ingroup ASN
\brief This function encodes a Curve25519 public key to DER format. If the
input key structure contains a private key, it will be ignored.
\return >0 Success, length of DER encoding
\return BAD_FUNC_ARG Returns if key or output is null
\return MEMORY_E Returns if there is an allocation failure
\return BUFFER_E Returns if output buffer is too small
\param key Pointer to curve25519_key structure containing public key to
encode
\param output Buffer to hold DER encoding
\param inLen Size of output buffer
\param withAlg Whether to include algorithm identifier in the DER encoding
\sa wc_Curve25519KeyToDer
\sa wc_Curve25519PrivateKeyToDer
_Example_
\code
curve25519_key key;
wc_curve25519_init(&key);
...
int derSz = 128; // Some appropriate size for output DER
byte der[derSz];
wc_Curve25519PublicKeyToDer(&key, der, derSz, 1);
\endcode
*/
int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
int withAlg);

/*!
\ingroup ASN
\brief This function encodes a Curve25519 key to DER format. It can encode
either a private key, a public key, or both.
\return >0 Success, length of DER encoding
\return BAD_FUNC_ARG Returns if key or output is null
\return MEMORY_E Returns if there is an allocation failure
\return BUFFER_E Returns if output buffer is too small
\param key Pointer to curve25519_key structure containing key to encode
\param output Buffer to hold DER encoding
\param inLen Size of output buffer
\param withAlg Whether to include algorithm identifier in the DER encoding
\sa wc_Curve25519PrivateKeyToDer
\sa wc_Curve25519PublicKeyToDer
_Example_
\code
curve25519_key key;
wc_curve25519_init(&key);
...
int derSz = 128; // Some appropriate size for output DER
byte der[derSz];
wc_Curve25519KeyToDer(&key, der, derSz, 1);
\endcode
*/
int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen,
int withAlg);

/*!
\ingroup ASN
Expand Down
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_PUB_KEY_SIZE];
word32 privKeyLen = CURVE25519_KEYSIZE;
word32 pubKeyLen = CURVE25519_PUB_KEY_SIZE;

/* 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_PUB_KEY_SIZE];
word32 privKeyLen = CURVE25519_KEYSIZE;
word32 pubKeyLen = CURVE25519_PUB_KEY_SIZE;

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
Loading

0 comments on commit 24003b2

Please sign in to comment.