AuroraRuntime/Source/Extensions/LTC/LTCExport.c
2021-06-27 22:25:29 +01:00

144 lines
4.1 KiB
C

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: LTCExport.c
Date: 2021-6-24
Author: Reece
***/
#include <tomcrypt.h>
#include "tomcrypt_private.h"
#include "LTCExtensions.h"
int rsa_basic_export(unsigned char *out, unsigned long *outlen, const rsa_key *key, int flags)
{
unsigned long zero = 0;
int err;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(key != NULL);
if ((flags & kRsaFlagPublic) == 0)
{
if (key->type == PK_PUBLIC)
{
return CRYPT_INVALID_ARG;
};
/* private key */
/* output is
Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p
*/
return der_encode_sequence_multi(out, outlen,
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
LTC_ASN1_INTEGER, 1UL, key->N,
LTC_ASN1_INTEGER, 1UL, key->e,
LTC_ASN1_INTEGER, 1UL, key->d,
LTC_ASN1_INTEGER, 1UL, key->p,
LTC_ASN1_INTEGER, 1UL, key->q,
LTC_ASN1_INTEGER, 1UL, key->dP,
LTC_ASN1_INTEGER, 1UL, key->dQ,
LTC_ASN1_INTEGER, 1UL, key->qP,
LTC_ASN1_EOL, 0UL, NULL);
}
else
{
/* public key */
unsigned long tmplen, *ptmplen;
unsigned char *tmp = NULL;
if (key->type != PK_PUBLIC)
{
return CRYPT_INVALID_ARG;
}
return der_encode_sequence_multi(out, outlen,
LTC_ASN1_INTEGER, 1UL, key->N,
LTC_ASN1_INTEGER, 1UL, key->e,
LTC_ASN1_EOL, 0UL, NULL);
}
}
int rsa_pkcs8_export(unsigned char *out, unsigned long *outlen, const rsa_key *key, int flags)
{
int ret;
char temp[4096];
unsigned long length = sizeof(temp);
if ((ret = rsa_basic_export(temp, &length, key, flags)) != CRYPT_OK)
{
return ret;
}
if ((flags & kRsaFlagPKCS1) != 0)
{
if (*outlen < length)
{
*outlen = length;
return CRYPT_BUFFER_OVERFLOW;
}
memcpy(out, temp, length);
return CRYPT_OK;
}
else
{
unsigned long oid[16];
unsigned long *oidReference;
ltc_asn1_list alg_seq[2];
ret = pk_get_oid(PKA_RSA, &oidReference);
if (ret != CRYPT_OK)
{
return ret;
}
unsigned long oidArraySize = 16;
ret = pk_oid_str_to_num(oidReference, oid, &oidArraySize);
if (ret != CRYPT_OK)
{
return ret;
}
LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidArraySize);
LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_NULL, NULL, 0UL);
if ((flags & kRsaFlagPublic) == 0)
{
if (key->type == PK_PUBLIC)
{
return CRYPT_INVALID_ARG;
};
void *keyType;
mp_init(&keyType);
mp_set_int(keyType, 0);
ret = der_encode_sequence_multi(out, outlen,
LTC_ASN1_INTEGER, 1, keyType,
LTC_ASN1_SEQUENCE, 2, alg_seq,
LTC_ASN1_OCTET_STRING, length, temp,
LTC_ASN1_EOL, 0UL, NULL);
mp_clear(keyType);
}
else
{
if (key->type != PK_PUBLIC)
{
return CRYPT_INVALID_ARG;
}
ret = der_encode_sequence_multi(out, outlen,
LTC_ASN1_SEQUENCE, 1, alg_seq,
LTC_ASN1_BIT_STRING, length, temp,
LTC_ASN1_EOL, 0UL, NULL);
}
return ret;
}
}