1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797 |
- /* rsa.c
- *
- * Copyright (C) 2006-2023 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
- #ifdef HAVE_CONFIG_H /* configure options when using autoconf */
- #include <config.h>
- #endif
- #include <wolfssl/options.h>
- #include <wolfssl/wolfcrypt/types.h>
- #ifndef NO_RSA
- #define USER_CRYPTO_ERROR -101
- #ifdef OPENSSL_EXTRA
- #include <wolfssl/openssl/rsa.h> /* include for openssl compatibility */
- #include <wolfssl/openssl/bn.h>
- #endif
- #include "user_rsa.h"
- #ifdef DEBUG_WOLFSSL /* debug done without variadic to allow older compilers */
- #include <stdio.h>
- #define USER_DEBUG(x) printf x
- #else
- #define USER_DEBUG(x) WC_DO_NOTHING
- #endif
- #define ASN_INTEGER 0x02
- #define ASN_BIT_STRING 0x03
- #define ASN_TAG_NULL 0x05
- #define ASN_OBJECT_ID 0x06
- /* Make sure compiler doesn't skip -- used from wolfSSL */
- static inline void ForceZero(const void* mem, word32 len)
- {
- volatile byte* z = (volatile byte*)mem;
- while (len--) *z++ = 0;
- }
- enum {
- RSA_PUBLIC_ENCRYPT = 0,
- RSA_PUBLIC_DECRYPT = 1,
- RSA_PRIVATE_ENCRYPT = 2,
- RSA_PRIVATE_DECRYPT = 3,
- RSA_BLOCK_TYPE_1 = 1,
- RSA_BLOCK_TYPE_2 = 2,
- RSA_MIN_SIZE = 512,
- RSA_MAX_SIZE = 4096, /* max allowed in IPP library */
- RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */
- };
- int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId)
- {
- USER_DEBUG(("Entering wc_InitRsaKey\n"));
- if (key == NULL)
- return USER_CRYPTO_ERROR;
- /* set full struct as 0 */
- ForceZero(key, sizeof(RsaKey));
- USER_DEBUG(("\tExit wc_InitRsaKey\n"));
- (void)devId;
- (void)heap;
- return 0;
- }
- int wc_InitRsaKey(RsaKey* key, void* heap)
- {
- return wc_InitRsaKey_ex(key, heap, INVALID_DEVID);
- }
- /* three functions needed for cert and key gen */
- #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)
- /* return 1 if there is a leading bit*/
- int wc_Rsa_leading_bit(void* bn)
- {
- int ret = 0;
- int dataSz;
- Ipp32u* data;
- Ipp32u q;
- int qSz = sizeof(Ipp32u);
- if (ippsExtGet_BN(NULL, &dataSz, NULL, bn) != ippStsNoErr) {
- USER_DEBUG(("ippsExtGet_BN Rsa leading bit error\n"));
- return USER_CRYPTO_ERROR;
- }
- /* convert from size in binary to Ipp32u */
- dataSz = dataSz / 32 + ((dataSz % 32)? 1 : 0);
- data = (Ipp32u*)XMALLOC(dataSz * sizeof(Ipp32u), NULL,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (data == NULL) {
- USER_DEBUG(("Rsa leading bit memory error\n"));
- return 0;
- }
- /* extract value from BN */
- if (ippsExtGet_BN(NULL, NULL, data, bn) != ippStsNoErr) {
- USER_DEBUG(("Rsa leading bit error\n"));
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return 0;
- }
- /* use method like what's used in wolfssl tfm.c */
- q = data[dataSz - 1];
- ret = 0;
- while (qSz > 0) {
- if (q != 0)
- ret = (q & 0x80) != 0;
- q >>= 8;
- qSz--;
- }
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return ret;
- }
- /* get the size in bytes of BN */
- int wc_Rsa_unsigned_bin_size(void* bn)
- {
- int ret = 0;
- if (ippsExtGet_BN(NULL, &ret, NULL, bn) != ippStsNoErr) {
- USER_DEBUG(("Rsa unsigned bin size error\n"));
- return USER_CRYPTO_ERROR;
- }
- return (ret / 8) + ((ret % 8)? 1: 0); /* size in bytes */
- }
- #ifndef MP_OKAY
- #define MP_OKAY 0
- #endif
- /* extract the bn value to a unsigned byte array and return MP_OKAY on success */
- int wc_Rsa_to_unsigned_bin(void* bn, byte* in, int inLen)
- {
- if (ippsGetOctString_BN((Ipp8u*)in, inLen, bn) != ippStsNoErr) {
- USER_DEBUG(("Rsa to unsigned bin error\n"));
- return USER_CRYPTO_ERROR;
- }
- return MP_OKAY;
- }
- #endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN || OPENSSL_EXTRA */
- #ifdef OPENSSL_EXTRA /* functions needed for openssl compatibility layer */
- static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, IppsBigNumState* in)
- {
- IppStatus ret;
- byte* data;
- int sz;
- USER_DEBUG(("Entering SetIndividualExternal\n"));
- if (bn == NULL || in == NULL) {
- USER_DEBUG(("inputs NULL error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (*bn == NULL) {
- *bn = wolfSSL_BN_new();
- if (*bn == NULL) {
- USER_DEBUG(("SetIndividualExternal alloc failed\n"));
- return USER_CRYPTO_ERROR;
- }
- }
- /* get size of array needed and extract oct array of data */
- ret = ippsGetSize_BN(in, &sz);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- data = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (data == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsGetOctString_BN(data, sz, in);
- if (ret != ippStsNoErr) {
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return USER_CRYPTO_ERROR;
- }
- /* store the data into a wolfSSL Big Number */
- *bn = wolfSSL_BN_bin2bn(data, sz, *bn);
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return 0;
- }
- static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, IppsBigNumState** mpi)
- {
- int length, ctxSz, sz;
- IppStatus ret;
- Ipp8u* data;
- USER_DEBUG(("Entering SetIndividualInternal\n"));
- if (bn == NULL || bn->internal == NULL) {
- USER_DEBUG(("bn NULL error\n"));
- return USER_CRYPTO_ERROR;
- }
- length = wolfSSL_BN_num_bytes(bn);
- /* if not IPP BN then create one */
- if (*mpi == NULL) {
- ret = ippsBigNumGetSize(length, &ctxSz);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- *mpi = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (*mpi == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsBigNumInit(length, *mpi);
- if (ret != ippStsNoErr) {
- XFREE(*mpi, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return USER_CRYPTO_ERROR;
- }
- }
- /* get the size of array needed and check IPP BigNum */
- if (ippsGetSize_BN(*mpi, &sz) != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- if (sz < length) {
- USER_DEBUG(("big num size is too small\n"));
- return USER_CRYPTO_ERROR;
- }
- data = (Ipp8u*)XMALLOC(length, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (data == NULL)
- return USER_CRYPTO_ERROR;
- /* extract the wolfSSL BigNum and store it into IPP BigNum */
- if (wolfSSL_BN_bn2bin(bn, data) < 0) {
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- USER_DEBUG(("error in getting bin from wolfssl bn\n"));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsSetOctString_BN(data, length, *mpi);
- if (ret != ippStsNoErr) {
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return USER_CRYPTO_ERROR;
- }
- XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return 0;
- }
- /* WolfSSL -> OpenSSL */
- int SetRsaExternal(WOLFSSL_RSA* rsa)
- {
- RsaKey* key;
- USER_DEBUG(("Entering SetRsaExternal\n"));
- if (rsa == NULL || rsa->internal == NULL) {
- USER_DEBUG(("rsa key NULL error\n"));
- return USER_CRYPTO_ERROR;
- }
- key = (RsaKey*)rsa->internal;
- if (SetIndividualExternal(&rsa->n, key->n) != 0) {
- USER_DEBUG(("rsa n key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualExternal(&rsa->e, key->e) != 0) {
- USER_DEBUG(("rsa e key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (key->type == RSA_PRIVATE) {
- if (SetIndividualExternal(&rsa->d, key->dipp) != 0) {
- USER_DEBUG(("rsa d key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualExternal(&rsa->p, key->pipp) != 0) {
- USER_DEBUG(("rsa p key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualExternal(&rsa->q, key->qipp) != 0) {
- USER_DEBUG(("rsa q key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualExternal(&rsa->dmp1, key->dPipp) != 0) {
- USER_DEBUG(("rsa dP key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualExternal(&rsa->dmq1, key->dQipp) != 0) {
- USER_DEBUG(("rsa dQ key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualExternal(&rsa->iqmp, key->uipp) != 0) {
- USER_DEBUG(("rsa u key error\n"));
- return USER_CRYPTO_ERROR;
- }
- }
- rsa->exSet = 1;
- /* SSL_SUCCESS */
- return 1;
- }
- /* Openssl -> WolfSSL */
- int SetRsaInternal(WOLFSSL_RSA* rsa)
- {
- int ctxSz, pSz, qSz;
- IppStatus ret;
- RsaKey* key;
- USER_DEBUG(("Entering SetRsaInternal\n"));
- if (rsa == NULL || rsa->internal == NULL) {
- USER_DEBUG(("rsa key NULL error\n"));
- return USER_CRYPTO_ERROR;
- }
- key = (RsaKey*)rsa->internal;
- if (SetIndividualInternal(rsa->n, &key->n) != 0) {
- USER_DEBUG(("rsa n key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (SetIndividualInternal(rsa->e, &key->e) != 0) {
- USER_DEBUG(("rsa e key error\n"));
- return USER_CRYPTO_ERROR;
- }
- /* public key */
- key->type = RSA_PUBLIC;
- if (rsa->d != NULL) {
- if (SetIndividualInternal(rsa->d, &key->dipp) != 0) {
- USER_DEBUG(("rsa d key error\n"));
- return USER_CRYPTO_ERROR;
- }
- /* private key */
- key->type = RSA_PRIVATE;
- }
- if (rsa->p != NULL &&
- SetIndividualInternal(rsa->p, &key->pipp) != 0) {
- USER_DEBUG(("rsa p key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (rsa->q != NULL &&
- SetIndividualInternal(rsa->q, &key->qipp) != 0) {
- USER_DEBUG(("rsa q key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (rsa->dmp1 != NULL &&
- SetIndividualInternal(rsa->dmp1, &key->dPipp) != 0) {
- USER_DEBUG(("rsa dP key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (rsa->dmq1 != NULL &&
- SetIndividualInternal(rsa->dmq1, &key->dQipp) != 0) {
- USER_DEBUG(("rsa dQ key error\n"));
- return USER_CRYPTO_ERROR;
- }
- if (rsa->iqmp != NULL &&
- SetIndividualInternal(rsa->iqmp, &key->uipp) != 0) {
- USER_DEBUG(("rsa u key error\n"));
- return USER_CRYPTO_ERROR;
- }
- rsa->inSet = 1;
- /* get sizes of IPP BN key states created from input */
- ret = ippsGetSize_BN(key->n, &key->nSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsGetSize_BN(key->e, &key->eSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->sz = key->nSz; /* set modulus size */
- /* convert to size in bits */
- key->nSz = key->nSz * 8;
- key->eSz = key->eSz * 8;
- /* set up public key state */
- ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPub == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_SetPublicKey error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- if (key->pipp != NULL && key->qipp != NULL && key->dipp != NULL &&
- key->dPipp != NULL && key->dQipp != NULL && key->uipp != NULL) {
- /* get bn sizes needed for private key set up */
- ret = ippsGetSize_BN(key->pipp, &pSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsGetSize_BN(key->qipp, &qSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* store sizes needed for creating tmp private keys */
- ret = ippsGetSize_BN(key->dipp, &key->dSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* convert to size in bits */
- key->dSz = key->dSz * 8;
- pSz = pSz * 8;
- qSz = qSz * 8;
- /* set up private key state */
- ret = ippsRSA_GetSizePrivateKeyType2(pSz, qSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->prvSz = ctxSz;
- key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPrv == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSA_InitPrivateKeyType2(pSz, qSz, key->pPrv, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsRSA_SetPrivateKeyType2(key->pipp, key->qipp, key->dPipp,
- key->dQipp, key->uipp, key->pPrv);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- }
- /* SSL_SUCCESS */
- return 1;
- }
- #endif /* OPENSSLEXTRA */
- /* Padding scheme function used in wolfSSL for signing needed for matching
- existing API signing scheme
- input : the msg to be signed
- inputLen : length of input msg
- pkcsBlock : the outputted padded msg
- pkcsBlockLen : length of outputted padded msg buffer
- padValue : the padded value after first 00 , is either 01 or 02
- rng : random number generator structure
- */
- static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
- word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
- {
- if (inputLen == 0 || pkcsBlockLen == 0) {
- return USER_CRYPTO_ERROR;
- }
- pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
- pkcsBlock++; pkcsBlockLen--;
- pkcsBlock[0] = padValue; /* insert padValue */
- if (padValue == RSA_BLOCK_TYPE_1) {
- if (pkcsBlockLen < inputLen + 2) {
- return USER_CRYPTO_ERROR;
- }
- /* pad with 0xff bytes */
- XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
- }
- else {
- /* pad with non-zero random bytes */
- word32 padLen, i;
- int ret;
- if (pkcsBlockLen < inputLen + 1) {
- return USER_CRYPTO_ERROR;
- }
- padLen = pkcsBlockLen - inputLen - 1;
- ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
- if (ret != 0)
- return ret;
- /* remove zeros */
- for (i = 1; i < padLen; i++)
- if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
- }
- pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
- XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
- return 0;
- }
- /* UnPad plaintext, set start to *output, return length of plaintext,
- * < 0 on error */
- static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
- byte **output, byte padValue)
- {
- word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
- invalid = 0,
- i = 1,
- outputLen;
- if (pkcsBlockLen == 0) {
- return USER_CRYPTO_ERROR;
- }
- if (pkcsBlock[0] != 0x0) /* skip past zero */
- invalid = 1;
- pkcsBlock++; pkcsBlockLen--;
- /* Require block type padValue */
- invalid = (pkcsBlock[0] != padValue) || invalid;
- /* verify the padding until we find the separator */
- if (padValue == RSA_BLOCK_TYPE_1) {
- while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
- }
- else {
- while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
- }
- if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
- USER_DEBUG(("RsaUnPad error, bad formatting\n"));
- return USER_CRYPTO_ERROR;
- }
- outputLen = pkcsBlockLen - i;
- invalid = (outputLen > maxOutputLen) || invalid;
- if (invalid) {
- USER_DEBUG(("RsaUnPad error, bad formatting\n"));
- return USER_CRYPTO_ERROR;
- }
- *output = (byte *)(pkcsBlock + i);
- return outputLen;
- }
- /* Set up memory and structure for a Big Number
- * returns ippStsNoErr on success
- */
- static IppStatus init_bn(IppsBigNumState** in, int sz)
- {
- int ctxSz;
- IppStatus ret;
- ret = ippsBigNumGetSize(sz, &ctxSz);
- if (ret != ippStsNoErr) {
- return ret;
- }
- *in = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (*in == NULL) {
- return ippStsNoMemErr;
- }
- ret = ippsBigNumInit(sz, *in);
- if (ret != ippStsNoErr) {
- XFREE(*in, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- *in = NULL;
- return ret;
- }
- return ippStsNoErr;
- }
- /* Set up memory and structure for a Montgomery struct
- * returns ippStsNoErr on success
- */
- static IppStatus init_mont(IppsMontState** mont, int* ctxSz,
- IppsBigNumState* modul)
- {
- int mSz;
- Ipp32u* m;
- IppStatus ret;
- ret = ippsExtGet_BN(NULL, ctxSz, NULL, modul);
- if (ret != ippStsNoErr) {
- return ret;
- }
- /* convert bits to Ipp32u array size and round up
- 32 is number of bits in type */
- mSz = (*ctxSz/32)+((*ctxSz % 32)? 1: 0);
- m = (Ipp32u*)XMALLOC(mSz * sizeof(Ipp32u), 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (m == NULL) {
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return ippStsNoMemErr;
- }
- ret = ippsExtGet_BN(NULL, NULL, m, modul);
- if (ret != ippStsNoErr) {
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return ret;
- }
- ret = ippsMontGetSize(IppsSlidingWindows, mSz, ctxSz);
- if (ret != ippStsNoErr) {
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return ret;
- }
- /* 2. Allocate working buffer using malloc */
- *mont = (IppsMontState*)XMALLOC(*ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (*mont == NULL) {
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return ippStsNoMemErr;
- }
- ret = ippsMontInit(IppsSlidingWindows, mSz, *mont);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsMontInit error of %s\n", ippGetStatusString(ret)));
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(*mont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- *mont = NULL;
- return ret;
- }
- /* 3. Call the function MontSet to set big number module */
- ret = ippsMontSet(m, mSz, *mont);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsMontSet error of %s\n", ippGetStatusString(ret)));
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(*mont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- *mont = NULL;
- return ret;
- }
- XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return ippStsNoErr;
- }
- int wc_FreeRsaKey(RsaKey* key)
- {
- if (key == NULL)
- return 0;
- USER_DEBUG(("Entering wc_FreeRsaKey\n"));
- if (key->pPub != NULL) {
- XFREE(key->pPub, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->pPub = NULL;
- }
- if (key->pPrv != NULL) {
- /* write over sensitive information */
- ForceZero(key->pPrv, key->prvSz);
- XFREE(key->pPrv, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->pPrv = NULL;
- }
- if (key->n != NULL) {
- XFREE(key->n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->n = NULL;
- }
- if (key->e != NULL) {
- XFREE(key->e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->e = NULL;
- }
- if (key->dipp != NULL) {
- XFREE(key->dipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->dipp = NULL;
- }
- if (key->pipp != NULL) {
- XFREE(key->pipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->pipp = NULL;
- }
- if (key->qipp != NULL) {
- XFREE(key->qipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->qipp = NULL;
- }
- if (key->dPipp != NULL) {
- XFREE(key->dPipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->dPipp = NULL;
- }
- if (key->dQipp != NULL) {
- XFREE(key->dQipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->dQipp = NULL;
- }
- if (key->uipp != NULL) {
- XFREE(key->uipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- key->uipp = NULL;
- }
- USER_DEBUG(("\tExit wc_FreeRsaKey\n"));
- (void)key;
- return 0;
- }
- /* Some parsing functions from wolfSSL code needed to match wolfSSL API used */
- static int GetLength(const byte* input, word32* inOutIdx, int* len,
- word32 maxIdx)
- {
- int length = 0;
- word32 idx = *inOutIdx;
- byte b;
- *len = 0; /* default length */
- if ((idx + 1) > maxIdx) { /* for first read */
- USER_DEBUG(("GetLength bad index on input\n"));
- return USER_CRYPTO_ERROR;
- }
- b = input[idx++];
- if (b >= 0x80) {
- word32 bytes = b & 0x7F;
- if ((idx + bytes) > maxIdx) { /* for reading bytes */
- USER_DEBUG(("GetLength bad long length\n"));
- return USER_CRYPTO_ERROR;
- }
- while (bytes--) {
- b = input[idx++];
- length = (length << 8) | b;
- }
- }
- else
- length = b;
- if ((idx + length) > maxIdx) { /* for user of length */
- USER_DEBUG(("GetLength value exceeds buffer length\n"));
- return USER_CRYPTO_ERROR;
- }
- *inOutIdx = idx;
- if (length > 0)
- *len = length;
- return length;
- }
- static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
- word32 maxIdx)
- {
- word32 idx = *inOutIdx;
- byte b;
- int length;
- if ((idx + 1) > maxIdx)
- return USER_CRYPTO_ERROR;
- b = input[idx++];
- if (b != tag)
- return USER_CRYPTO_ERROR;
- if (GetLength(input, &idx, &length, maxIdx) < 0)
- return USER_CRYPTO_ERROR;
- *len = length;
- *inOutIdx = idx;
- return length;
- }
- static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
- word32 maxIdx)
- {
- int ret;
- ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
- if (ret < 0)
- return ret;
- if (*len > 0) {
- /* remove leading zero, unless there is only one 0x00 byte */
- if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
- (*inOutIdx)++;
- (*len)--;
- if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
- return USER_CRYPTO_ERROR;
- }
- }
- return 0;
- }
- static int GetInt(IppsBigNumState** mpi, const byte* input, word32* inOutIdx,
- word32 maxIdx)
- {
- IppStatus ret;
- word32 idx = *inOutIdx;
- int length;
- int ctxSz;
- if (GetASNInt(input, &idx, &length, maxIdx) < 0) {
- return USER_CRYPTO_ERROR;
- }
- ret = ippsBigNumGetSize(length, &ctxSz);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- *mpi = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (*mpi == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsBigNumInit(length, *mpi);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- ret = ippsSetOctString_BN((Ipp8u*)input + idx, length, *mpi);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- *inOutIdx = idx + length;
- return 0;
- }
- static int GetSequence(const byte* input, word32* inOutIdx, int* len,
- word32 maxIdx)
- {
- int length = -1;
- word32 idx = *inOutIdx;
- if ((idx + 1) > maxIdx)
- return USER_CRYPTO_ERROR;
- if (input[idx++] != (0x10 | 0x20) ||
- GetLength(input, &idx, &length, maxIdx) < 0)
- return USER_CRYPTO_ERROR;
- *len = length;
- *inOutIdx = idx;
- return length;
- }
- static int GetMyVersion(const byte* input, word32* inOutIdx,
- int* version, word32 maxIdx)
- {
- word32 idx = *inOutIdx;
- if ((idx + 3) > maxIdx)
- return USER_CRYPTO_ERROR;
- if (input[idx++] != 0x02)
- return USER_CRYPTO_ERROR;
- if (input[idx++] != 0x01)
- return USER_CRYPTO_ERROR;
- *version = input[idx++];
- *inOutIdx = idx;
- return *version;
- }
- int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
- word32 inSz)
- {
- int version, length;
- int ctxSz, pSz, qSz;
- IppStatus ret;
- if (input == NULL || inOutIdx == NULL || key == NULL) {
- return USER_CRYPTO_ERROR;
- }
- USER_DEBUG(("Entering wc_RsaPrivateKeyDecode\n"));
- /* read in key information */
- if (GetSequence(input, inOutIdx, &length, inSz) < 0)
- return USER_CRYPTO_ERROR;
- if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
- return USER_CRYPTO_ERROR;
- key->type = RSA_PRIVATE;
- if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->dipp, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->pipp, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->qipp, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->dPipp, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->dQipp, input, inOutIdx, inSz) < 0 ||
- GetInt(&key->uipp, input, inOutIdx, inSz) < 0 )
- return USER_CRYPTO_ERROR;
- /* get sizes of IPP BN key states created from input */
- ret = ippsGetSize_BN(key->n, &key->nSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsGetSize_BN(key->e, &key->eSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->sz = key->nSz; /* set modulus size */
- /* convert to size in bits */
- key->nSz = key->nSz * 8;
- key->eSz = key->eSz * 8;
- /* set up public key state */
- ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPub == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* get bn sizes needed for private key set up */
- ret = ippsGetSize_BN(key->pipp, &pSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsGetSize_BN(key->qipp, &qSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* store sizes needed for creating tmp private keys */
- ret = ippsGetSize_BN(key->dipp, &key->dSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* convert to size in bits */
- key->dSz = key->dSz * 8;
- pSz = pSz * 8;
- qSz = qSz * 8;
- /* set up private key state */
- ret = ippsRSA_GetSizePrivateKeyType2(pSz, qSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->prvSz = ctxSz;
- key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPrv == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSA_InitPrivateKeyType2(pSz, qSz, key->pPrv, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsRSA_SetPrivateKeyType2(key->pipp, key->qipp, key->dPipp,
- key->dQipp, key->uipp, key->pPrv);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- USER_DEBUG(("\tExit wc_RsaPrivateKeyDecode\n"));
- return 0;
- }
- int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
- word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz)
- {
- IppStatus ret = 0;
- int length;
- #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
- byte b;
- #endif
- if (input == NULL || inOutIdx == NULL) {
- return USER_CRYPTO_ERROR;
- }
- USER_DEBUG(("Entering wc_RsaPublicKeyDecode_ex\n"));
- if (GetSequence(input, inOutIdx, &length, inSz) < 0)
- return USER_CRYPTO_ERROR;
- #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
- if ((*inOutIdx + 1) > inSz)
- return USER_CRYPTO_ERROR;
- b = input[*inOutIdx];
- if (b != ASN_INTEGER) {
- /* not from decoded cert, will have algo id, skip past */
- if (GetSequence(input, inOutIdx, &length, inSz) < 0)
- return USER_CRYPTO_ERROR;
- b = input[(*inOutIdx)++];
- if (b != ASN_OBJECT_ID)
- return USER_CRYPTO_ERROR;
- if (GetLength(input, inOutIdx, &length, inSz) < 0)
- return USER_CRYPTO_ERROR;
- *inOutIdx += length; /* skip past */
- /* could have NULL tag and 0 terminator, but may not */
- b = input[(*inOutIdx)++];
- if (b == ASN_TAG_NULL) {
- b = input[(*inOutIdx)++];
- if (b != 0)
- return USER_CRYPTO_ERROR;
- }
- else {
- /* go back, didn't have it */
- (*inOutIdx)--;
- }
- /* should have bit tag length and seq next */
- b = input[(*inOutIdx)++];
- if (b != ASN_BIT_STRING)
- return USER_CRYPTO_ERROR;
- if (GetLength(input, inOutIdx, &length, inSz) <= 0)
- return USER_CRYPTO_ERROR;
- /* could have 0 */
- b = input[(*inOutIdx)++];
- if (b != 0)
- (*inOutIdx)--;
- if (GetSequence(input, inOutIdx, &length, inSz) < 0)
- return USER_CRYPTO_ERROR;
- }
- #endif /* OPENSSL_EXTRA || RSA_DECODE_EXTRA */
- /* Get modulus */
- ret = GetASNInt(input, inOutIdx, &length, inSz);
- if (ret < 0) {
- return USER_CRYPTO_ERROR;
- }
- if (nSz)
- *nSz = length;
- if (n)
- *n = &input[*inOutIdx];
- *inOutIdx += length;
- /* Get exponent */
- ret = GetASNInt(input, inOutIdx, &length, inSz);
- if (ret < 0) {
- return USER_CRYPTO_ERROR;
- }
- if (eSz)
- *eSz = length;
- if (e)
- *e = &input[*inOutIdx];
- *inOutIdx += length;
- USER_DEBUG(("\tExit wc_RsaPublicKeyDecode_ex\n"));
- return ret;
- }
- /* read in a public RSA key */
- int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
- word32 inSz)
- {
- IppStatus ret;
- const byte *n = NULL, *e = NULL;
- word32 nSz = 0, eSz = 0;
- if (key == NULL)
- return USER_CRYPTO_ERROR;
- USER_DEBUG(("Entering wc_RsaPublicKeyDecode\n"));
- ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
- if (ret == 0) {
- ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
- }
- USER_DEBUG(("\tExit RsaPublicKeyDecode\n"));
- return ret;
- }
- /* import RSA public key elements (n, e) into RsaKey structure (key) */
- int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
- word32 eSz, RsaKey* key)
- {
- IppStatus ret;
- int ctxSz;
- USER_DEBUG(("Entering wc_RsaPublicKeyDecodeRaw\n"));
- if (n == NULL || e == NULL || key == NULL)
- return USER_CRYPTO_ERROR;
- /* set up IPP key states -- read in n */
- ret = init_bn(&key->n, nSz);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- ret = ippsSetOctString_BN((Ipp8u*)n, nSz, key->n);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- /* read in e */
- ret = init_bn(&key->e, eSz);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- ret = ippsSetOctString_BN((Ipp8u*)e, eSz, key->e);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- /* store size and convert to binary */
- key->sz = nSz;
- nSz = nSz * 8;
- eSz = eSz * 8;
- /* set up public key state */
- ret = ippsRSA_GetSizePublicKey(nSz, eSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPub == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSA_InitPublicKey(nSz, eSz, key->pPub, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsRSA_SetPublicKey(key->n,key->e, key->pPub);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- key->nSz = nSz;
- key->eSz = eSz;
- key->type = RSA_PUBLIC;
- return 0;
- }
- /* encrypt using PKCS v15 */
- int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
- RsaKey* key, WC_RNG* rng)
- {
- IppStatus ret;
- Ipp8u* scratchBuffer;
- int scratchSz;
- if (key == NULL || in == NULL || out == NULL)
- return USER_CRYPTO_ERROR;
- if (key->pPub == NULL || outLen < key->sz)
- return USER_CRYPTO_ERROR;
- /* set size of scratch buffer */
- ret = ippsRSA_GetBufferSizePublicKey(&scratchSz, key->pPub);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (scratchBuffer == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSAEncrypt_PKCSv15((Ipp8u*)in, inLen, NULL, (Ipp8u*)out,
- key->pPub, scratchBuffer);
- if (ret != ippStsNoErr) {
- XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- USER_DEBUG(("encrypt error of %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- (void)rng;
- return key->sz;
- }
- /* decrypt using PLCS v15 */
- int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
- RsaKey* key)
- {
- IppStatus ret;
- Ipp8u* scratchBuffer;
- int scratchSz;
- int outSz;
- if (in == NULL || out == NULL || key == NULL)
- return USER_CRYPTO_ERROR;
- if (key->pPrv == NULL || inLen != key->sz)
- return USER_CRYPTO_ERROR;
- outSz = outLen;
- /* set size of scratch buffer */
- ret = ippsRSA_GetBufferSizePrivateKey(&scratchSz, key->pPrv);
- if (ret != ippStsNoErr) {
- return USER_CRYPTO_ERROR;
- }
- scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (scratchBuffer == NULL) {
- return USER_CRYPTO_ERROR;
- }
- /* perform decryption using IPP */
- ret = ippsRSADecrypt_PKCSv15((Ipp8u*)in, (Ipp8u*)out, &outSz, key->pPrv,
- scratchBuffer);
- if (ret != ippStsNoErr) {
- XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- USER_DEBUG(("decrypt error of %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return outSz;
- }
- /* out is a pointer that is set to the location in byte array "in" where input
- data has been decrypted */
- int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
- {
- int outSz;
- byte* tmp;
- USER_DEBUG(("Entering wc_RsaPrivateDecryptInline\n"));
- /* allocate a buffer for max decrypted text */
- tmp = (byte*)XMALLOC(key->sz, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (tmp == NULL)
- return USER_CRYPTO_ERROR;
- outSz = wc_RsaPrivateDecrypt(in, inLen, tmp, key->sz, key);
- if (outSz >= 0) {
- XMEMCPY(in, tmp, outSz);
- *out = in;
- }
- else {
- XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return USER_CRYPTO_ERROR;
- }
- XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- USER_DEBUG(("\tExit wc_RsaPrivateDecryptInline\n"));
- return outSz;
- }
- /* Used to clean up memory when exiting, clean up memory used */
- static int FreeHelper(IppsBigNumState* pTxt, IppsBigNumState* cTxt,
- Ipp8u* scratchBuffer, void* pPub)
- {
- if (pTxt != NULL)
- XFREE(pTxt, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (cTxt != NULL)
- XFREE(cTxt, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (scratchBuffer != NULL)
- XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (pPub != NULL)
- XFREE(pPub, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return 0;
- }
- /* for Rsa Verify
- in : byte array to be verified
- inLen : length of input array
- out : pointer to location of in byte array that has been verified
- */
- int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
- {
- int ctxSz;
- int scratchSz;
- Ipp8u* scratchBuffer = NULL;
- IppStatus ret;
- IppsRSAPrivateKeyState* pPub = NULL;
- IppsBigNumState* pTxt = NULL;
- IppsBigNumState* cTxt = NULL;
- USER_DEBUG(("Entering wc_RsaSSL_VerifyInline\n"));
- if (key == NULL || key->n == NULL || key->e == NULL) {
- USER_DEBUG(("n or e element was null\n"));
- return USER_CRYPTO_ERROR;
- }
- if (in == NULL || inLen == 0 || out == NULL)
- return USER_CRYPTO_ERROR;
- /* set up a private key state using public key values */
- ret = ippsRSA_GetSizePrivateKeyType1(key->nSz, key->eSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- pPub = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (pPub == NULL)
- return USER_CRYPTO_ERROR;
- ret = ippsRSA_InitPrivateKeyType1(key->nSz, key->eSz, pPub, ctxSz);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- ret = ippsRSA_SetPrivateKeyType1(key->n, key->e, pPub);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n",
- ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* set size of scratch buffer */
- ret = ippsRSA_GetBufferSizePrivateKey(&scratchSz, pPub);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- return USER_CRYPTO_ERROR;
- }
- scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (scratchBuffer == NULL) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- return USER_CRYPTO_ERROR;
- }
- /* load plain and cipher into big num states */
- ret = init_bn(&pTxt, key->sz);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsSetOctString_BN((Ipp8u*)in, key->sz, pTxt);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- return USER_CRYPTO_ERROR;
- }
- /* set up cipher to hold signature */
- ret = init_bn(&cTxt, key->sz);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsSetOctString_BN((Ipp8u*)in, key->sz, cTxt);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- return USER_CRYPTO_ERROR;
- }
- /* decrypt using public key information */
- ret = ippsRSA_Decrypt(cTxt, pTxt, pPub, scratchBuffer);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- USER_DEBUG(("decrypt error of %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- /* extract big num struct to octet string */
- ret = ippsGetOctString_BN((Ipp8u*)in, key->sz, pTxt);
- if (ret != ippStsNoErr) {
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- USER_DEBUG(("BN get string error of %s\n", ippGetStatusString(ret)));
- return USER_CRYPTO_ERROR;
- }
- FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
- /* unpad the decrypted information and return size of array */
- return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
- }
- /* sets up and call VerifyInline to verify a signature */
- int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
- RsaKey* key)
- {
- int plainLen;
- byte* tmp;
- byte* pad = 0;
- if (out == NULL || in == NULL || key == NULL)
- return USER_CRYPTO_ERROR;
- tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_USER_CRYPTO);
- if (tmp == NULL) {
- return USER_CRYPTO_ERROR;
- }
- XMEMCPY(tmp, in, inLen);
- /* verify signature and test if output buffer is large enough */
- plainLen = wc_RsaSSL_VerifyInline(tmp, inLen, &pad, key);
- if (plainLen < 0) {
- XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return plainLen;
- }
- if (plainLen > (int)outLen)
- plainLen = USER_CRYPTO_ERROR;
- else
- XMEMCPY(out, pad, plainLen);
- ForceZero(tmp, inLen);
- XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return plainLen;
- }
- /* Check if a > b , if so c = a mod b
- return ippStsNoErr on success */
- static IppStatus reduce(IppsBigNumState* a, IppsBigNumState* b,
- IppsBigNumState* c)
- {
- IppStatus ret;
- if ((ret = ippsMod_BN(a, b, c)) != ippStsNoErr)
- return ret;
- return ippStsNoErr;
- }
- static IppStatus exptmod(IppsBigNumState* a, IppsBigNumState* b,
- IppsMontState* mont, IppsBigNumState* out, IppsBigNumState* one)
- {
- IppStatus ret;
- ret = ippsMontForm(a, mont, a);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsMontForm error of %s\n", ippGetStatusString(ret)));
- return ret;
- }
- /* a = a^b mod mont */
- ret = ippsMontExp(a, b, mont, out);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsMontExp error of %s\n", ippGetStatusString(ret)));
- return ret;
- }
- /* convert back from montgomery */
- ret = ippsMontMul(out, one, mont, out);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsMontMul error of %s\n", ippGetStatusString(ret)));
- return ret;
- }
- return ippStsNoErr;
- }
- static void Free_BN(IppsBigNumState* bn)
- {
- int sz, ctxSz;
- IppStatus ret;
- if (bn != NULL) {
- ret = ippStsNoErr;
- ret |= ippsGetSize_BN(bn, &sz);
- ret |= ippsBigNumGetSize(sz, &ctxSz);
- if (ret == ippStsNoErr) {
- ForceZero(bn, ctxSz);
- }
- else {
- USER_DEBUG(("Issue with clearing a struct in RsaSSL_Sign free\n"));
- }
- XFREE(bn, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- }
- }
- /* free up memory used during CRT sign operation */
- static void FreeSignHelper(IppsBigNumState* one, IppsBigNumState* tmp,
- IppsBigNumState* tmpP, IppsBigNumState* tmpQ, IppsBigNumState* tmpa,
- IppsBigNumState* tmpb)
- {
- Free_BN(one);
- Free_BN(tmp);
- Free_BN(tmpP);
- Free_BN(tmpQ);
- Free_BN(tmpa);
- Free_BN(tmpb);
- }
- /* for Rsa Sign */
- int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
- RsaKey* key, WC_RNG* rng)
- {
- int sz, pSz, qSz;
- IppStatus ret;
- word32 outSz;
- IppsMontState* pMont = NULL;
- IppsMontState* qMont = NULL;
- IppsBigNumState* one = NULL;
- IppsBigNumState* tmp = NULL;
- IppsBigNumState* tmpP = NULL;
- IppsBigNumState* tmpQ = NULL;
- IppsBigNumState* tmpa = NULL;
- IppsBigNumState* tmpb = NULL;
- IppsBigNumSGN sa, sb;
- Ipp8u o[1];
- o[0] = 1;
- USER_DEBUG(("Entering wc_RsaSSL_Sign\n"));
- if (in == NULL || out == NULL || key == NULL || rng == NULL) {
- USER_DEBUG(("Bad argument to wc_RsaSSL_Sign\n"));
- return USER_CRYPTO_ERROR;
- }
- sz = key->sz;
- /* sanity check on key being used */
- if (key->pipp == NULL || key->qipp == NULL || key->uipp == NULL ||
- key->dPipp == NULL || key->dQipp == NULL) {
- USER_DEBUG(("Bad key argument to wc_RsaSSL_Sign\n"));
- return USER_CRYPTO_ERROR;
- }
- if (sz > (int)outLen) {
- USER_DEBUG(("Bad argument outLen to wc_RsaSSL_Sign\n"));
- return USER_CRYPTO_ERROR;
- }
- if (sz < RSA_MIN_PAD_SZ) {
- USER_DEBUG(("Key size is too small\n"));
- return USER_CRYPTO_ERROR;
- }
- if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) {
- USER_DEBUG(("Bad argument inLen to wc_RsaSSL_Sign\n"));
- return USER_CRYPTO_ERROR;
- }
- /* Set up needed pkcs v15 padding */
- if (wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng) != 0) {
- USER_DEBUG(("RSA Padding error\n"));
- return USER_CRYPTO_ERROR;
- }
- /* tmp = input to sign */
- ret = init_bn(&tmp, sz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsSetOctString_BN(out, sz, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsSetOctString_BN error of %s\n",
- ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmpP = tmp mod p */
- ret = init_bn(&tmpP, sz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmpQ = tmp mod q */
- ret = init_bn(&tmpQ, sz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmpa */
- ret = init_bn(&tmpa, sz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmpb */
- ret = init_bn(&tmpb, sz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* one : used for conversion from Montgomery to classical */
- ret = init_bn(&one, sz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsSetOctString_BN(o, 1, one);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsSetOctString_BN error of %s\n",
- ippGetStatusString(ret)));
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /**
- Set up Montgomery state
- */
- ret = init_mont(&pMont, &pSz, key->pipp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_mont error of %s\n", ippGetStatusString(ret)));
- if (pMont != NULL) {
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- }
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = init_mont(&qMont, &qSz, key->qipp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("init_mont error of %s\n", ippGetStatusString(ret)));
- if (qMont != NULL) {
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- }
- ForceZero(pMont, pSz);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /**
- Check and reduce input
- This is needed for calls to MontExp since required value of a < modulus
- */
- ret = reduce(tmp, key->pipp, tmpP);
- if (ret != ippStsNoErr)
- {
- USER_DEBUG(("reduce error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = reduce(tmp, key->qipp, tmpQ);
- if (ret != ippStsNoErr)
- {
- USER_DEBUG(("reduce error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmpa = (tmp mod p)^dP mod p */
- ret = exptmod(tmpP, key->dPipp, pMont, tmpa, one);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("exptmod error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmpb = (tmp mod q)^dQ mod q */
- ret = exptmod(tmpQ, key->dQipp, qMont, tmpb, one);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("exptmod error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* tmp = (tmpa - tmpb) * qInv (mod p) */
- ret = ippsSub_BN(tmpa, tmpb, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsMul_BN(tmp, key->uipp, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsMul_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* mod performed the same was as wolfSSL fp_mod -- tmpa is just scratch */
- ret = ippsDiv_BN(tmp, key->pipp, tmpa, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsDiv_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* Check sign of values and perform conditional add */
- ret = ippsExtGet_BN(&sa, NULL, NULL, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsExtGet_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsExtGet_BN(&sb, NULL, NULL, key->pipp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsExtGet_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- if (sa != sb) {
- ret = ippsAdd_BN(tmp, key->pipp, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsAdd_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- }
- /* tmp = tmpb + q * tmp */
- ret = ippsMul_BN(tmp, key->qipp, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- ret = ippsAdd_BN(tmp, tmpb, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- /* Extract the output */
- ret = ippsGetOctString_BN(out, sz, tmp);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetOctString_BN error of %s\n",
- ippGetStatusString(ret)));
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return USER_CRYPTO_ERROR;
- }
- outSz = sz;
- /* clear memory and free */
- ForceZero(pMont, pSz);
- ForceZero(qMont, qSz);
- XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
- return outSz;
- }
- int wc_RsaEncryptSize(RsaKey* key)
- {
- if (key == NULL)
- return 0;
- return key->sz;
- }
- /* flatten RsaKey structure into individual elements (e, n) */
- int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
- word32* nSz)
- {
- int sz, bytSz;
- IppStatus ret;
- USER_DEBUG(("Entering wc_RsaFlattenPublicKey\n"));
- if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL)
- return USER_CRYPTO_ERROR;
- bytSz = sizeof(byte) * 8;
- ret = ippsExtGet_BN(NULL, &sz, NULL, key->e);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- /* sz is in bits change to bytes */
- sz = (sz / bytSz) + ((sz % bytSz)? 1 : 0);
- if (*eSz < (word32)sz)
- return USER_CRYPTO_ERROR;
- ret = ippsGetOctString_BN(e, sz, key->e);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- *eSz = (word32)sz;
- /* flatten n */
- ret = ippsExtGet_BN(NULL, &sz, NULL, key->n);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- /* sz is in bits change to bytes */
- sz = (sz / bytSz) + ((sz % bytSz)? 1: 0);
- if (*nSz < (word32)sz)
- return USER_CRYPTO_ERROR;
- ret = ippsGetOctString_BN(n, sz, key->n);
- if (ret != ippStsNoErr)
- return USER_CRYPTO_ERROR;
- *nSz = (word32)sz;
- return 0;
- }
- IppStatus wolfSSL_rng(Ipp32u* pData, int nBits, void* pEbsParams);
- IppStatus wolfSSL_rng(Ipp32u* pData, int nBits, void* pEbsParams)
- {
- int nBytes;
- if (pData == NULL) {
- USER_DEBUG(("error with wolfSSL_rng argument\n"));
- return ippStsErr;
- }
- nBytes = (nBits/8) + ((nBits % 8)? 1: 0);
- if (wc_RNG_GenerateBlock((WC_RNG*)pEbsParams, (byte*)pData, nBytes) != 0) {
- USER_DEBUG(("error in generating random wolfSSL block\n"));
- return ippStsErr;
- }
- return ippStsNoErr;
- }
- #ifdef WOLFSSL_KEY_GEN
- /* Make an RSA key for size bits, with e specified, 65537 is a good e */
- int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
- {
- IppStatus ret;
- int scratchSz;
- int i; /* for trys on calling make key */
- int ctxSz;
- IppsBigNumState* pSrcPublicExp = NULL;
- Ipp8u* scratchBuffer = NULL;
- Ipp8u eAry[8];
- int trys = 8; /* Miller-Rabin test parameter */
- IppsPrimeState* pPrime = NULL;
- int qBitSz; /* size of q factor */
- int bytSz; /* size of key in bytes */
- int leng;
- USER_DEBUG(("Entering wc_MakeRsaKey\n"));
- /* get byte size and individual private key size -- round up */
- qBitSz = (size / 2) + ((size % 2)? 1: 0);
- bytSz = (size / 8) + ((size % 8)? 1: 0);
- if (key == NULL || rng == NULL) {
- USER_DEBUG(("Error, NULL argument passed in\n"));
- return USER_CRYPTO_ERROR;
- }
- if (e < 3 || (e&1) == 0)
- return USER_CRYPTO_ERROR;
- if (size > RSA_MAX_SIZE || size < RSA_MIN_SIZE)
- return USER_CRYPTO_ERROR;
- key->type = RSA_PRIVATE;
- key->sz = bytSz;
- /* initialize prime number */
- ret = ippsPrimeGetSize(size, &ctxSz); /* size in bits */
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsPrimeGetSize error of %s\n", ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- pPrime = (IppsPrimeState*)XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (pPrime == NULL) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- ret = ippsPrimeInit(size, pPrime);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsPrimeInit error of %s\n", ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* define RSA privete key type 2 */
- /* length in bits of p and q factors */
- ret = ippsRSA_GetSizePrivateKeyType2(qBitSz, qBitSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePrivateKeyType2 error of %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- key->prvSz = ctxSz; /* used when freeing private key */
- key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, NULL,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPrv == NULL) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* length in bits of p and q factors */
- ret = ippsRSA_InitPrivateKeyType2(qBitSz, qBitSz, key->pPrv, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPrivateKeyType2 error of %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* allocate scratch buffer */
- ret = ippsRSA_GetBufferSizePrivateKey(&scratchSz, key->pPrv);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetBufferSizePrivateKey error of %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- scratchBuffer = (Ipp8u*)XMALLOC(scratchSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
- if (scratchBuffer == NULL) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* set up initial value of pScrPublicExp */
- leng = (int)sizeof(long); /* # of Ipp32u in long */
- /* place the value of e into the array eAry then load into BN */
- for (i = 0; i < leng; i++) {
- eAry[i] = (e >> (8 * (leng - 1 - i))) & 0XFF;
- }
- ret = init_bn(&pSrcPublicExp, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- ret = ippsSetOctString_BN(eAry, leng, pSrcPublicExp);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* initializing key->n */
- ret = init_bn(&key->n, bytSz);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* initializing public exponent key->e */
- ret = init_bn(&key->e, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* private exponent key->dipp */
- ret = init_bn(&key->dipp, bytSz);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* call IPP to generate keys, if inseficent entropy error call again */
- ret = ippStsInsufficientEntropy;
- while (ret == ippStsInsufficientEntropy) {
- ret = ippsRSA_GenerateKeys(pSrcPublicExp, key->n, key->e,
- key->dipp, key->pPrv, scratchBuffer, trys, pPrime,
- wolfSSL_rng, rng);
- if (ret == ippStsNoErr) {
- break;
- }
- /* catch all errors other than entropy error */
- if (ret != ippStsInsufficientEntropy) {
- USER_DEBUG(("ippsRSA_GeneratKeys error of %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- }
- /* get bn sizes needed for private key set up */
- ret = ippsExtGet_BN(NULL, &key->eSz, NULL, key->e);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- ret = ippsExtGet_BN(NULL, &key->nSz, NULL, key->n);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* set up public key state */
- ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetSizePublicKey error %s nSz = %d eSz = %d\n",
- ippGetStatusString(ret), key->nSz, key->eSz));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (key->pPub == NULL) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* get private key information for key struct */
- leng = size/16; /* size of q, p, u, dP, dQ */
- ret = init_bn(&key->pipp, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* set up q BN for key */
- ret = init_bn(&key->qipp, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* set up dP BN for key */
- ret = init_bn(&key->dPipp, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* set up dQ BN for key */
- ret = init_bn(&key->dQipp, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* set up u BN for key */
- ret = init_bn(&key->uipp, leng);
- if (ret != ippStsNoErr) {
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- /* get values from created key */
- ret = ippsRSA_GetPrivateKeyType2(key->pipp, key->qipp, key->dPipp,
- key->dQipp, key->uipp, key->pPrv);
- if (ret != ippStsNoErr) {
- USER_DEBUG(("ippsRSA_GetPrivateKeyType2 error %s\n",
- ippGetStatusString(ret)));
- ret = USER_CRYPTO_ERROR;
- goto makeKeyEnd;
- }
- ret = 0; /* success case */
- makeKeyEnd:
- /* clean up memory used */
- XFREE(pSrcPublicExp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(pPrime, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (ret != 0) { /* with fail case free RSA components created */
- wc_FreeRsaKey(key);
- }
- return ret;
- }
- #endif
- #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)
- /********** duplicate code needed -- future refactor */
- #define MAX_VERSION_SZ 5
- #define MAX_SEQ_SZ 5
- #define ASN_CONTEXT_SPECIFIC 0x80
- #define ASN_CONSTRUCTED 0x20
- #define ASN_LONG_LENGTH 0x80
- #define ASN_SEQUENCE 0x10
- #define RSA_INTS 8
- #define FALSE 0
- #define TRUE 1
- #define MAX_LENGTH_SZ 4
- #define RSAk 645
- #define keyType 2
- #define MAX_RSA_INT_SZ 517
- #define MAX_RSA_E_SZ 16
- #define MAX_ALGO_SZ 20
- static word32 BytePrecision(word32 value)
- {
- word32 i;
- for (i = sizeof(value); i; --i)
- if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
- break;
- return i;
- }
- static int SetMyVersion(word32 version, byte* output, int header)
- {
- int i = 0;
- if (output == NULL)
- return USER_CRYPTO_ERROR;
- if (header) {
- output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
- output[i++] = ASN_BIT_STRING;
- }
- output[i++] = ASN_INTEGER;
- output[i++] = 0x01;
- output[i++] = (byte)version;
- return i;
- }
- static word32 SetLength(word32 length, byte* output)
- {
- word32 i = 0, j;
- if (length < 0x80)
- output[i++] = (byte)length;
- else {
- output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
- for (j = BytePrecision(length); j; --j) {
- output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
- i++;
- }
- }
- return i;
- }
- static word32 SetSequence(word32 len, byte* output)
- {
- output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
- return SetLength(len, output + 1) + 1;
- }
- static word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
- {
- /* adding TAG_NULL and 0 to end */
- /* RSA keyType */
- #ifndef NO_RSA
- static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x01, 0x05, 0x00};
- #endif /* NO_RSA */
- int algoSz = 0;
- int tagSz = 2; /* tag null and terminator */
- word32 idSz, seqSz;
- const byte* algoName = 0;
- byte ID_Length[MAX_LENGTH_SZ];
- byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */
- if (type == keyType) { /* keyType */
- switch (algoOID) {
- #ifndef NO_RSA
- case RSAk:
- algoSz = sizeof(RSA_AlgoID);
- algoName = RSA_AlgoID;
- break;
- #endif /* NO_RSA */
- default:
- /* unknown key algo */
- return 0;
- }
- }
- else {
- /* unknown algo type */
- return 0;
- }
- idSz = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */
- seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray);
- /* +1 for object id, curveID of curveSz follows for ecc */
- seqArray[seqSz++] = ASN_OBJECT_ID;
- XMEMCPY(output, seqArray, seqSz);
- XMEMCPY(output + seqSz, ID_Length, idSz);
- XMEMCPY(output + seqSz + idSz, algoName, algoSz);
- return seqSz + idSz + algoSz;
- }
- /* Write a public RSA key to output */
- static int SetRsaPublicKey(byte* output, RsaKey* key,
- int outLen, int with_header)
- {
- #ifdef WOLFSSL_SMALL_STACK
- byte* n = NULL;
- byte* e = NULL;
- #else
- byte n[MAX_RSA_INT_SZ];
- byte e[MAX_RSA_E_SZ];
- #endif
- byte seq[MAX_SEQ_SZ];
- byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
- int nSz;
- int eSz;
- int seqSz;
- int lenSz;
- int idx;
- int rawLen;
- int leadingBit;
- int err;
- if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
- return USER_CRYPTO_ERROR;
- /* n */
- #ifdef WOLFSSL_SMALL_STACK
- n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (n == NULL)
- return USER_CRYPTO_ERROR;
- #endif
- leadingBit = wc_Rsa_leading_bit(key->n);
- rawLen = wc_Rsa_unsigned_bin_size(key->n);
- if ((int)rawLen < 0) {
- return USER_CRYPTO_ERROR;
- }
- rawLen = rawLen + leadingBit;
- n[0] = ASN_INTEGER;
- nSz = SetLength(rawLen, n + 1) + 1; /* int tag */
- if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
- if (leadingBit)
- n[nSz] = 0;
- err = ippsGetOctString_BN((Ipp8u*)n + nSz, rawLen - leadingBit, key->n);
- if (err == ippStsNoErr)
- nSz += rawLen;
- else {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- }
- else {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- /* e */
- #ifdef WOLFSSL_SMALL_STACK
- e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (e == NULL) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- #endif
- leadingBit = wc_Rsa_leading_bit(key->e);
- rawLen = wc_Rsa_unsigned_bin_size(key->e);
- if ((int)rawLen < 0) {
- return USER_CRYPTO_ERROR;
- }
- rawLen = rawLen + leadingBit;
- e[0] = ASN_INTEGER;
- eSz = SetLength(rawLen, e + 1) + 1; /* int tag */
- if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
- if (leadingBit)
- e[eSz] = 0;
- err = ippsGetOctString_BN((Ipp8u*)e + eSz, rawLen - leadingBit, key->e);
- if (err == ippStsNoErr)
- eSz += rawLen;
- else {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- }
- else {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- seqSz = SetSequence(nSz + eSz, seq);
- /* check output size */
- if ( (seqSz + nSz + eSz) > outLen) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- /* headers */
- if (with_header) {
- int algoSz;
- #ifdef WOLFSSL_SMALL_STACK
- byte* algo;
- algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- if (algo == NULL) {
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- return USER_CRYPTO_ERROR;
- }
- #else
- byte algo[MAX_ALGO_SZ];
- #endif
- algoSz = SetAlgoID(RSAk, algo, keyType, 0);
- lenSz = SetLength(seqSz + nSz + eSz + 1, len);
- len[lenSz++] = 0; /* trailing 0 */
- /* write, 1 is for ASN_BIT_STRING */
- idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
- /* check output size */
- if ( (idx + algoSz + 1 + lenSz + seqSz + nSz + eSz) > outLen) {
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(algo, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return USER_CRYPTO_ERROR;
- }
- /* algo */
- XMEMCPY(output + idx, algo, algoSz);
- idx += algoSz;
- /* bit string */
- output[idx++] = ASN_BIT_STRING;
- /* length */
- XMEMCPY(output + idx, len, lenSz);
- idx += lenSz;
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(algo, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- }
- else
- idx = 0;
- /* seq */
- XMEMCPY(output + idx, seq, seqSz);
- idx += seqSz;
- /* n */
- XMEMCPY(output + idx, n, nSz);
- idx += nSz;
- /* e */
- XMEMCPY(output + idx, e, eSz);
- idx += eSz;
- #ifdef WOLFSSL_SMALL_STACK
- XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
- #endif
- return idx;
- }
- static IppsBigNumState* GetRsaInt(RsaKey* key, int idx)
- {
- if (idx == 0)
- return key->n;
- if (idx == 1)
- return key->e;
- if (idx == 2)
- return key->dipp;
- if (idx == 3)
- return key->pipp;
- if (idx == 4)
- return key->qipp;
- if (idx == 5)
- return key->dPipp;
- if (idx == 6)
- return key->dQipp;
- if (idx == 7)
- return key->uipp;
- return NULL;
- }
- /* Release Tmp RSA resources */
- static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
- {
- int i;
- (void)heap;
- for (i = 0; i < RSA_INTS; i++)
- XFREE(tmps[i], heap, DYNAMIC_TYPE_USER_CRYPTO);
- }
- /* Convert RsaKey key to DER format, write to output (inLen), return bytes
- written */
- int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
- {
- word32 seqSz, verSz, rawLen, intTotalLen = 0;
- word32 sizes[RSA_INTS];
- int i, j, outLen, ret = 0, lbit;
- byte seq[MAX_SEQ_SZ];
- byte ver[MAX_VERSION_SZ];
- byte* tmps[RSA_INTS];
- USER_DEBUG(("Entering RsaKeyToDer\n"));
- if (!key)
- return USER_CRYPTO_ERROR;
- if (key->type != RSA_PRIVATE)
- return USER_CRYPTO_ERROR;
- for (i = 0; i < RSA_INTS; i++)
- tmps[i] = NULL;
- /* write all big ints from key to DER tmps */
- for (i = 0; i < RSA_INTS; i++) {
- Ipp32u isZero;
- IppsBigNumState* keyInt = GetRsaInt(key, i);
- ippsCmpZero_BN(keyInt, &isZero); /* makes isZero 0 if true */
- rawLen = wc_Rsa_unsigned_bin_size(keyInt);
- if ((int)rawLen < 0) {
- return USER_CRYPTO_ERROR;
- }
- /* leading zero */
- if (!isZero || wc_Rsa_leading_bit(keyInt))
- lbit = 1;
- else
- lbit = 0;
- rawLen += lbit;
- tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
- DYNAMIC_TYPE_USER_CRYPTO);
- if (tmps[i] == NULL) {
- ret = USER_CRYPTO_ERROR;
- break;
- }
- tmps[i][0] = ASN_INTEGER;
- sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1 + lbit; /* tag & lbit */
- if (sizes[i] <= MAX_SEQ_SZ) {
- int err;
- /* leading zero */
- if (lbit)
- tmps[i][sizes[i]-1] = 0x00;
- /* extract data*/
- err = ippsGetOctString_BN((Ipp8u*)(tmps[i] + sizes[i]),
- rawLen - lbit, keyInt);
- if (err == ippStsOk) {
- sizes[i] += (rawLen-lbit); /* lbit included in rawLen */
- intTotalLen += sizes[i];
- ret = 0;
- }
- else {
- ret = USER_CRYPTO_ERROR;
- USER_DEBUG(("ippsGetOctString_BN error %s\n",
- ippGetStatusString(err)));
- break;
- }
- }
- else {
- ret = USER_CRYPTO_ERROR;
- break;
- }
- }
- if (ret != 0) {
- FreeTmpRsas(tmps, key->heap);
- return ret;
- }
- /* make headers */
- verSz = SetMyVersion(0, ver, FALSE);
- seqSz = SetSequence(verSz + intTotalLen, seq);
- outLen = seqSz + verSz + intTotalLen;
- if (output) {
- if (outLen > (int)inLen) {
- return USER_CRYPTO_ERROR;
- }
- /* write to output */
- XMEMCPY(output, seq, seqSz);
- j = seqSz;
- XMEMCPY(output + j, ver, verSz);
- j += verSz;
- for (i = 0; i < RSA_INTS; i++) {
- XMEMCPY(output + j, tmps[i], sizes[i]);
- j += sizes[i];
- }
- }
- FreeTmpRsas(tmps, key->heap);
- return outLen;
- }
- /* Convert Rsa Public key to DER format, write to output (inLen), return bytes
- written
- */
- int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
- {
- return SetRsaPublicKey(output, key, inLen, 1);
- }
- /* Returns public DER version of the RSA key. If with_header is 0 then only a
- * seq + n + e is returned in ASN.1 DER format */
- int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
- int with_header)
- {
- return SetRsaPublicKey(output, key, inLen, with_header);
- }
- #endif /* WOLFSSL_KEY_GEN || OPENSSL_EXTRA */
- #ifdef WC_RSA_BLINDING
- int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
- {
- if (key == NULL)
- return USER_CRYPTO_ERROR;
- (void)rng;
- return 0;
- }
- #endif /* WC_RSA_BLINDING */
- #endif /* NO_RSA */
|