Skip to content

Commit 876fa3b

Browse files
committed
Save cert to maxq.
Untested WIP
1 parent a207794 commit 876fa3b

File tree

1 file changed

+232
-1
lines changed

1 file changed

+232
-1
lines changed

src/internal.c

Lines changed: 232 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,10 +1701,237 @@ static int wp11_Object_Load_Cert(WP11_Object* object, int tokenId, int objId)
17011701
return ret;
17021702
}
17031703

1704+
#if defined(MAXQ10XX_PRODUCTION_KEY)
1705+
#include "maxq10xx_key.h"
1706+
#else
1707+
/* TEST KEY. This must be changed for production environments!! */
1708+
static const mxq_u1 KeyPairImport[] = {
1709+
0xd0,0x97,0x31,0xc7,0x63,0xc0,0x9e,0xe3,0x9a,0xb4,0xd0,0xce,0xa7,0x89,0xab,
1710+
0x52,0xc8,0x80,0x3a,0x91,0x77,0x29,0xc3,0xa0,0x79,0x2e,0xe6,0x61,0x8b,0x2d,
1711+
0x53,0x70,0xcc,0xa4,0x62,0xd5,0x4a,0x47,0x74,0xea,0x22,0xfa,0xa9,0xd4,0x95,
1712+
0x4e,0xca,0x32,0x70,0x88,0xd6,0xeb,0x58,0x24,0xa3,0xc5,0xbf,0x29,0xdc,0xfd,
1713+
0xe5,0xde,0x8f,0x48,0x19,0xe8,0xc6,0x4f,0xf2,0x46,0x10,0xe2,0x58,0xb9,0xb6,
1714+
0x72,0x5e,0x88,0xaf,0xc2,0xee,0x8b,0x6f,0xe5,0x36,0xe3,0x60,0x7c,0xf8,0x2c,
1715+
0xea,0x3a,0x4f,0xe3,0x6d,0x73
1716+
};
1717+
#endif /* MAXQ10XX_PRODUCTION_KEY || !DEBUG_WOLFSSL */
1718+
1719+
static int crypto_sha256(const uint8_t *buf, uint32_t len, uint8_t *hash,
1720+
uint32_t hashSz, uint32_t blkSz)
1721+
{
1722+
int ret;
1723+
uint32_t i = 0, chunk;
1724+
wc_Sha256 sha256;
1725+
1726+
/* validate arguments */
1727+
if ((buf == NULL && len > 0) || hash == NULL ||
1728+
hashSz < WC_SHA256_DIGEST_SIZE || blkSz == 0) {
1729+
return BAD_FUNC_ARG;
1730+
}
1731+
1732+
/* Init Sha256 structure */
1733+
ret = wc_InitSha256(&sha256);
1734+
if (ret != 0) {
1735+
return ret;
1736+
}
1737+
1738+
sha256.maxq_ctx.soft_hash = 1;
1739+
1740+
while (i < len) {
1741+
chunk = blkSz;
1742+
if ((chunk + i) > len) {
1743+
chunk = len - i;
1744+
}
1745+
/* Perform chunked update */
1746+
ret = wc_Sha256Update(&sha256, (buf + i), chunk);
1747+
if (ret != 0) {
1748+
break;
1749+
}
1750+
i += chunk;
1751+
}
1752+
1753+
if (ret == 0) {
1754+
/* Get final digest result */
1755+
ret = wc_Sha256Final(&sha256, hash);
1756+
}
1757+
return ret;
1758+
}
1759+
1760+
static int crypto_ecc_sign(const uint8_t *key, uint32_t keySz,
1761+
const uint8_t *hash, uint32_t hashSz, uint8_t *sig, uint32_t* sigSz,
1762+
uint32_t curveSz, int curveId, WC_RNG* rng)
1763+
{
1764+
int ret;
1765+
mp_int r, s;
1766+
ecc_key ecc;
1767+
1768+
/* validate arguments */
1769+
if (key == NULL || hash == NULL || sig == NULL || sigSz == NULL ||
1770+
curveSz == 0 || hashSz == 0 || keySz < curveSz ||
1771+
*sigSz < (curveSz * 2)) {
1772+
return BAD_FUNC_ARG;
1773+
}
1774+
1775+
/* Initialize signature result */
1776+
XMEMSET(sig, 0, curveSz * 2);
1777+
1778+
/* Setup the ECC key */
1779+
ret = wc_ecc_init(&ecc);
1780+
if (ret < 0) {
1781+
return ret;
1782+
}
1783+
1784+
ecc.maxq_ctx.hw_ecc = -1;
1785+
1786+
/* Setup the signature r/s variables */
1787+
ret = mp_init(&r);
1788+
if (ret != MP_OKAY) {
1789+
wc_ecc_free(&ecc);
1790+
return ret;
1791+
}
1792+
1793+
ret = mp_init(&s);
1794+
if (ret != MP_OKAY) {
1795+
mp_clear(&r);
1796+
wc_ecc_free(&ecc);
1797+
return ret;
1798+
}
1799+
1800+
/* Import private key "k" */
1801+
ret = wc_ecc_import_private_key_ex(key, keySz, /* private key "d" */
1802+
NULL, 0, /* public (optional) */
1803+
&ecc, curveId);
1804+
1805+
if (ret == 0) {
1806+
ret = wc_ecc_sign_hash_ex(hash, hashSz, /* computed hash digest */
1807+
rng, &ecc, /* random and key context */
1808+
&r, &s);
1809+
}
1810+
1811+
if (ret == 0) {
1812+
/* export r/s */
1813+
mp_to_unsigned_bin_len(&r, sig, curveSz);
1814+
mp_to_unsigned_bin_len(&s, sig + curveSz, curveSz);
1815+
}
1816+
1817+
mp_clear(&r);
1818+
mp_clear(&s);
1819+
wc_ecc_free(&ecc);
1820+
return ret;
1821+
}
1822+
1823+
static int ECDSA_sign(mxq_u1* dest, int* signlen, mxq_u1* key,
1824+
mxq_u1* data, mxq_length data_length, int curve)
1825+
{
1826+
int ret;
1827+
int hashlen = WC_SHA256_DIGEST_SIZE;
1828+
unsigned char hash[WC_SHA256_DIGEST_SIZE];
1829+
WC_RNG rng;
1830+
int algo = ALGO_ECDSA_SHA_256;
1831+
int wc_curve_id = ECC_SECP256R1;
1832+
int wc_curve_size = 32;
1833+
uint32_t sigSz = 0;
1834+
1835+
if (curve != MXQ_KEYPARAM_EC_P256R1) {
1836+
return BAD_FUNC_ARG;
1837+
}
1838+
1839+
sigSz = (2 * wc_curve_size);
1840+
if (*signlen < (int)sigSz) {
1841+
return BAD_FUNC_ARG;
1842+
}
1843+
1844+
ret = wc_InitRng(&rng);
1845+
if (ret != 0) {
1846+
return ret;
1847+
}
1848+
1849+
ret = crypto_sha256(data, data_length, /* input message */
1850+
hash, hashlen, /* hash digest result */
1851+
32 /* configurable block/chunk size */
1852+
);
1853+
1854+
if (ret == 0) {
1855+
ret = crypto_ecc_sign(
1856+
(key + (2 * wc_curve_size)), wc_curve_size, /* private key */
1857+
hash, hashlen, /* computed hash digest */
1858+
dest, &sigSz, /* signature r/s */
1859+
wc_curve_size, /* curve size in bytes */
1860+
wc_curve_id, /* curve id */
1861+
&rng);
1862+
1863+
*signlen = sigSz;
1864+
}
1865+
1866+
wc_FreeRng(&rng);
1867+
return ret;
1868+
}
1869+
1870+
static int wp11_maxq10xx_store_cert(int objId, byte *data, word32 len) {
1871+
1872+
DecodedCert dcert;
1873+
1874+
mxq_u1 signature[256];
1875+
int signature_len = sizeof(signature);
1876+
1877+
unsigned char sign_key[MAX_SIGNKEY_DATASIZE];
1878+
int sign_key_len = 32;
1879+
int sign_key_curve = MXQ_KEYPARAM_EC_P256R1;
1880+
int sign_key_type = MXQ_KEYTYPE_ECC;
1881+
int sign_key_algo = ALGO_ECDSA_SHA_256;
1882+
1883+
mxq_keyuse_t uu1 = MXQ_KEYUSE_VERIFY_KEY_CERT;
1884+
mxq_algo_id_t aa1 = ALGO_ECDSA_SHA_256;
1885+
mxq_keyuse_t uu2 = MXQ_KEYUSE_NONE;
1886+
mxq_algo_id_t aa2 = ALGO_NONE;
1887+
int pk_offset = 0;
1888+
1889+
mxq_keytype_id_t key_type = MXQ_KEYTYPE_ECC;
1890+
mxq_keyparam_id_t mxq_keytype = MXQ_KEYPARAM_EC_P256R1;
1891+
int keycomplen = 32;
1892+
1893+
mxq_u1 dest[2048];
1894+
mxq_length destlen = sizeof(dest);
1895+
1896+
int verifkeyid = 0x1000;
1897+
1898+
/* We need the public key offset so we need to decode the certificate. */
1899+
InitDecodedCert(&decodedCert, data, len, 0);
1900+
ret = ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL);
1901+
fprintf(stderr, "ParseCert returned %d\n");
1902+
pk_offset = decodedCert.publicKeyIndex;
1903+
1904+
if (decodedCert.signatureOID != CTC_SHA256wECDSA) {
1905+
WOLFSSL_MSG("MAXQ: signature algo not supported");
1906+
return NOT_COMPILED_IN;
1907+
}
1908+
1909+
if (decodedCert.keyOID != ECDSAk) {
1910+
WOLFSSL_MSG("MAXQ: key algo not supported");
1911+
return NOT_COMPILED_IN;
1912+
}
1913+
1914+
if (decodedCert.pkCurveOID != ECC_SECP256R1_OID) {
1915+
WOLFSSL_MSG("MAXQ: key curve not supported");
1916+
return NOT_COMPILED_IN;
1917+
}
1918+
1919+
MXQ_Build_EC_Cert(dest, &destlen, key_type, mxq_keytype, keycomplen, keycomplen, pk_offset, decodedCert.certBegin, decodedCert.sigIndex - decodedCert.certBegin, decodedCert.maxIdx, 0, 0, uu1, aa1, uu2, aa2, decodedCert.source);
1920+
1921+
XMEMCPY(sign_key, KeyPairImport, sizeof(KeyPairImport));
1922+
1923+
rc = ECDSA_sign(signature, &signature_len, sign_key, data, len,
1924+
sign_key_curve);
1925+
1926+
MXQ_ImportRootCert(objId, sign_key_algo, verifkeyid, dest, destlen, signature, signature_len);
1927+
1928+
FreeDecodedCert(&decodedCert);
1929+
}
1930+
17041931
/**
17051932
* Store an certificate to storage.
17061933
*
1707-
* @param [in] object Certificate object.
1934+
* @param [in] object Certificate object.
17081935
* @param [in] tokenId Id of token this cert belongs to.
17091936
* @param [in] objId Id of object for token.
17101937
* @return 0 on success.
@@ -1732,6 +1959,10 @@ static int wp11_Object_Store_Cert(WP11_Object* object, int tokenId, int objId)
17321959
wp11_storage_close(storage);
17331960
}
17341961

1962+
/* todo: write a function that saves to maxq and call it here. ensure objID
1963+
* is a hex string. The function should be based on code from
1964+
* maxq10xx_rootcert-import.c. */
1965+
17351966
exit:
17361967
return ret;
17371968
}

0 commit comments

Comments
 (0)