1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 *
4 * LibTomCrypt is a library that provides various cryptographic
5 * algorithms in a highly modular and flexible manner.
6 *
7 * The library is free for all purposes without any express
8 * guarantee it works.
9 */
10 #include "tomcrypt_private.h"
11
12 /**
13 @file ec25519_export.c
14 Generic export of a Curve/Ed25519 key to a binary packet, Steffen Jaeckel
15 */
16
17 #ifdef LTC_CURVE25519
18
19 /**
20 Generic export of a Curve/Ed25519 key to a binary packet
21 @param out [out] The destination for the key
22 @param outlen [in/out] The max size and resulting size of the Ed25519 key
23 @param type Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
24 @param key The key you wish to export
25 @return CRYPT_OK if successful
26 */
ec25519_export(unsigned char * out,unsigned long * outlen,int which,const curve25519_key * key)27 int ec25519_export( unsigned char *out, unsigned long *outlen,
28 int which,
29 const curve25519_key *key)
30 {
31 int err, std;
32 const char* OID;
33 unsigned long oid[16], oidlen;
34 ltc_asn1_list alg_id[1];
35 unsigned char private_key[34];
36 unsigned long version, private_key_len = sizeof(private_key);
37
38 LTC_ARGCHK(out != NULL);
39 LTC_ARGCHK(outlen != NULL);
40 LTC_ARGCHK(key != NULL);
41
42 std = which & PK_STD;
43 which &= ~PK_STD;
44
45 if (which == PK_PRIVATE) {
46 if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
47
48 if (std == PK_STD) {
49 if ((err = pk_get_oid(key->algo, &OID)) != CRYPT_OK) {
50 return err;
51 }
52 oidlen = sizeof(oid)/sizeof(oid[0]);
53 if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
54 return err;
55 }
56
57 LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
58
59 /* encode private key as PKCS#8 */
60 if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
61 return err;
62 }
63
64 version = 0;
65 err = der_encode_sequence_multi(out, outlen,
66 LTC_ASN1_SHORT_INTEGER, 1uL, &version,
67 LTC_ASN1_SEQUENCE, 1uL, alg_id,
68 LTC_ASN1_OCTET_STRING, private_key_len, private_key,
69 LTC_ASN1_EOL, 0uL, NULL);
70 } else {
71 if (*outlen < sizeof(key->priv)) {
72 err = CRYPT_BUFFER_OVERFLOW;
73 } else {
74 XMEMCPY(out, key->priv, sizeof(key->priv));
75 err = CRYPT_OK;
76 }
77 *outlen = sizeof(key->priv);
78 }
79 } else {
80 if (std == PK_STD) {
81 /* encode public key as SubjectPublicKeyInfo */
82 err = x509_encode_subject_public_key_info(out, outlen, key->algo, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
83 } else {
84 if (*outlen < sizeof(key->pub)) {
85 err = CRYPT_BUFFER_OVERFLOW;
86 } else {
87 XMEMCPY(out, key->pub, sizeof(key->pub));
88 err = CRYPT_OK;
89 }
90 *outlen = sizeof(key->pub);
91 }
92 }
93
94 return err;
95 }
96
97 #endif
98
99 /* ref: $Format:%D$ */
100 /* git commit: $Format:%H$ */
101 /* commit time: $Format:%ai$ */
102