@@ -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+
17351966exit :
17361967 return ret ;
17371968}
0 commit comments