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