1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192 |
- /*
- * MbedTLS Source Code Library Source
- */
- #include "mbedtls.h"
- #if ME_COM_MBEDTLS
- /********* Start of file library/aes.c ************/
- /*
- * FIPS-197 compliant AES implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
- *
- * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
- * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_AES_C)
- #include <string.h>
- #if defined(MBEDTLS_PADLOCK_C)
- #endif
- #if defined(MBEDTLS_AESNI_C)
- #endif
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_AES_ALT)
- /* Amalgamated Release Mappings */
- #define FSb AESFSb
- /* Implementation that should never be optimized out by the compiler */
- static void aes_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (little endian)
- */
- #ifndef GET_UINT32_LE
- #define GET_UINT32_LE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
- }
- #endif
- #ifndef PUT_UINT32_LE
- #define PUT_UINT32_LE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
- }
- #endif
- #if defined(MBEDTLS_PADLOCK_C) && \
- ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
- static int aes_padlock_ace = -1;
- #endif
- #if defined(MBEDTLS_AES_ROM_TABLES)
- /*
- * Forward S-box
- */
- static const unsigned char FSb[256] =
- {
- 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
- 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
- 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
- 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
- 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
- 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
- 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
- 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
- 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
- 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
- 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
- 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
- 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
- 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
- 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
- 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
- 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
- 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
- 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
- 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
- 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
- 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
- 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
- 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
- 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
- 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
- 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
- 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
- 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
- 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
- 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
- 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
- };
- /*
- * Forward tables
- */
- #define FT \
- \
- V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
- V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
- V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
- V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
- V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
- V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
- V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
- V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
- V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
- V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
- V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
- V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
- V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
- V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
- V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
- V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
- V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
- V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
- V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
- V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
- V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
- V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
- V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
- V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
- V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
- V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
- V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
- V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
- V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
- V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
- V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
- V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
- V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
- V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
- V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
- V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
- V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
- V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
- V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
- V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
- V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
- V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
- V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
- V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
- V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
- V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
- V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
- V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
- V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
- V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
- V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
- V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
- V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
- V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
- V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
- V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
- V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
- V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
- V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
- V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
- V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
- V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
- V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
- V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
- #define V(a,b,c,d) 0x##a##b##c##d
- static const uint32_t FT0[256] = { FT };
- #undef V
- #define V(a,b,c,d) 0x##b##c##d##a
- static const uint32_t FT1[256] = { FT };
- #undef V
- #define V(a,b,c,d) 0x##c##d##a##b
- static const uint32_t FT2[256] = { FT };
- #undef V
- #define V(a,b,c,d) 0x##d##a##b##c
- static const uint32_t FT3[256] = { FT };
- #undef V
- #undef FT
- /*
- * Reverse S-box
- */
- static const unsigned char RSb[256] =
- {
- 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
- 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
- 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
- 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
- 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
- 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
- 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
- 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
- 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
- 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
- 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
- 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
- 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
- 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
- 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
- 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
- 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
- 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
- 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
- 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
- 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
- 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
- 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
- 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
- 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
- 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
- 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
- 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
- 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
- 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
- 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
- };
- /*
- * Reverse tables
- */
- #define RT \
- \
- V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
- V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
- V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
- V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
- V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
- V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
- V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
- V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
- V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
- V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
- V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
- V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
- V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
- V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
- V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
- V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
- V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
- V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
- V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
- V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
- V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
- V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
- V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
- V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
- V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
- V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
- V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
- V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
- V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
- V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
- V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
- V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
- V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
- V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
- V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
- V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
- V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
- V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
- V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
- V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
- V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
- V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
- V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
- V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
- V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
- V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
- V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
- V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
- V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
- V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
- V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
- V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
- V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
- V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
- V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
- V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
- V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
- V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
- V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
- V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
- V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
- V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
- V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
- V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
- #define V(a,b,c,d) 0x##a##b##c##d
- static const uint32_t RT0[256] = { RT };
- #undef V
- #define V(a,b,c,d) 0x##b##c##d##a
- static const uint32_t RT1[256] = { RT };
- #undef V
- #define V(a,b,c,d) 0x##c##d##a##b
- static const uint32_t RT2[256] = { RT };
- #undef V
- #define V(a,b,c,d) 0x##d##a##b##c
- static const uint32_t RT3[256] = { RT };
- #undef V
- #undef RT
- /*
- * Round constants
- */
- static const uint32_t RCON[10] =
- {
- 0x00000001, 0x00000002, 0x00000004, 0x00000008,
- 0x00000010, 0x00000020, 0x00000040, 0x00000080,
- 0x0000001B, 0x00000036
- };
- #else /* MBEDTLS_AES_ROM_TABLES */
- /*
- * Forward S-box & tables
- */
- static unsigned char FSb[256];
- static uint32_t FT0[256];
- static uint32_t FT1[256];
- static uint32_t FT2[256];
- static uint32_t FT3[256];
- /*
- * Reverse S-box & tables
- */
- static unsigned char RSb[256];
- static uint32_t RT0[256];
- static uint32_t RT1[256];
- static uint32_t RT2[256];
- static uint32_t RT3[256];
- /*
- * Round constants
- */
- static uint32_t RCON[10];
- /*
- * Tables generation code
- */
- #define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
- #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
- #define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
- static int aes_init_done = 0;
- static void aes_gen_tables( void )
- {
- int i, x, y, z;
- int pow[256];
- int log[256];
- /*
- * compute pow and log tables over GF(2^8)
- */
- for( i = 0, x = 1; i < 256; i++ )
- {
- pow[i] = x;
- log[x] = i;
- x = ( x ^ XTIME( x ) ) & 0xFF;
- }
- /*
- * calculate the round constants
- */
- for( i = 0, x = 1; i < 10; i++ )
- {
- RCON[i] = (uint32_t) x;
- x = XTIME( x ) & 0xFF;
- }
- /*
- * generate the forward and reverse S-boxes
- */
- FSb[0x00] = 0x63;
- RSb[0x63] = 0x00;
- for( i = 1; i < 256; i++ )
- {
- x = pow[255 - log[i]];
- y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y ^ 0x63;
- FSb[i] = (unsigned char) x;
- RSb[x] = (unsigned char) i;
- }
- /*
- * generate the forward and reverse tables
- */
- for( i = 0; i < 256; i++ )
- {
- x = FSb[i];
- y = XTIME( x ) & 0xFF;
- z = ( y ^ x ) & 0xFF;
- FT0[i] = ( (uint32_t) y ) ^
- ( (uint32_t) x << 8 ) ^
- ( (uint32_t) x << 16 ) ^
- ( (uint32_t) z << 24 );
- FT1[i] = ROTL8( FT0[i] );
- FT2[i] = ROTL8( FT1[i] );
- FT3[i] = ROTL8( FT2[i] );
- x = RSb[i];
- RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
- ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
- ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
- ( (uint32_t) MUL( 0x0B, x ) << 24 );
- RT1[i] = ROTL8( RT0[i] );
- RT2[i] = ROTL8( RT1[i] );
- RT3[i] = ROTL8( RT2[i] );
- }
- }
- #endif /* MBEDTLS_AES_ROM_TABLES */
- void mbedtls_aes_init( mbedtls_aes_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_aes_context ) );
- }
- void mbedtls_aes_free( mbedtls_aes_context *ctx )
- {
- if( ctx == NULL )
- return;
- aes_zeroize( ctx, sizeof( mbedtls_aes_context ) );
- }
- /*
- * AES key schedule (encryption)
- */
- #if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
- int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
- unsigned int keybits )
- {
- unsigned int i;
- uint32_t *RK;
- #if !defined(MBEDTLS_AES_ROM_TABLES)
- if( aes_init_done == 0 )
- {
- aes_gen_tables();
- aes_init_done = 1;
- }
- #endif
- switch( keybits )
- {
- case 128: ctx->nr = 10; break;
- case 192: ctx->nr = 12; break;
- case 256: ctx->nr = 14; break;
- default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
- }
- #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
- if( aes_padlock_ace == -1 )
- aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
- if( aes_padlock_ace )
- ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
- else
- #endif
- ctx->rk = RK = ctx->buf;
- #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
- return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
- #endif
- for( i = 0; i < ( keybits >> 5 ); i++ )
- {
- GET_UINT32_LE( RK[i], key, i << 2 );
- }
- switch( ctx->nr )
- {
- case 10:
- for( i = 0; i < 10; i++, RK += 4 )
- {
- RK[4] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
- RK[5] = RK[1] ^ RK[4];
- RK[6] = RK[2] ^ RK[5];
- RK[7] = RK[3] ^ RK[6];
- }
- break;
- case 12:
- for( i = 0; i < 8; i++, RK += 6 )
- {
- RK[6] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
- RK[7] = RK[1] ^ RK[6];
- RK[8] = RK[2] ^ RK[7];
- RK[9] = RK[3] ^ RK[8];
- RK[10] = RK[4] ^ RK[9];
- RK[11] = RK[5] ^ RK[10];
- }
- break;
- case 14:
- for( i = 0; i < 7; i++, RK += 8 )
- {
- RK[8] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
- RK[9] = RK[1] ^ RK[8];
- RK[10] = RK[2] ^ RK[9];
- RK[11] = RK[3] ^ RK[10];
- RK[12] = RK[4] ^
- ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
- RK[13] = RK[5] ^ RK[12];
- RK[14] = RK[6] ^ RK[13];
- RK[15] = RK[7] ^ RK[14];
- }
- break;
- }
- return( 0 );
- }
- #endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
- /*
- * AES key schedule (decryption)
- */
- #if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
- int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
- unsigned int keybits )
- {
- int i, j, ret;
- mbedtls_aes_context cty;
- uint32_t *RK;
- uint32_t *SK;
- mbedtls_aes_init( &cty );
- #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
- if( aes_padlock_ace == -1 )
- aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
- if( aes_padlock_ace )
- ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
- else
- #endif
- ctx->rk = RK = ctx->buf;
- /* Also checks keybits */
- if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
- goto exit;
- ctx->nr = cty.nr;
- #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
- {
- mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
- (const unsigned char *) cty.rk, ctx->nr );
- goto exit;
- }
- #endif
- SK = cty.rk + cty.nr * 4;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
- {
- for( j = 0; j < 4; j++, SK++ )
- {
- *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
- RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
- RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
- RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
- }
- }
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- exit:
- mbedtls_aes_free( &cty );
- return( ret );
- }
- #endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
- #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
- { \
- X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
- FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
- FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
- FT3[ ( Y3 >> 24 ) & 0xFF ]; \
- \
- X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
- FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
- FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
- FT3[ ( Y0 >> 24 ) & 0xFF ]; \
- \
- X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
- FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
- FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
- FT3[ ( Y1 >> 24 ) & 0xFF ]; \
- \
- X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
- FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
- FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
- FT3[ ( Y2 >> 24 ) & 0xFF ]; \
- }
- #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
- { \
- X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
- RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
- RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
- RT3[ ( Y1 >> 24 ) & 0xFF ]; \
- \
- X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
- RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
- RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
- RT3[ ( Y2 >> 24 ) & 0xFF ]; \
- \
- X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
- RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
- RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
- RT3[ ( Y3 >> 24 ) & 0xFF ]; \
- \
- X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
- RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
- RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
- RT3[ ( Y0 >> 24 ) & 0xFF ]; \
- }
- /*
- * AES-ECB block encryption
- */
- #if !defined(MBEDTLS_AES_ENCRYPT_ALT)
- void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- int i;
- uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
- RK = ctx->rk;
- GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
- GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
- GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
- GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
- for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
- {
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
- AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
- }
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
- X0 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
- X1 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
- X2 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
- X3 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
- PUT_UINT32_LE( X0, output, 0 );
- PUT_UINT32_LE( X1, output, 4 );
- PUT_UINT32_LE( X2, output, 8 );
- PUT_UINT32_LE( X3, output, 12 );
- }
- #endif /* !MBEDTLS_AES_ENCRYPT_ALT */
- /*
- * AES-ECB block decryption
- */
- #if !defined(MBEDTLS_AES_DECRYPT_ALT)
- void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- int i;
- uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
- RK = ctx->rk;
- GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
- GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
- GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
- GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
- for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
- {
- AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
- AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
- }
- AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
- X0 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
- X1 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
- X2 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
- X3 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
- PUT_UINT32_LE( X0, output, 0 );
- PUT_UINT32_LE( X1, output, 4 );
- PUT_UINT32_LE( X2, output, 8 );
- PUT_UINT32_LE( X3, output, 12 );
- }
- #endif /* !MBEDTLS_AES_DECRYPT_ALT */
- /*
- * AES-ECB block encryption/decryption
- */
- int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
- return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
- #endif
- #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
- if( aes_padlock_ace )
- {
- if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
- return( 0 );
- // If padlock data misaligned, we just fall back to
- // unaccelerated mode
- //
- }
- #endif
- if( mode == MBEDTLS_AES_ENCRYPT )
- mbedtls_aes_encrypt( ctx, input, output );
- else
- mbedtls_aes_decrypt( ctx, input, output );
- return( 0 );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * AES-CBC buffer encryption/decryption
- */
- int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int i;
- unsigned char temp[16];
- if( length % 16 )
- return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
- #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
- if( aes_padlock_ace )
- {
- if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
- return( 0 );
- // If padlock data misaligned, we just fall back to
- // unaccelerated mode
- //
- }
- #endif
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- while( length > 0 )
- {
- memcpy( temp, input, 16 );
- mbedtls_aes_crypt_ecb( ctx, mode, input, output );
- for( i = 0; i < 16; i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
- memcpy( iv, temp, 16 );
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- else
- {
- while( length > 0 )
- {
- for( i = 0; i < 16; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
- mbedtls_aes_crypt_ecb( ctx, mode, output, output );
- memcpy( iv, output, 16 );
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- /*
- * AES-CFB128 buffer encryption/decryption
- */
- int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- size_t *iv_off,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int c;
- size_t n = *iv_off;
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
- c = *input++;
- *output++ = (unsigned char)( c ^ iv[n] );
- iv[n] = (unsigned char) c;
- n = ( n + 1 ) & 0x0F;
- }
- }
- else
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
- iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
- n = ( n + 1 ) & 0x0F;
- }
- }
- *iv_off = n;
- return( 0 );
- }
- /*
- * AES-CFB8 buffer encryption/decryption
- */
- int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
- {
- unsigned char c;
- unsigned char ov[17];
- while( length-- )
- {
- memcpy( ov, iv, 16 );
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
- if( mode == MBEDTLS_AES_DECRYPT )
- ov[16] = *input;
- c = *output++ = (unsigned char)( iv[0] ^ *input++ );
- if( mode == MBEDTLS_AES_ENCRYPT )
- ov[16] = c;
- memcpy( iv, ov + 1, 16 );
- }
- return( 0 );
- }
- #endif /*MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * AES-CTR buffer encryption/decryption
- */
- int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
- size_t length,
- size_t *nc_off,
- unsigned char nonce_counter[16],
- unsigned char stream_block[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int c, i;
- size_t n = *nc_off;
- while( length-- )
- {
- if( n == 0 ) {
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
- for( i = 16; i > 0; i-- )
- if( ++nonce_counter[i - 1] != 0 )
- break;
- }
- c = *input++;
- *output++ = (unsigned char)( c ^ stream_block[n] );
- n = ( n + 1 ) & 0x0F;
- }
- *nc_off = n;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #endif /* !MBEDTLS_AES_ALT */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * AES test vectors from:
- *
- * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
- */
- static const unsigned char aes_test_ecb_dec[3][16] =
- {
- { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
- 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
- { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
- 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
- { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
- 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
- };
- static const unsigned char aes_test_ecb_enc[3][16] =
- {
- { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
- 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
- { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
- 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
- { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
- 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const unsigned char aes_test_cbc_dec[3][16] =
- {
- { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
- 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
- { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
- 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
- { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
- 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
- };
- static const unsigned char aes_test_cbc_enc[3][16] =
- {
- { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
- 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
- { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
- 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
- { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
- 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- /*
- * AES-CFB128 test vectors from:
- *
- * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
- */
- static const unsigned char aes_test_cfb128_key[3][32] =
- {
- { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
- 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
- { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
- 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
- 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
- { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
- 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
- 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
- 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
- };
- static const unsigned char aes_test_cfb128_iv[16] =
- {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
- };
- static const unsigned char aes_test_cfb128_pt[64] =
- {
- 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
- 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
- 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
- 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
- 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
- 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
- 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
- 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
- };
- static const unsigned char aes_test_cfb128_ct[3][64] =
- {
- { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
- 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
- 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
- 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
- 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
- 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
- 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
- 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
- { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
- 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
- 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
- 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
- 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
- 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
- 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
- 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
- { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
- 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
- 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
- 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
- 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
- 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
- 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
- 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
- };
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * AES-CTR test vectors from:
- *
- * http://www.faqs.org/rfcs/rfc3686.html
- */
- static const unsigned char aes_test_ctr_key[3][16] =
- {
- { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
- 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
- { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
- 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
- { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
- 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
- };
- static const unsigned char aes_test_ctr_nonce_counter[3][16] =
- {
- { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
- 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
- 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
- };
- static const unsigned char aes_test_ctr_pt[3][48] =
- {
- { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
- 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23 }
- };
- static const unsigned char aes_test_ctr_ct[3][48] =
- {
- { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
- 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
- { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
- 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
- 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
- 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
- { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
- 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
- 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
- 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
- 0x25, 0xB2, 0x07, 0x2F }
- };
- static const int aes_test_ctr_len[3] =
- { 16, 32, 36 };
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- /*
- * Checkup routine
- */
- int mbedtls_aes_self_test( int verbose )
- {
- int ret = 0, i, j, u, v;
- unsigned char key[32];
- unsigned char buf[64];
- unsigned char iv[16];
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- unsigned char prv[16];
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB)
- size_t offset;
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- int len;
- unsigned char nonce_counter[16];
- unsigned char stream_block[16];
- #endif
- mbedtls_aes_context ctx;
- memset( key, 0, 32 );
- mbedtls_aes_init( &ctx );
- /*
- * ECB mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64,
- ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
- memset( buf, 0, 16 );
- if( v == MBEDTLS_AES_DECRYPT )
- {
- mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 );
- for( j = 0; j < 10000; j++ )
- mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
- if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- else
- {
- mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 );
- for( j = 0; j < 10000; j++ )
- mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
- if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * CBC mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64,
- ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
- memset( iv , 0, 16 );
- memset( prv, 0, 16 );
- memset( buf, 0, 16 );
- if( v == MBEDTLS_AES_DECRYPT )
- {
- mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 );
- for( j = 0; j < 10000; j++ )
- mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
- if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- else
- {
- mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 );
- for( j = 0; j < 10000; j++ )
- {
- unsigned char tmp[16];
- mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
- memcpy( tmp, prv, 16 );
- memcpy( prv, buf, 16 );
- memcpy( buf, tmp, 16 );
- }
- if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- /*
- * CFB128 mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64,
- ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
- memcpy( iv, aes_test_cfb128_iv, 16 );
- memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 );
- offset = 0;
- mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 );
- if( v == MBEDTLS_AES_DECRYPT )
- {
- memcpy( buf, aes_test_cfb128_ct[u], 64 );
- mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf );
- if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- else
- {
- memcpy( buf, aes_test_cfb128_pt, 64 );
- mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf );
- if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * CTR mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " AES-CTR-128 (%s): ",
- ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
- memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
- memcpy( key, aes_test_ctr_key[u], 16 );
- offset = 0;
- mbedtls_aes_setkey_enc( &ctx, key, 128 );
- if( v == MBEDTLS_AES_DECRYPT )
- {
- len = aes_test_ctr_len[u];
- memcpy( buf, aes_test_ctr_ct[u], len );
- mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
- buf, buf );
- if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- else
- {
- len = aes_test_ctr_len[u];
- memcpy( buf, aes_test_ctr_pt[u], len );
- mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
- buf, buf );
- if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- ret = 0;
- exit:
- mbedtls_aes_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef FSb
- #endif /* MBEDTLS_AES_C */
- /********* Start of file library/aesni.c ************/
- /*
- * AES-NI support functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set
- * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_AESNI_C)
- #include <string.h>
- #ifndef asm
- #define asm __asm
- #endif
- #if defined(MBEDTLS_HAVE_X86_64)
- /*
- * AES-NI support detection routine
- */
- int mbedtls_aesni_has_support( unsigned int what )
- {
- static int done = 0;
- static unsigned int c = 0;
- if( ! done )
- {
- asm( "movl $1, %%eax \n\t"
- "cpuid \n\t"
- : "=c" (c)
- :
- : "eax", "ebx", "edx" );
- done = 1;
- }
- return( ( c & what ) != 0 );
- }
- /*
- * Binutils needs to be at least 2.19 to support AES-NI instructions.
- * Unfortunately, a lot of users have a lower version now (2014-04).
- * Emit bytecode directly in order to support "old" version of gas.
- *
- * Opcodes from the Intel architecture reference manual, vol. 3.
- * We always use registers, so we don't need prefixes for memory operands.
- * Operand macros are in gas order (src, dst) as opposed to Intel order
- * (dst, src) in order to blend better into the surrounding assembly code.
- */
- #define AESDEC ".byte 0x66,0x0F,0x38,0xDE,"
- #define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF,"
- #define AESENC ".byte 0x66,0x0F,0x38,0xDC,"
- #define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD,"
- #define AESIMC ".byte 0x66,0x0F,0x38,0xDB,"
- #define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF,"
- #define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44,"
- #define xmm0_xmm0 "0xC0"
- #define xmm0_xmm1 "0xC8"
- #define xmm0_xmm2 "0xD0"
- #define xmm0_xmm3 "0xD8"
- #define xmm0_xmm4 "0xE0"
- #define xmm1_xmm0 "0xC1"
- #define xmm1_xmm2 "0xD1"
- /*
- * AES-NI AES-ECB block en(de)cryption
- */
- int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- asm( "movdqu (%3), %%xmm0 \n\t" // load input
- "movdqu (%1), %%xmm1 \n\t" // load round key 0
- "pxor %%xmm1, %%xmm0 \n\t" // round 0
- "addq $16, %1 \n\t" // point to next round key
- "subl $1, %0 \n\t" // normal rounds = nr - 1
- "test %2, %2 \n\t" // mode?
- "jz 2f \n\t" // 0 = decrypt
- "1: \n\t" // encryption loop
- "movdqu (%1), %%xmm1 \n\t" // load round key
- AESENC xmm1_xmm0 "\n\t" // do round
- "addq $16, %1 \n\t" // point to next round key
- "subl $1, %0 \n\t" // loop
- "jnz 1b \n\t"
- "movdqu (%1), %%xmm1 \n\t" // load round key
- AESENCLAST xmm1_xmm0 "\n\t" // last round
- "jmp 3f \n\t"
- "2: \n\t" // decryption loop
- "movdqu (%1), %%xmm1 \n\t"
- AESDEC xmm1_xmm0 "\n\t" // do round
- "addq $16, %1 \n\t"
- "subl $1, %0 \n\t"
- "jnz 2b \n\t"
- "movdqu (%1), %%xmm1 \n\t" // load round key
- AESDECLAST xmm1_xmm0 "\n\t" // last round
- "3: \n\t"
- "movdqu %%xmm0, (%4) \n\t" // export output
- :
- : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output)
- : "memory", "cc", "xmm0", "xmm1" );
- return( 0 );
- }
- /*
- * GCM multiplication: c = a times b in GF(2^128)
- * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5.
- */
- void mbedtls_aesni_gcm_mult( unsigned char c[16],
- const unsigned char a[16],
- const unsigned char b[16] )
- {
- unsigned char aa[16], bb[16], cc[16];
- size_t i;
- /* The inputs are in big-endian order, so byte-reverse them */
- for( i = 0; i < 16; i++ )
- {
- aa[i] = a[15 - i];
- bb[i] = b[15 - i];
- }
- asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0
- "movdqu (%1), %%xmm1 \n\t" // b1:b0
- /*
- * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1
- * using [CLMUL-WP] algorithm 1 (p. 13).
- */
- "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0
- "movdqa %%xmm1, %%xmm3 \n\t" // same
- "movdqa %%xmm1, %%xmm4 \n\t" // same
- PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0
- PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0
- PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0
- PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0
- "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0
- "movdqa %%xmm4, %%xmm3 \n\t" // same
- "psrldq $8, %%xmm4 \n\t" // 0:e1+f1
- "pslldq $8, %%xmm3 \n\t" // e0+f0:0
- "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1
- "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0
- /*
- * Now shift the result one bit to the left,
- * taking advantage of [CLMUL-WP] eq 27 (p. 20)
- */
- "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0
- "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2
- "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1
- "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1
- "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63
- "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63
- "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63
- "pslldq $8, %%xmm3 \n\t" // r0>>63:0
- "pslldq $8, %%xmm4 \n\t" // r2>>63:0
- "psrldq $8, %%xmm5 \n\t" // 0:r1>>63
- "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1
- "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1
- "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63
- /*
- * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1
- * using [CLMUL-WP] algorithm 5 (p. 20).
- * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted).
- */
- /* Step 2 (1) */
- "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0
- "movdqa %%xmm1, %%xmm4 \n\t" // same
- "movdqa %%xmm1, %%xmm5 \n\t" // same
- "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a
- "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b
- "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c
- /* Step 2 (2) */
- "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b
- "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c
- "pslldq $8, %%xmm3 \n\t" // a+b+c:0
- "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0
- /* Steps 3 and 4 */
- "movdqa %%xmm1,%%xmm0 \n\t" // d:x0
- "movdqa %%xmm1,%%xmm4 \n\t" // same
- "movdqa %%xmm1,%%xmm5 \n\t" // same
- "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0'
- "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0'
- "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0'
- "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0'
- "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0'
- // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing
- // bits carried from d. Now get those\t bits back in.
- "movdqa %%xmm1,%%xmm3 \n\t" // d:x0
- "movdqa %%xmm1,%%xmm4 \n\t" // same
- "movdqa %%xmm1,%%xmm5 \n\t" // same
- "psllq $63, %%xmm3 \n\t" // d<<63:stuff
- "psllq $62, %%xmm4 \n\t" // d<<62:stuff
- "psllq $57, %%xmm5 \n\t" // d<<57:stuff
- "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff
- "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff
- "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d
- "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0
- "pxor %%xmm1, %%xmm0 \n\t" // h1:h0
- "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0
- "movdqu %%xmm0, (%2) \n\t" // done
- :
- : "r" (aa), "r" (bb), "r" (cc)
- : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" );
- /* Now byte-reverse the outputs */
- for( i = 0; i < 16; i++ )
- c[i] = cc[15 - i];
- return;
- }
- /*
- * Compute decryption round keys from encryption round keys
- */
- void mbedtls_aesni_inverse_key( unsigned char *invkey,
- const unsigned char *fwdkey, int nr )
- {
- unsigned char *ik = invkey;
- const unsigned char *fk = fwdkey + 16 * nr;
- memcpy( ik, fk, 16 );
- for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 )
- asm( "movdqu (%0), %%xmm0 \n\t"
- AESIMC xmm0_xmm0 "\n\t"
- "movdqu %%xmm0, (%1) \n\t"
- :
- : "r" (fk), "r" (ik)
- : "memory", "xmm0" );
- memcpy( ik, fk, 16 );
- }
- /*
- * Key expansion, 128-bit case
- */
- static void aesni_setkey_enc_128( unsigned char *rk,
- const unsigned char *key )
- {
- asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key
- "movdqu %%xmm0, (%0) \n\t" // as round key 0
- "jmp 2f \n\t" // skip auxiliary routine
- /*
- * Finish generating the next round key.
- *
- * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff
- * with X = rot( sub( r3 ) ) ^ RCON.
- *
- * On exit, xmm0 is r7:r6:r5:r4
- * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3
- * and those are written to the round key buffer.
- */
- "1: \n\t"
- "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X
- "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4
- "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0
- "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4
- "pslldq $4, %%xmm0 \n\t" // etc
- "pxor %%xmm0, %%xmm1 \n\t"
- "pslldq $4, %%xmm0 \n\t"
- "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time!
- "add $16, %0 \n\t" // point to next round key
- "movdqu %%xmm0, (%0) \n\t" // write it
- "ret \n\t"
- /* Main "loop" */
- "2: \n\t"
- AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t"
- AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t"
- :
- : "r" (rk), "r" (key)
- : "memory", "cc", "0" );
- }
- /*
- * Key expansion, 192-bit case
- */
- static void aesni_setkey_enc_192( unsigned char *rk,
- const unsigned char *key )
- {
- asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key
- "movdqu %%xmm0, (%0) \n\t"
- "add $16, %0 \n\t"
- "movq 16(%1), %%xmm1 \n\t"
- "movq %%xmm1, (%0) \n\t"
- "add $8, %0 \n\t"
- "jmp 2f \n\t" // skip auxiliary routine
- /*
- * Finish generating the next 6 quarter-keys.
- *
- * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4
- * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON.
- *
- * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10
- * and those are written to the round key buffer.
- */
- "1: \n\t"
- "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X
- "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4
- "pslldq $4, %%xmm0 \n\t" // etc
- "pxor %%xmm0, %%xmm2 \n\t"
- "pslldq $4, %%xmm0 \n\t"
- "pxor %%xmm0, %%xmm2 \n\t"
- "pslldq $4, %%xmm0 \n\t"
- "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6
- "movdqu %%xmm0, (%0) \n\t"
- "add $16, %0 \n\t"
- "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9
- "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10
- "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0
- "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10
- "movq %%xmm1, (%0) \n\t"
- "add $8, %0 \n\t"
- "ret \n\t"
- "2: \n\t"
- AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t"
- :
- : "r" (rk), "r" (key)
- : "memory", "cc", "0" );
- }
- /*
- * Key expansion, 256-bit case
- */
- static void aesni_setkey_enc_256( unsigned char *rk,
- const unsigned char *key )
- {
- asm( "movdqu (%1), %%xmm0 \n\t"
- "movdqu %%xmm0, (%0) \n\t"
- "add $16, %0 \n\t"
- "movdqu 16(%1), %%xmm1 \n\t"
- "movdqu %%xmm1, (%0) \n\t"
- "jmp 2f \n\t" // skip auxiliary routine
- /*
- * Finish generating the next two round keys.
- *
- * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and
- * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON
- *
- * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12
- * and those have been written to the output buffer.
- */
- "1: \n\t"
- "pshufd $0xff, %%xmm2, %%xmm2 \n\t"
- "pxor %%xmm0, %%xmm2 \n\t"
- "pslldq $4, %%xmm0 \n\t"
- "pxor %%xmm0, %%xmm2 \n\t"
- "pslldq $4, %%xmm0 \n\t"
- "pxor %%xmm0, %%xmm2 \n\t"
- "pslldq $4, %%xmm0 \n\t"
- "pxor %%xmm2, %%xmm0 \n\t"
- "add $16, %0 \n\t"
- "movdqu %%xmm0, (%0) \n\t"
- /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 )
- * and proceed to generate next round key from there */
- AESKEYGENA xmm0_xmm2 ",0x00 \n\t"
- "pshufd $0xaa, %%xmm2, %%xmm2 \n\t"
- "pxor %%xmm1, %%xmm2 \n\t"
- "pslldq $4, %%xmm1 \n\t"
- "pxor %%xmm1, %%xmm2 \n\t"
- "pslldq $4, %%xmm1 \n\t"
- "pxor %%xmm1, %%xmm2 \n\t"
- "pslldq $4, %%xmm1 \n\t"
- "pxor %%xmm2, %%xmm1 \n\t"
- "add $16, %0 \n\t"
- "movdqu %%xmm1, (%0) \n\t"
- "ret \n\t"
- /*
- * Main "loop" - Generating one more key than necessary,
- * see definition of mbedtls_aes_context.buf
- */
- "2: \n\t"
- AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
- AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
- :
- : "r" (rk), "r" (key)
- : "memory", "cc", "0" );
- }
- /*
- * Key expansion, wrapper
- */
- int mbedtls_aesni_setkey_enc( unsigned char *rk,
- const unsigned char *key,
- size_t bits )
- {
- switch( bits )
- {
- case 128: aesni_setkey_enc_128( rk, key ); break;
- case 192: aesni_setkey_enc_192( rk, key ); break;
- case 256: aesni_setkey_enc_256( rk, key ); break;
- default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_HAVE_X86_64 */
- #endif /* MBEDTLS_AESNI_C */
- /********* Start of file library/arc4.c ************/
- /*
- * An implementation of the ARCFOUR algorithm
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The ARCFOUR algorithm was publicly disclosed on 94/09.
- *
- * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ARC4_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_ARC4_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void arc4_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
- }
- void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
- {
- if( ctx == NULL )
- return;
- arc4_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
- }
- /*
- * ARC4 key schedule
- */
- void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
- unsigned int keylen )
- {
- int i, j, a;
- unsigned int k;
- unsigned char *m;
- ctx->x = 0;
- ctx->y = 0;
- m = ctx->m;
- for( i = 0; i < 256; i++ )
- m[i] = (unsigned char) i;
- j = k = 0;
- for( i = 0; i < 256; i++, k++ )
- {
- if( k >= keylen ) k = 0;
- a = m[i];
- j = ( j + a + key[k] ) & 0xFF;
- m[i] = m[j];
- m[j] = (unsigned char) a;
- }
- }
- /*
- * ARC4 cipher function
- */
- int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
- unsigned char *output )
- {
- int x, y, a, b;
- size_t i;
- unsigned char *m;
- x = ctx->x;
- y = ctx->y;
- m = ctx->m;
- for( i = 0; i < length; i++ )
- {
- x = ( x + 1 ) & 0xFF; a = m[x];
- y = ( y + a ) & 0xFF; b = m[y];
- m[x] = (unsigned char) b;
- m[y] = (unsigned char) a;
- output[i] = (unsigned char)
- ( input[i] ^ m[(unsigned char)( a + b )] );
- }
- ctx->x = x;
- ctx->y = y;
- return( 0 );
- }
- #endif /* !MBEDTLS_ARC4_ALT */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
- *
- * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
- */
- static const unsigned char arc4_test_key[3][8] =
- {
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- };
- static const unsigned char arc4_test_pt[3][8] =
- {
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- };
- static const unsigned char arc4_test_ct[3][8] =
- {
- { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
- { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
- { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
- };
- /*
- * Checkup routine
- */
- int mbedtls_arc4_self_test( int verbose )
- {
- int i, ret = 0;
- unsigned char ibuf[8];
- unsigned char obuf[8];
- mbedtls_arc4_context ctx;
- mbedtls_arc4_init( &ctx );
- for( i = 0; i < 3; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " ARC4 test #%d: ", i + 1 );
- memcpy( ibuf, arc4_test_pt[i], 8 );
- mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 );
- mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf );
- if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- exit:
- mbedtls_arc4_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_ARC4_C */
- /********* Start of file library/asn1parse.c ************/
- /*
- * Generic ASN.1 parsing
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ASN1_PARSE_C)
- #include <string.h>
- #if defined(MBEDTLS_BIGNUM_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void asn1_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * ASN.1 DER decoding routines
- */
- int mbedtls_asn1_get_len( unsigned char **p,
- const unsigned char *end,
- size_t *len )
- {
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- if( ( **p & 0x80 ) == 0 )
- *len = *(*p)++;
- else
- {
- switch( **p & 0x7F )
- {
- case 1:
- if( ( end - *p ) < 2 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- *len = (*p)[1];
- (*p) += 2;
- break;
- case 2:
- if( ( end - *p ) < 3 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
- (*p) += 3;
- break;
- case 3:
- if( ( end - *p ) < 4 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- *len = ( (size_t)(*p)[1] << 16 ) |
- ( (size_t)(*p)[2] << 8 ) | (*p)[3];
- (*p) += 4;
- break;
- case 4:
- if( ( end - *p ) < 5 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
- ( (size_t)(*p)[3] << 8 ) | (*p)[4];
- (*p) += 5;
- break;
- default:
- return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- }
- }
- if( *len > (size_t) ( end - *p ) )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- return( 0 );
- }
- int mbedtls_asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- size_t *len, int tag )
- {
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- if( **p != tag )
- return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- (*p)++;
- return( mbedtls_asn1_get_len( p, end, len ) );
- }
- int mbedtls_asn1_get_bool( unsigned char **p,
- const unsigned char *end,
- int *val )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
- return( ret );
- if( len != 1 )
- return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- *val = ( **p != 0 ) ? 1 : 0;
- (*p)++;
- return( 0 );
- }
- int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
- return( ret );
- if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
- return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- *val = 0;
- while( len-- > 0 )
- {
- *val = ( *val << 8 ) | **p;
- (*p)++;
- }
- return( 0 );
- }
- #if defined(MBEDTLS_BIGNUM_C)
- int mbedtls_asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mbedtls_mpi *X )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
- return( ret );
- ret = mbedtls_mpi_read_binary( X, *p, len );
- *p += len;
- return( ret );
- }
- #endif /* MBEDTLS_BIGNUM_C */
- int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
- mbedtls_asn1_bitstring *bs)
- {
- int ret;
- /* Certificate type is a single byte bitstring */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
- return( ret );
- /* Check length, subtract one for actual bit string length */
- if( bs->len < 1 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- bs->len -= 1;
- /* Get number of unused bits, ensure unused bits <= 7 */
- bs->unused_bits = **p;
- if( bs->unused_bits > 7 )
- return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- (*p)++;
- /* Get actual bitstring */
- bs->p = *p;
- *p += bs->len;
- if( *p != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * Get a bit string without unused bits
- */
- int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
- size_t *len )
- {
- int ret;
- if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
- return( ret );
- if( (*len)-- < 2 || *(*p)++ != 0 )
- return( MBEDTLS_ERR_ASN1_INVALID_DATA );
- return( 0 );
- }
- /*
- * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- */
- int mbedtls_asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_sequence *cur,
- int tag)
- {
- int ret;
- size_t len;
- mbedtls_asn1_buf *buf;
- /* Get main sequence tag */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( ret );
- if( *p + len != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- while( *p < end )
- {
- buf = &(cur->buf);
- buf->tag = **p;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
- return( ret );
- buf->p = *p;
- *p += buf->len;
- /* Allocate and assign next pointer */
- if( *p < end )
- {
- cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
- if( cur->next == NULL )
- return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
- cur = cur->next;
- }
- }
- /* Set final sequence entry's next pointer to NULL */
- cur->next = NULL;
- if( *p != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- int mbedtls_asn1_get_alg( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( ret );
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- alg->tag = **p;
- end = *p + len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( ret );
- alg->p = *p;
- *p += alg->len;
- if( *p == end )
- {
- asn1_zeroize( params, sizeof(mbedtls_asn1_buf) );
- return( 0 );
- }
- params->tag = **p;
- (*p)++;
- if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 )
- return( ret );
- params->p = *p;
- *p += params->len;
- if( *p != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- int mbedtls_asn1_get_alg_null( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_buf *alg )
- {
- int ret;
- mbedtls_asn1_buf params;
- memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) );
- if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 )
- return( ret );
- if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
- return( MBEDTLS_ERR_ASN1_INVALID_DATA );
- return( 0 );
- }
- void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
- {
- if( cur == NULL )
- return;
- mbedtls_free( cur->oid.p );
- mbedtls_free( cur->val.p );
- asn1_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
- }
- void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
- {
- mbedtls_asn1_named_data *cur;
- while( ( cur = *head ) != NULL )
- {
- *head = cur->next;
- mbedtls_asn1_free_named_data( cur );
- mbedtls_free( cur );
- }
- }
- mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
- const char *oid, size_t len )
- {
- while( list != NULL )
- {
- if( list->oid.len == len &&
- memcmp( list->oid.p, oid, len ) == 0 )
- {
- break;
- }
- list = list->next;
- }
- return( list );
- }
- #endif /* MBEDTLS_ASN1_PARSE_C */
- /********* Start of file library/asn1write.c ************/
- /*
- * ASN.1 buffer writing functionality
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ASN1_WRITE_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
- {
- if( len < 0x80 )
- {
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = (unsigned char) len;
- return( 1 );
- }
- if( len <= 0xFF )
- {
- if( *p - start < 2 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = (unsigned char) len;
- *--(*p) = 0x81;
- return( 2 );
- }
- if( *p - start < 3 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- // We assume we never have lengths larger than 65535 bytes
- //
- *--(*p) = len % 256;
- *--(*p) = ( len / 256 ) % 256;
- *--(*p) = 0x82;
- return( 3 );
- }
- int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
- {
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = tag;
- return( 1 );
- }
- int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
- const unsigned char *buf, size_t size )
- {
- size_t len = 0;
- if( *p < start || (size_t)( *p - start ) < size )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- len = size;
- (*p) -= len;
- memcpy( *p, buf, len );
- return( (int) len );
- }
- #if defined(MBEDTLS_BIGNUM_C)
- int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X )
- {
- int ret;
- size_t len = 0;
- // Write the MPI
- //
- len = mbedtls_mpi_size( X );
- if( *p < start || (size_t)( *p - start ) < len )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- (*p) -= len;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) );
- // DER format assumes 2s complement for numbers, so the leftmost bit
- // should be 0 for positive numbers and 1 for negative numbers.
- //
- if( X->s ==1 && **p & 0x80 )
- {
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = 0x00;
- len += 1;
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
- ret = (int) len;
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_BIGNUM_C */
- int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
- {
- int ret;
- size_t len = 0;
- // Write NULL
- //
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
- const char *oid, size_t oid_len )
- {
- int ret;
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
- (const unsigned char *) oid, oid_len ) );
- MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
- const char *oid, size_t oid_len,
- size_t par_len )
- {
- int ret;
- size_t len = 0;
- if( par_len == 0 )
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) );
- else
- len += par_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
- {
- int ret;
- size_t len = 0;
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = (boolean) ? 255 : 0;
- len++;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
- {
- int ret;
- size_t len = 0;
- // TODO negative values and values larger than 128
- // DER format assumes 2s complement for numbers, so the leftmost bit
- // should be 0 for positive numbers and 1 for negative numbers.
- //
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- len += 1;
- *--(*p) = val;
- if( val > 0 && **p & 0x80 )
- {
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = 0x00;
- len += 1;
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
- const char *text, size_t text_len )
- {
- int ret;
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
- (const unsigned char *) text, text_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
- const char *text, size_t text_len )
- {
- int ret;
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
- (const unsigned char *) text, text_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
- const unsigned char *buf, size_t bits )
- {
- int ret;
- size_t len = 0, size;
- size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
- // Calculate byte length
- //
- if( *p < start || (size_t)( *p - start ) < size + 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- len = size + 1;
- (*p) -= size;
- memcpy( *p, buf, size );
- // Write unused bits
- //
- *--(*p) = (unsigned char) (size * 8 - bits);
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
- return( (int) len );
- }
- int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
- const unsigned char *buf, size_t size )
- {
- int ret;
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
- return( (int) len );
- }
- mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head,
- const char *oid, size_t oid_len,
- const unsigned char *val,
- size_t val_len )
- {
- mbedtls_asn1_named_data *cur;
- if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
- {
- // Add new entry if not present yet based on OID
- //
- if( ( cur = mbedtls_calloc( 1, sizeof(mbedtls_asn1_named_data) ) ) == NULL )
- return( NULL );
- cur->oid.len = oid_len;
- cur->oid.p = mbedtls_calloc( 1, oid_len );
- if( cur->oid.p == NULL )
- {
- mbedtls_free( cur );
- return( NULL );
- }
- memcpy( cur->oid.p, oid, oid_len );
- cur->val.len = val_len;
- cur->val.p = mbedtls_calloc( 1, val_len );
- if( cur->val.p == NULL )
- {
- mbedtls_free( cur->oid.p );
- mbedtls_free( cur );
- return( NULL );
- }
- cur->next = *head;
- *head = cur;
- }
- else if( cur->val.len < val_len )
- {
- /*
- * Enlarge existing value buffer if needed
- * Preserve old data until the allocation succeeded, to leave list in
- * a consistent state in case allocation fails.
- */
- void *p = mbedtls_calloc( 1, val_len );
- if( p == NULL )
- return( NULL );
- mbedtls_free( cur->val.p );
- cur->val.p = p;
- cur->val.len = val_len;
- }
- if( val != NULL )
- memcpy( cur->val.p, val, val_len );
- return( cur );
- }
- #endif /* MBEDTLS_ASN1_WRITE_C */
- /********* Start of file library/base64.c ************/
- /*
- * RFC 1521 base64 encoding/decoding
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_BASE64_C)
- #if !VXWORKS
- #include <stdint.h>
- #endif
- #if defined(MBEDTLS_SELF_TEST)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- static const unsigned char base64_enc_map[64] =
- {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '+', '/'
- };
- static const unsigned char base64_dec_map[128] =
- {
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
- 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 127, 127, 127, 127, 127
- };
- #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
- /*
- * Encode a buffer into base64 format
- */
- int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
- const unsigned char *src, size_t slen )
- {
- size_t i, n;
- int C1, C2, C3;
- unsigned char *p;
- if( slen == 0 )
- {
- *olen = 0;
- return( 0 );
- }
- n = slen / 3 + ( slen % 3 != 0 );
- if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
- {
- *olen = BASE64_SIZE_T_MAX;
- return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
- }
- n *= 4;
- if( dlen < n + 1 )
- {
- *olen = n + 1;
- return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
- }
- n = ( slen / 3 ) * 3;
- for( i = 0, p = dst; i < n; i += 3 )
- {
- C1 = *src++;
- C2 = *src++;
- C3 = *src++;
- *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
- *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
- *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
- *p++ = base64_enc_map[C3 & 0x3F];
- }
- if( i < slen )
- {
- C1 = *src++;
- C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
- *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
- *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
- if( ( i + 1 ) < slen )
- *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
- else *p++ = '=';
- *p++ = '=';
- }
- *olen = p - dst;
- *p = 0;
- return( 0 );
- }
- /*
- * Decode a base64-formatted buffer
- */
- int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
- const unsigned char *src, size_t slen )
- {
- size_t i, n;
- uint32_t j, x;
- unsigned char *p;
- /* First pass: check for validity and get output length */
- for( i = n = j = 0; i < slen; i++ )
- {
- /* Skip spaces before checking for EOL */
- x = 0;
- while( i < slen && src[i] == ' ' )
- {
- ++i;
- ++x;
- }
- /* Spaces at end of buffer are OK */
- if( i == slen )
- break;
- if( ( slen - i ) >= 2 &&
- src[i] == '\r' && src[i + 1] == '\n' )
- continue;
- if( src[i] == '\n' )
- continue;
- /* Space inside a line is an error */
- if( x != 0 )
- return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
- if( src[i] == '=' && ++j > 2 )
- return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
- if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
- return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
- if( base64_dec_map[src[i]] < 64 && j != 0 )
- return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
- n++;
- }
- if( n == 0 )
- {
- *olen = 0;
- return( 0 );
- }
- n = ( ( n * 6 ) + 7 ) >> 3;
- n -= j;
- if( dst == NULL || dlen < n )
- {
- *olen = n;
- return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
- }
- for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
- {
- if( *src == '\r' || *src == '\n' || *src == ' ' )
- continue;
- j -= ( base64_dec_map[*src] == 64 );
- x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
- if( ++n == 4 )
- {
- n = 0;
- if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
- if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
- if( j > 2 ) *p++ = (unsigned char)( x );
- }
- }
- *olen = p - dst;
- return( 0 );
- }
- #if defined(MBEDTLS_SELF_TEST)
- static const unsigned char base64_test_dec[64] =
- {
- 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
- 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
- 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
- 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
- 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
- 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
- 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
- 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
- };
- static const unsigned char base64_test_enc[] =
- "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
- "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
- /*
- * Checkup routine
- */
- int mbedtls_base64_self_test( int verbose )
- {
- size_t len;
- const unsigned char *src;
- unsigned char buffer[128];
- if( verbose != 0 )
- mbedtls_printf( " Base64 encoding test: " );
- src = base64_test_dec;
- if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
- memcmp( base64_test_enc, buffer, 88 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n Base64 decoding test: " );
- src = base64_test_enc;
- if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
- memcmp( base64_test_dec, buffer, 64 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_BASE64_C */
- /********* Start of file library/bignum.c ************/
- /*
- * Multi-precision integer library
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The following sources were referenced in the design of this Multi-precision
- * Integer library:
- *
- * [1] Handbook of Applied Cryptography - 1997
- * Menezes, van Oorschot and Vanstone
- *
- * [2] Multi-Precision Math
- * Tom St Denis
- * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
- *
- * [3] GNU Multi-Precision Arithmetic Library
- * https://gmplib.org/manual/index.html
- *
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_BIGNUM_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #include <stdlib.h>
- #define mbedtls_printf printf
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void mbedtls_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
- #define biL (ciL << 3) /* bits in limb */
- #define biH (ciL << 2) /* half limb size */
- #define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
- /*
- * Convert between bits/chars and number of limbs
- * Divide first in order to avoid potential overflows
- */
- #define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
- #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
- /*
- * Initialize one MPI
- */
- void mbedtls_mpi_init( mbedtls_mpi *X )
- {
- if( X == NULL )
- return;
- X->s = 1;
- X->n = 0;
- X->p = NULL;
- }
- /*
- * Unallocate one MPI
- */
- void mbedtls_mpi_free( mbedtls_mpi *X )
- {
- if( X == NULL )
- return;
- if( X->p != NULL )
- {
- mbedtls_zeroize( X->p, X->n * ciL );
- mbedtls_free( X->p );
- }
- X->s = 1;
- X->n = 0;
- X->p = NULL;
- }
- /*
- * Enlarge to the specified number of limbs
- */
- int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
- {
- mbedtls_mpi_uint *p;
- if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
- return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
- if( X->n < nblimbs )
- {
- if( ( p = mbedtls_calloc( nblimbs, ciL ) ) == NULL )
- return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
- if( X->p != NULL )
- {
- memcpy( p, X->p, X->n * ciL );
- mbedtls_zeroize( X->p, X->n * ciL );
- mbedtls_free( X->p );
- }
- X->n = nblimbs;
- X->p = p;
- }
- return( 0 );
- }
- /*
- * Resize down as much as possible,
- * while keeping at least the specified number of limbs
- */
- int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
- {
- mbedtls_mpi_uint *p;
- size_t i;
- /* Actually resize up in this case */
- if( X->n <= nblimbs )
- return( mbedtls_mpi_grow( X, nblimbs ) );
- for( i = X->n - 1; i > 0; i-- )
- if( X->p[i] != 0 )
- break;
- i++;
- if( i < nblimbs )
- i = nblimbs;
- if( ( p = mbedtls_calloc( i, ciL ) ) == NULL )
- return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
- if( X->p != NULL )
- {
- memcpy( p, X->p, i * ciL );
- mbedtls_zeroize( X->p, X->n * ciL );
- mbedtls_free( X->p );
- }
- X->n = i;
- X->p = p;
- return( 0 );
- }
- /*
- * Copy the contents of Y into X
- */
- int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
- {
- int ret;
- size_t i;
- if( X == Y )
- return( 0 );
- if( Y->p == NULL )
- {
- mbedtls_mpi_free( X );
- return( 0 );
- }
- for( i = Y->n - 1; i > 0; i-- )
- if( Y->p[i] != 0 )
- break;
- i++;
- X->s = Y->s;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
- memset( X->p, 0, X->n * ciL );
- memcpy( X->p, Y->p, i * ciL );
- cleanup:
- return( ret );
- }
- /*
- * Swap the contents of X and Y
- */
- void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
- {
- mbedtls_mpi T;
- memcpy( &T, X, sizeof( mbedtls_mpi ) );
- memcpy( X, Y, sizeof( mbedtls_mpi ) );
- memcpy( Y, &T, sizeof( mbedtls_mpi ) );
- }
- /*
- * Conditionally assign X = Y, without leaking information
- * about whether the assignment was made or not.
- * (Leaking information about the respective sizes of X and Y is ok however.)
- */
- int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
- {
- int ret = 0;
- size_t i;
- /* make sure assign is 0 or 1 in a time-constant manner */
- assign = (assign | (unsigned char)-assign) >> 7;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
- X->s = X->s * ( 1 - assign ) + Y->s * assign;
- for( i = 0; i < Y->n; i++ )
- X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
- for( ; i < X->n; i++ )
- X->p[i] *= ( 1 - assign );
- cleanup:
- return( ret );
- }
- /*
- * Conditionally swap X and Y, without leaking information
- * about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
- * different memory access patterns when X and Y are used afterwards.
- */
- int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
- {
- int ret, s;
- size_t i;
- mbedtls_mpi_uint tmp;
- if( X == Y )
- return( 0 );
- /* make sure swap is 0 or 1 in a time-constant manner */
- swap = (swap | (unsigned char)-swap) >> 7;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
- s = X->s;
- X->s = X->s * ( 1 - swap ) + Y->s * swap;
- Y->s = Y->s * ( 1 - swap ) + s * swap;
- for( i = 0; i < X->n; i++ )
- {
- tmp = X->p[i];
- X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
- Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
- }
- cleanup:
- return( ret );
- }
- /*
- * Set value from integer
- */
- int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
- {
- int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
- memset( X->p, 0, X->n * ciL );
- X->p[0] = ( z < 0 ) ? -z : z;
- X->s = ( z < 0 ) ? -1 : 1;
- cleanup:
- return( ret );
- }
- /*
- * Get a specific bit
- */
- int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
- {
- if( X->n * biL <= pos )
- return( 0 );
- return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
- }
- /*
- * Set a bit to a specific value of 0 or 1
- */
- int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
- {
- int ret = 0;
- size_t off = pos / biL;
- size_t idx = pos % biL;
- if( val != 0 && val != 1 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- if( X->n * biL <= pos )
- {
- if( val == 0 )
- return( 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
- }
- X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
- X->p[off] |= (mbedtls_mpi_uint) val << idx;
- cleanup:
- return( ret );
- }
- /*
- * Return the number of less significant zero-bits
- */
- size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
- {
- size_t i, j, count = 0;
- for( i = 0; i < X->n; i++ )
- for( j = 0; j < biL; j++, count++ )
- if( ( ( X->p[i] >> j ) & 1 ) != 0 )
- return( count );
- return( 0 );
- }
- /*
- * Count leading zero bits in a given integer
- */
- static size_t mbedtls_clz( const mbedtls_mpi_uint x )
- {
- size_t j;
- mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
- for( j = 0; j < biL; j++ )
- {
- if( x & mask ) break;
- mask >>= 1;
- }
- return j;
- }
- /*
- * Return the number of bits
- */
- size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
- {
- size_t i, j;
- if( X->n == 0 )
- return( 0 );
- for( i = X->n - 1; i > 0; i-- )
- if( X->p[i] != 0 )
- break;
- j = biL - mbedtls_clz( X->p[i] );
- return( ( i * biL ) + j );
- }
- /*
- * Return the total size in bytes
- */
- size_t mbedtls_mpi_size( const mbedtls_mpi *X )
- {
- return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
- }
- /*
- * Convert an ASCII character to digit value
- */
- static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
- {
- *d = 255;
- if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
- if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
- if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
- if( *d >= (mbedtls_mpi_uint) radix )
- return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
- return( 0 );
- }
- /*
- * Import from an ASCII string
- */
- int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
- {
- int ret;
- size_t i, j, slen, n;
- mbedtls_mpi_uint d;
- mbedtls_mpi T;
- if( radix < 2 || radix > 16 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- mbedtls_mpi_init( &T );
- slen = strlen( s );
- if( radix == 16 )
- {
- if( slen > MPI_SIZE_T_MAX >> 2 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- n = BITS_TO_LIMBS( slen << 2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
- for( i = slen, j = 0; i > 0; i--, j++ )
- {
- if( i == 1 && s[i - 1] == '-' )
- {
- X->s = -1;
- break;
- }
- MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
- X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
- }
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
- for( i = 0; i < slen; i++ )
- {
- if( i == 0 && s[i] == '-' )
- {
- X->s = -1;
- continue;
- }
- MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
- if( X->s == 1 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
- }
- }
- }
- cleanup:
- mbedtls_mpi_free( &T );
- return( ret );
- }
- /*
- * Helper to write the digits high-order first
- */
- static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p )
- {
- int ret;
- mbedtls_mpi_uint r;
- if( radix < 2 || radix > 16 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
- if( mbedtls_mpi_cmp_int( X, 0 ) != 0 )
- MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) );
- if( r < 10 )
- *(*p)++ = (char)( r + 0x30 );
- else
- *(*p)++ = (char)( r + 0x37 );
- cleanup:
- return( ret );
- }
- /*
- * Export into an ASCII string
- */
- int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
- char *buf, size_t buflen, size_t *olen )
- {
- int ret = 0;
- size_t n;
- char *p;
- mbedtls_mpi T;
- if( radix < 2 || radix > 16 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- n = mbedtls_mpi_bitlen( X );
- if( radix >= 4 ) n >>= 1;
- if( radix >= 16 ) n >>= 1;
- n += 3;
- if( buflen < n )
- {
- *olen = n;
- return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
- }
- p = buf;
- mbedtls_mpi_init( &T );
- if( X->s == -1 )
- *p++ = '-';
- if( radix == 16 )
- {
- int c;
- size_t i, j, k;
- for( i = X->n, k = 0; i > 0; i-- )
- {
- for( j = ciL; j > 0; j-- )
- {
- c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
- if( c == 0 && k == 0 && ( i + j ) != 2 )
- continue;
- *(p++) = "0123456789ABCDEF" [c / 16];
- *(p++) = "0123456789ABCDEF" [c % 16];
- k = 1;
- }
- }
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
- if( T.s == -1 )
- T.s = 1;
- MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
- }
- *p++ = '\0';
- *olen = p - buf;
- cleanup:
- mbedtls_mpi_free( &T );
- return( ret );
- }
- #if defined(MBEDTLS_FS_IO)
- /*
- * Read X from an opened file
- */
- int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
- {
- mbedtls_mpi_uint d;
- size_t slen;
- char *p;
- /*
- * Buffer should have space for (short) label and decimal formatted MPI,
- * newline characters and '\0'
- */
- char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
- memset( s, 0, sizeof( s ) );
- if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
- return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
- slen = strlen( s );
- if( slen == sizeof( s ) - 2 )
- return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
- if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
- if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
- p = s + slen;
- while( --p >= s )
- if( mpi_get_digit( &d, radix, *p ) != 0 )
- break;
- return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
- }
- /*
- * Write X into an opened file (or stdout if fout == NULL)
- */
- int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
- {
- int ret;
- size_t n, slen, plen;
- /*
- * Buffer should have space for (short) label and decimal formatted MPI,
- * newline characters and '\0'
- */
- char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
- memset( s, 0, sizeof( s ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
- if( p == NULL ) p = "";
- plen = strlen( p );
- slen = strlen( s );
- s[slen++] = '\r';
- s[slen++] = '\n';
- if( fout != NULL )
- {
- if( fwrite( p, 1, plen, fout ) != plen ||
- fwrite( s, 1, slen, fout ) != slen )
- return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
- }
- else
- mbedtls_printf( "%s%s", p, s );
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- /*
- * Import X from unsigned binary data, big endian
- */
- int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
- {
- int ret;
- size_t i, j, n;
- for( n = 0; n < buflen; n++ )
- if( buf[n] != 0 )
- break;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
- for( i = buflen, j = 0; i > n; i--, j++ )
- X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
- cleanup:
- return( ret );
- }
- /*
- * Export X into unsigned binary data, big endian
- */
- int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen )
- {
- size_t i, j, n;
- n = mbedtls_mpi_size( X );
- if( buflen < n )
- return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
- memset( buf, 0, buflen );
- for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
- buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
- return( 0 );
- }
- /*
- * Left-shift: X <<= count
- */
- int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
- {
- int ret;
- size_t i, v0, t1;
- mbedtls_mpi_uint r0 = 0, r1;
- v0 = count / (biL );
- t1 = count & (biL - 1);
- i = mbedtls_mpi_bitlen( X ) + count;
- if( X->n * biL < i )
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
- ret = 0;
- /*
- * shift by count / limb_size
- */
- if( v0 > 0 )
- {
- for( i = X->n; i > v0; i-- )
- X->p[i - 1] = X->p[i - v0 - 1];
- for( ; i > 0; i-- )
- X->p[i - 1] = 0;
- }
- /*
- * shift by count % limb_size
- */
- if( t1 > 0 )
- {
- for( i = v0; i < X->n; i++ )
- {
- r1 = X->p[i] >> (biL - t1);
- X->p[i] <<= t1;
- X->p[i] |= r0;
- r0 = r1;
- }
- }
- cleanup:
- return( ret );
- }
- /*
- * Right-shift: X >>= count
- */
- int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
- {
- size_t i, v0, v1;
- mbedtls_mpi_uint r0 = 0, r1;
- v0 = count / biL;
- v1 = count & (biL - 1);
- if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
- return mbedtls_mpi_lset( X, 0 );
- /*
- * shift by count / limb_size
- */
- if( v0 > 0 )
- {
- for( i = 0; i < X->n - v0; i++ )
- X->p[i] = X->p[i + v0];
- for( ; i < X->n; i++ )
- X->p[i] = 0;
- }
- /*
- * shift by count % limb_size
- */
- if( v1 > 0 )
- {
- for( i = X->n; i > 0; i-- )
- {
- r1 = X->p[i - 1] << (biL - v1);
- X->p[i - 1] >>= v1;
- X->p[i - 1] |= r0;
- r0 = r1;
- }
- }
- return( 0 );
- }
- /*
- * Compare unsigned values
- */
- int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
- {
- size_t i, j;
- for( i = X->n; i > 0; i-- )
- if( X->p[i - 1] != 0 )
- break;
- for( j = Y->n; j > 0; j-- )
- if( Y->p[j - 1] != 0 )
- break;
- if( i == 0 && j == 0 )
- return( 0 );
- if( i > j ) return( 1 );
- if( j > i ) return( -1 );
- for( ; i > 0; i-- )
- {
- if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
- if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
- }
- return( 0 );
- }
- /*
- * Compare signed values
- */
- int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
- {
- size_t i, j;
- for( i = X->n; i > 0; i-- )
- if( X->p[i - 1] != 0 )
- break;
- for( j = Y->n; j > 0; j-- )
- if( Y->p[j - 1] != 0 )
- break;
- if( i == 0 && j == 0 )
- return( 0 );
- if( i > j ) return( X->s );
- if( j > i ) return( -Y->s );
- if( X->s > 0 && Y->s < 0 ) return( 1 );
- if( Y->s > 0 && X->s < 0 ) return( -1 );
- for( ; i > 0; i-- )
- {
- if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
- if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
- }
- return( 0 );
- }
- /*
- * Compare signed values
- */
- int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
- {
- mbedtls_mpi Y;
- mbedtls_mpi_uint p[1];
- *p = ( z < 0 ) ? -z : z;
- Y.s = ( z < 0 ) ? -1 : 1;
- Y.n = 1;
- Y.p = p;
- return( mbedtls_mpi_cmp_mpi( X, &Y ) );
- }
- /*
- * Unsigned addition: X = |A| + |B| (HAC 14.7)
- */
- int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret;
- size_t i, j;
- mbedtls_mpi_uint *o, *p, c;
- if( X == B )
- {
- const mbedtls_mpi *T = A; A = X; B = T;
- }
- if( X != A )
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
- /*
- * X should always be positive as a result of unsigned additions.
- */
- X->s = 1;
- for( j = B->n; j > 0; j-- )
- if( B->p[j - 1] != 0 )
- break;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
- o = B->p; p = X->p; c = 0;
- for( i = 0; i < j; i++, o++, p++ )
- {
- *p += c; c = ( *p < c );
- *p += *o; c += ( *p < *o );
- }
- while( c != 0 )
- {
- if( i >= X->n )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
- p = X->p + i;
- }
- *p += c; c = ( *p < c ); i++; p++;
- }
- cleanup:
- return( ret );
- }
- /*
- * Helper for mbedtls_mpi subtraction
- */
- static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
- {
- size_t i;
- mbedtls_mpi_uint c, z;
- for( i = c = 0; i < n; i++, s++, d++ )
- {
- z = ( *d < c ); *d -= c;
- c = ( *d < *s ) + z; *d -= *s;
- }
- while( c != 0 )
- {
- z = ( *d < c ); *d -= c;
- c = z; i++; d++;
- }
- }
- /*
- * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
- */
- int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- mbedtls_mpi TB;
- int ret;
- size_t n;
- if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
- return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
- mbedtls_mpi_init( &TB );
- if( X == B )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
- B = &TB;
- }
- if( X != A )
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
- /*
- * X should always be positive as a result of unsigned subtractions.
- */
- X->s = 1;
- ret = 0;
- for( n = B->n; n > 0; n-- )
- if( B->p[n - 1] != 0 )
- break;
- mpi_sub_hlp( n, B->p, X->p );
- cleanup:
- mbedtls_mpi_free( &TB );
- return( ret );
- }
- /*
- * Signed addition: X = A + B
- */
- int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret, s = A->s;
- if( A->s * B->s < 0 )
- {
- if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
- X->s = s;
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
- X->s = -s;
- }
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
- X->s = s;
- }
- cleanup:
- return( ret );
- }
- /*
- * Signed subtraction: X = A - B
- */
- int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret, s = A->s;
- if( A->s * B->s > 0 )
- {
- if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
- X->s = s;
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
- X->s = -s;
- }
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
- X->s = s;
- }
- cleanup:
- return( ret );
- }
- /*
- * Signed addition: X = A + b
- */
- int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
- {
- mbedtls_mpi _B;
- mbedtls_mpi_uint p[1];
- p[0] = ( b < 0 ) ? -b : b;
- _B.s = ( b < 0 ) ? -1 : 1;
- _B.n = 1;
- _B.p = p;
- return( mbedtls_mpi_add_mpi( X, A, &_B ) );
- }
- /*
- * Signed subtraction: X = A - b
- */
- int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
- {
- mbedtls_mpi _B;
- mbedtls_mpi_uint p[1];
- p[0] = ( b < 0 ) ? -b : b;
- _B.s = ( b < 0 ) ? -1 : 1;
- _B.n = 1;
- _B.p = p;
- return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
- }
- /*
- * Helper for mbedtls_mpi multiplication
- */
- static
- #if defined(__APPLE__) && defined(__arm__)
- /*
- * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
- * appears to need this to prevent bad ARM code generation at -O3.
- */
- __attribute__ ((noinline))
- #endif
- void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
- {
- mbedtls_mpi_uint c = 0, t = 0;
- #if defined(MULADDC_HUIT)
- for( ; i >= 8; i -= 8 )
- {
- MULADDC_INIT
- MULADDC_HUIT
- MULADDC_STOP
- }
- for( ; i > 0; i-- )
- {
- MULADDC_INIT
- MULADDC_CORE
- MULADDC_STOP
- }
- #else /* MULADDC_HUIT */
- for( ; i >= 16; i -= 16 )
- {
- MULADDC_INIT
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_STOP
- }
- for( ; i >= 8; i -= 8 )
- {
- MULADDC_INIT
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_STOP
- }
- for( ; i > 0; i-- )
- {
- MULADDC_INIT
- MULADDC_CORE
- MULADDC_STOP
- }
- #endif /* MULADDC_HUIT */
- t++;
- do {
- *d += c; c = ( *d < c ); d++;
- }
- while( c != 0 );
- }
- /*
- * Baseline multiplication: X = A * B (HAC 14.12)
- */
- int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret;
- size_t i, j;
- mbedtls_mpi TA, TB;
- mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
- if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
- if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
- for( i = A->n; i > 0; i-- )
- if( A->p[i - 1] != 0 )
- break;
- for( j = B->n; j > 0; j-- )
- if( B->p[j - 1] != 0 )
- break;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
- for( i++; j > 0; j-- )
- mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
- X->s = A->s * B->s;
- cleanup:
- mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
- return( ret );
- }
- /*
- * Baseline multiplication: X = A * b
- */
- int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
- {
- mbedtls_mpi _B;
- mbedtls_mpi_uint p[1];
- _B.s = 1;
- _B.n = 1;
- _B.p = p;
- p[0] = b;
- return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
- }
- /*
- * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
- * mbedtls_mpi_uint divisor, d
- */
- static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
- mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
- {
- #if defined(MBEDTLS_HAVE_UDBL)
- mbedtls_t_udbl dividend, quotient;
- #else
- const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
- const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
- mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
- mbedtls_mpi_uint u0_msw, u0_lsw;
- size_t s;
- #endif
- /*
- * Check for overflow
- */
- if( 0 == d || u1 >= d )
- {
- if (r != NULL) *r = ~0;
- return ( ~0 );
- }
- #if defined(MBEDTLS_HAVE_UDBL)
- dividend = (mbedtls_t_udbl) u1 << biL;
- dividend |= (mbedtls_t_udbl) u0;
- quotient = dividend / d;
- if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
- quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
- if( r != NULL )
- *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
- return (mbedtls_mpi_uint) quotient;
- #else
- /*
- * Algorithm D, Section 4.3.1 - The Art of Computer Programming
- * Vol. 2 - Seminumerical Algorithms, Knuth
- */
- /*
- * Normalize the divisor, d, and dividend, u0, u1
- */
- s = mbedtls_clz( d );
- d = d << s;
- u1 = u1 << s;
- u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
- u0 = u0 << s;
- d1 = d >> biH;
- d0 = d & uint_halfword_mask;
- u0_msw = u0 >> biH;
- u0_lsw = u0 & uint_halfword_mask;
- /*
- * Find the first quotient and remainder
- */
- q1 = u1 / d1;
- r0 = u1 - d1 * q1;
- while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
- {
- q1 -= 1;
- r0 += d1;
- if ( r0 >= radix ) break;
- }
- rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
- q0 = rAX / d1;
- r0 = rAX - q0 * d1;
- while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
- {
- q0 -= 1;
- r0 += d1;
- if ( r0 >= radix ) break;
- }
- if (r != NULL)
- *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
- quotient = q1 * radix + q0;
- return quotient;
- #endif
- }
- /*
- * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
- */
- int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret;
- size_t i, n, t, k;
- mbedtls_mpi X, Y, Z, T1, T2;
- if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
- return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
- mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
- mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
- if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
- {
- if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
- if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
- return( 0 );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
- X.s = Y.s = 1;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
- k = mbedtls_mpi_bitlen( &Y ) % biL;
- if( k < biL - 1 )
- {
- k = biL - 1 - k;
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
- }
- else k = 0;
- n = X.n - 1;
- t = Y.n - 1;
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
- while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
- {
- Z.p[n - t]++;
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
- for( i = n; i > t ; i-- )
- {
- if( X.p[i] >= Y.p[t] )
- Z.p[i - t - 1] = ~0;
- else
- {
- Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
- Y.p[t], NULL);
- }
- Z.p[i - t - 1]++;
- do
- {
- Z.p[i - t - 1]--;
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
- T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
- T1.p[1] = Y.p[t];
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
- T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
- T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
- T2.p[2] = X.p[i];
- }
- while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
- if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
- Z.p[i - t - 1]--;
- }
- }
- if( Q != NULL )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
- Q->s = A->s * B->s;
- }
- if( R != NULL )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
- X.s = A->s;
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
- if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
- R->s = 1;
- }
- cleanup:
- mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
- mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
- return( ret );
- }
- /*
- * Division by int: A = Q * b + R
- */
- int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b )
- {
- mbedtls_mpi _B;
- mbedtls_mpi_uint p[1];
- p[0] = ( b < 0 ) ? -b : b;
- _B.s = ( b < 0 ) ? -1 : 1;
- _B.n = 1;
- _B.p = p;
- return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
- }
- /*
- * Modulo: R = A mod B
- */
- int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret;
- if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
- return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
- MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
- while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
- while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
- cleanup:
- return( ret );
- }
- /*
- * Modulo: r = A mod b
- */
- int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
- {
- size_t i;
- mbedtls_mpi_uint x, y, z;
- if( b == 0 )
- return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
- if( b < 0 )
- return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
- /*
- * handle trivial cases
- */
- if( b == 1 )
- {
- *r = 0;
- return( 0 );
- }
- if( b == 2 )
- {
- *r = A->p[0] & 1;
- return( 0 );
- }
- /*
- * general case
- */
- for( i = A->n, y = 0; i > 0; i-- )
- {
- x = A->p[i - 1];
- y = ( y << biH ) | ( x >> biH );
- z = y / b;
- y -= z * b;
- x <<= biH;
- y = ( y << biH ) | ( x >> biH );
- z = y / b;
- y -= z * b;
- }
- /*
- * If A is negative, then the current y represents a negative value.
- * Flipping it to the positive side.
- */
- if( A->s < 0 && y != 0 )
- y = b - y;
- *r = y;
- return( 0 );
- }
- /*
- * Fast Montgomery initialization (thanks to Tom St Denis)
- */
- static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
- {
- mbedtls_mpi_uint x, m0 = N->p[0];
- unsigned int i;
- x = m0;
- x += ( ( m0 + 2 ) & 4 ) << 1;
- for( i = biL; i >= 8; i /= 2 )
- x *= ( 2 - ( m0 * x ) );
- *mm = ~x + 1;
- }
- /*
- * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
- */
- static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
- const mbedtls_mpi *T )
- {
- size_t i, n, m;
- mbedtls_mpi_uint u0, u1, *d;
- memset( T->p, 0, T->n * ciL );
- d = T->p;
- n = N->n;
- m = ( B->n < n ) ? B->n : n;
- for( i = 0; i < n; i++ )
- {
- /*
- * T = (T + u0*B + u1*N) / 2^biL
- */
- u0 = A->p[i];
- u1 = ( d[0] + u0 * B->p[0] ) * mm;
- mpi_mul_hlp( m, B->p, d, u0 );
- mpi_mul_hlp( n, N->p, d, u1 );
- *d++ = u0; d[n + 1] = 0;
- }
- memcpy( A->p, d, ( n + 1 ) * ciL );
- if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
- mpi_sub_hlp( n, N->p, A->p );
- else
- /* prevent timing attacks */
- mpi_sub_hlp( n, A->p, T->p );
- }
- /*
- * Montgomery reduction: A = A * R^-1 mod N
- */
- static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
- {
- mbedtls_mpi_uint z = 1;
- mbedtls_mpi U;
- U.n = U.s = (int) z;
- U.p = &z;
- mpi_montmul( A, &U, N, mm, T );
- }
- /*
- * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
- */
- int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR )
- {
- int ret;
- size_t wbits, wsize, one = 1;
- size_t i, j, nblimbs;
- size_t bufsize, nbits;
- mbedtls_mpi_uint ei, mm, state;
- mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
- int neg;
- if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- /*
- * Init temps and window size
- */
- mpi_montg_init( &mm, N );
- mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
- mbedtls_mpi_init( &Apos );
- memset( W, 0, sizeof( W ) );
- i = mbedtls_mpi_bitlen( E );
- wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
- ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
- if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
- wsize = MBEDTLS_MPI_WINDOW_SIZE;
- j = N->n + 1;
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
- /*
- * Compensate for negative A (and correct at the end)
- */
- neg = ( A->s == -1 );
- if( neg )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
- Apos.s = 1;
- A = &Apos;
- }
- /*
- * If 1st call, pre-compute R^2 mod N
- */
- if( _RR == NULL || _RR->p == NULL )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
- if( _RR != NULL )
- memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
- }
- else
- memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
- /*
- * W[1] = A * R^2 * R^-1 mod N = A * R mod N
- */
- if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
- else
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
- mpi_montmul( &W[1], &RR, N, mm, &T );
- /*
- * X = R^2 * R^-1 mod N = R mod N
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
- mpi_montred( X, N, mm, &T );
- if( wsize > 1 )
- {
- /*
- * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
- */
- j = one << ( wsize - 1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
- for( i = 0; i < wsize - 1; i++ )
- mpi_montmul( &W[j], &W[j], N, mm, &T );
- /*
- * W[i] = W[i - 1] * W[1]
- */
- for( i = j + 1; i < ( one << wsize ); i++ )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
- mpi_montmul( &W[i], &W[1], N, mm, &T );
- }
- }
- nblimbs = E->n;
- bufsize = 0;
- nbits = 0;
- wbits = 0;
- state = 0;
- while( 1 )
- {
- if( bufsize == 0 )
- {
- if( nblimbs == 0 )
- break;
- nblimbs--;
- bufsize = sizeof( mbedtls_mpi_uint ) << 3;
- }
- bufsize--;
- ei = (E->p[nblimbs] >> bufsize) & 1;
- /*
- * skip leading 0s
- */
- if( ei == 0 && state == 0 )
- continue;
- if( ei == 0 && state == 1 )
- {
- /*
- * out of window, square X
- */
- mpi_montmul( X, X, N, mm, &T );
- continue;
- }
- /*
- * add ei to current window
- */
- state = 2;
- nbits++;
- wbits |= ( ei << ( wsize - nbits ) );
- if( nbits == wsize )
- {
- /*
- * X = X^wsize R^-1 mod N
- */
- for( i = 0; i < wsize; i++ )
- mpi_montmul( X, X, N, mm, &T );
- /*
- * X = X * W[wbits] R^-1 mod N
- */
- mpi_montmul( X, &W[wbits], N, mm, &T );
- state--;
- nbits = 0;
- wbits = 0;
- }
- }
- /*
- * process the remaining bits
- */
- for( i = 0; i < nbits; i++ )
- {
- mpi_montmul( X, X, N, mm, &T );
- wbits <<= 1;
- if( ( wbits & ( one << wsize ) ) != 0 )
- mpi_montmul( X, &W[1], N, mm, &T );
- }
- /*
- * X = A^E * R * R^-1 mod N = A^E mod N
- */
- mpi_montred( X, N, mm, &T );
- if( neg )
- {
- X->s = -1;
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
- }
- cleanup:
- for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
- mbedtls_mpi_free( &W[i] );
- mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
- if( _RR == NULL || _RR->p == NULL )
- mbedtls_mpi_free( &RR );
- return( ret );
- }
- /*
- * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
- */
- int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
- {
- int ret;
- size_t lz, lzt;
- mbedtls_mpi TG, TA, TB;
- mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
- lz = mbedtls_mpi_lsb( &TA );
- lzt = mbedtls_mpi_lsb( &TB );
- if( lzt < lz )
- lz = lzt;
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
- TA.s = TB.s = 1;
- while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
- if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
- }
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
- cleanup:
- mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
- return( ret );
- }
- /*
- * Fill X with size bytes of random.
- *
- * Use a temporary bytes representation to make sure the result is the same
- * regardless of the platform endianness (useful when f_rng is actually
- * deterministic, eg for tests).
- */
- int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- if( size > MBEDTLS_MPI_MAX_SIZE )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
- cleanup:
- return( ret );
- }
- /*
- * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
- */
- int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
- {
- int ret;
- mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
- if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
- mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV );
- mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
- if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
- {
- ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
- do
- {
- while( ( TU.p[0] & 1 ) == 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
- if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
- }
- while( ( TV.p[0] & 1 ) == 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
- if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
- }
- if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
- }
- }
- while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
- while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
- while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
- cleanup:
- mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
- mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
- mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
- return( ret );
- }
- #if defined(MBEDTLS_GENPRIME)
- static const int small_prime[] =
- {
- 3, 5, 7, 11, 13, 17, 19, 23,
- 29, 31, 37, 41, 43, 47, 53, 59,
- 61, 67, 71, 73, 79, 83, 89, 97,
- 101, 103, 107, 109, 113, 127, 131, 137,
- 139, 149, 151, 157, 163, 167, 173, 179,
- 181, 191, 193, 197, 199, 211, 223, 227,
- 229, 233, 239, 241, 251, 257, 263, 269,
- 271, 277, 281, 283, 293, 307, 311, 313,
- 317, 331, 337, 347, 349, 353, 359, 367,
- 373, 379, 383, 389, 397, 401, 409, 419,
- 421, 431, 433, 439, 443, 449, 457, 461,
- 463, 467, 479, 487, 491, 499, 503, 509,
- 521, 523, 541, 547, 557, 563, 569, 571,
- 577, 587, 593, 599, 601, 607, 613, 617,
- 619, 631, 641, 643, 647, 653, 659, 661,
- 673, 677, 683, 691, 701, 709, 719, 727,
- 733, 739, 743, 751, 757, 761, 769, 773,
- 787, 797, 809, 811, 821, 823, 827, 829,
- 839, 853, 857, 859, 863, 877, 881, 883,
- 887, 907, 911, 919, 929, 937, 941, 947,
- 953, 967, 971, 977, 983, 991, 997, -103
- };
- /*
- * Small divisors test (X must be positive)
- *
- * Return values:
- * 0: no small factor (possible prime, more tests needed)
- * 1: certain prime
- * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
- * other negative: error
- */
- static int mpi_check_small_factors( const mbedtls_mpi *X )
- {
- int ret = 0;
- size_t i;
- mbedtls_mpi_uint r;
- if( ( X->p[0] & 1 ) == 0 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
- for( i = 0; small_prime[i] > 0; i++ )
- {
- if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
- return( 1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
- if( r == 0 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
- }
- cleanup:
- return( ret );
- }
- /*
- * Miller-Rabin pseudo-primality test (HAC 4.24)
- */
- static int mpi_miller_rabin( const mbedtls_mpi *X,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret, count;
- size_t i, j, k, n, s;
- mbedtls_mpi W, R, T, A, RR;
- mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
- mbedtls_mpi_init( &RR );
- /*
- * W = |X| - 1
- * R = W >> lsb( W )
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
- s = mbedtls_mpi_lsb( &W );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
- i = mbedtls_mpi_bitlen( X );
- /*
- * HAC, table 4.4
- */
- n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
- ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
- ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
- for( i = 0; i < n; i++ )
- {
- /*
- * pick a random A, 1 < A < |X| - 1
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
- if( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 )
- {
- j = mbedtls_mpi_bitlen( &A ) - mbedtls_mpi_bitlen( &W );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j + 1 ) );
- }
- A.p[0] |= 3;
- count = 0;
- do {
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
- j = mbedtls_mpi_bitlen( &A );
- k = mbedtls_mpi_bitlen( &W );
- if (j > k) {
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j - k ) );
- }
- if (count++ > 30) {
- return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
- }
- } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
- mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
- /*
- * A = A^R mod |X|
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
- if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
- mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
- continue;
- j = 1;
- while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
- {
- /*
- * A = A * A mod |X|
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
- if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
- break;
- j++;
- }
- /*
- * not prime if A != |X| - 1 or A == 1
- */
- if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
- mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
- {
- ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
- break;
- }
- }
- cleanup:
- mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
- mbedtls_mpi_free( &RR );
- return( ret );
- }
- /*
- * Pseudo-primality test: small factors, then Miller-Rabin
- */
- int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_mpi XX;
- XX.s = 1;
- XX.n = X->n;
- XX.p = X->p;
- if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
- mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
- if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
- return( 0 );
- if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
- {
- if( ret == 1 )
- return( 0 );
- return( ret );
- }
- return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
- }
- /*
- * Prime number generation
- */
- int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- size_t k, n;
- mbedtls_mpi_uint r;
- mbedtls_mpi Y;
- if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
- return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- mbedtls_mpi_init( &Y );
- n = BITS_TO_LIMBS( nbits );
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
- k = mbedtls_mpi_bitlen( X );
- if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) );
- mbedtls_mpi_set_bit( X, nbits-1, 1 );
- X->p[0] |= 1;
- if( dh_flag == 0 )
- {
- while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
- {
- if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
- goto cleanup;
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
- }
- }
- else
- {
- /*
- * An necessary condition for Y and X = 2Y + 1 to be prime
- * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
- * Make sure it is satisfied, while keeping X = 3 mod 4
- */
- X->p[0] |= 2;
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
- if( r == 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
- else if( r == 1 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
- /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
- while( 1 )
- {
- /*
- * First, check small factors for X and Y
- * before doing Miller-Rabin on any of them
- */
- if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
- ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
- ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
- ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
- {
- break;
- }
- if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
- goto cleanup;
- /*
- * Next candidates. We want to preserve Y = (X-1) / 2 and
- * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
- * so up Y by 6 and X by 12.
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
- }
- }
- cleanup:
- mbedtls_mpi_free( &Y );
- return( ret );
- }
- #endif /* MBEDTLS_GENPRIME */
- #if defined(MBEDTLS_SELF_TEST)
- #define GCD_PAIR_COUNT 3
- static const int gcd_pairs[GCD_PAIR_COUNT][3] =
- {
- { 693, 609, 21 },
- { 1764, 868, 28 },
- { 768454923, 542167814, 1 }
- };
- /*
- * Checkup routine
- */
- int mbedtls_mpi_self_test( int verbose )
- {
- int ret, i;
- mbedtls_mpi A, E, N, X, Y, U, V;
- mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X );
- mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
- "EFE021C2645FD1DC586E69184AF4A31E" \
- "D5F53E93B5F123FA41680867BA110131" \
- "944FE7952E2517337780CB0DB80E61AA" \
- "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
- "B2E7EFD37075B9F03FF989C7C5051C20" \
- "34D2A323810251127E7BF8625A4F49A5" \
- "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
- "5B5C25763222FEFCCFC38B832366C29E" ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
- "0066A198186C18C10B2F5ED9B522752A" \
- "9830B69916E535C8F047518A889A43A5" \
- "94B6BED27A168D31D4A52F88925AA8F5" ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
- "602AB7ECA597A3D6B56FF9829A5E8B85" \
- "9E857EA95A03512E2BAE7391688D264A" \
- "A5663B0341DB9CCFD2C4C5F421FEC814" \
- "8001B72E848A38CAE1C65F78E56ABDEF" \
- "E12D3C039B8A02D6BE593F0BBBDA56F1" \
- "ECF677152EF804370C1A305CAF3B5BF1" \
- "30879B56C61DE584A0F53A2447A51E" ) );
- if( verbose != 0 )
- mbedtls_printf( " MPI test #1 (mul_mpi): " );
- if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto cleanup;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
- "256567336059E52CAE22925474705F39A94" ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
- "6613F26162223DF488E9CD48CC132C7A" \
- "0AC93C701B001B092E4E5B9F73BCD27B" \
- "9EE50D0657C77F374E903CDFA4C642" ) );
- if( verbose != 0 )
- mbedtls_printf( " MPI test #2 (div_mpi): " );
- if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
- mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto cleanup;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
- "36E139AEA55215609D2816998ED020BB" \
- "BD96C37890F65171D948E9BC7CBAA4D9" \
- "325D24D6A3C12710F10A09FA08AB87" ) );
- if( verbose != 0 )
- mbedtls_printf( " MPI test #3 (exp_mod): " );
- if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto cleanup;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
- "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
- "C3DBA76456363A10869622EAC2DD84EC" \
- "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
- if( verbose != 0 )
- mbedtls_printf( " MPI test #4 (inv_mod): " );
- if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto cleanup;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " MPI test #5 (simple gcd): " );
- for( i = 0; i < GCD_PAIR_COUNT; i++ )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
- if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed at %d\n", i );
- ret = 1;
- goto cleanup;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- cleanup:
- if( ret != 0 && verbose != 0 )
- mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
- mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
- mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_BIGNUM_C */
- /********* Start of file library/blowfish.c ************/
- /*
- * Blowfish implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The Blowfish block cipher was designed by Bruce Schneier in 1993.
- * http://www.schneier.com/blowfish.html
- * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29
- *
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_BLOWFISH_C)
- #include <string.h>
- #if !defined(MBEDTLS_BLOWFISH_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void blowfish_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- }
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- }
- #endif
- static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
- 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
- 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
- 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
- 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
- 0x9216D5D9L, 0x8979FB1BL
- };
- /* declarations of data at the end of this file */
- static const uint32_t S[4][256];
- static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
- {
- unsigned short a, b, c, d;
- uint32_t y;
- d = (unsigned short)(x & 0xFF);
- x >>= 8;
- c = (unsigned short)(x & 0xFF);
- x >>= 8;
- b = (unsigned short)(x & 0xFF);
- x >>= 8;
- a = (unsigned short)(x & 0xFF);
- y = ctx->S[0][a] + ctx->S[1][b];
- y = y ^ ctx->S[2][c];
- y = y + ctx->S[3][d];
- return( y );
- }
- static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
- {
- uint32_t Xl, Xr, temp;
- short i;
- Xl = *xl;
- Xr = *xr;
- for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i )
- {
- Xl = Xl ^ ctx->P[i];
- Xr = F( ctx, Xl ) ^ Xr;
- temp = Xl;
- Xl = Xr;
- Xr = temp;
- }
- temp = Xl;
- Xl = Xr;
- Xr = temp;
- Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS];
- Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1];
- *xl = Xl;
- *xr = Xr;
- }
- static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
- {
- uint32_t Xl, Xr, temp;
- short i;
- Xl = *xl;
- Xr = *xr;
- for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i )
- {
- Xl = Xl ^ ctx->P[i];
- Xr = F( ctx, Xl ) ^ Xr;
- temp = Xl;
- Xl = Xr;
- Xr = temp;
- }
- temp = Xl;
- Xl = Xr;
- Xr = temp;
- Xr = Xr ^ ctx->P[1];
- Xl = Xl ^ ctx->P[0];
- *xl = Xl;
- *xr = Xr;
- }
- void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
- }
- void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx )
- {
- if( ctx == NULL )
- return;
- blowfish_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
- }
- /*
- * Blowfish key schedule
- */
- int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
- unsigned int keybits )
- {
- unsigned int i, j, k;
- uint32_t data, datal, datar;
- if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS ||
- ( keybits % 8 ) )
- {
- return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH );
- }
- keybits >>= 3;
- for( i = 0; i < 4; i++ )
- {
- for( j = 0; j < 256; j++ )
- ctx->S[i][j] = S[i][j];
- }
- j = 0;
- for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i )
- {
- data = 0x00000000;
- for( k = 0; k < 4; ++k )
- {
- data = ( data << 8 ) | key[j++];
- if( j >= keybits )
- j = 0;
- }
- ctx->P[i] = P[i] ^ data;
- }
- datal = 0x00000000;
- datar = 0x00000000;
- for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 )
- {
- blowfish_enc( ctx, &datal, &datar );
- ctx->P[i] = datal;
- ctx->P[i + 1] = datar;
- }
- for( i = 0; i < 4; i++ )
- {
- for( j = 0; j < 256; j += 2 )
- {
- blowfish_enc( ctx, &datal, &datar );
- ctx->S[i][j] = datal;
- ctx->S[i][j + 1] = datar;
- }
- }
- return( 0 );
- }
- /*
- * Blowfish-ECB block encryption/decryption
- */
- int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
- int mode,
- const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
- unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
- {
- uint32_t X0, X1;
- GET_UINT32_BE( X0, input, 0 );
- GET_UINT32_BE( X1, input, 4 );
- if( mode == MBEDTLS_BLOWFISH_DECRYPT )
- {
- blowfish_dec( ctx, &X0, &X1 );
- }
- else /* MBEDTLS_BLOWFISH_ENCRYPT */
- {
- blowfish_enc( ctx, &X0, &X1 );
- }
- PUT_UINT32_BE( X0, output, 0 );
- PUT_UINT32_BE( X1, output, 4 );
- return( 0 );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * Blowfish-CBC buffer encryption/decryption
- */
- int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
- const unsigned char *input,
- unsigned char *output )
- {
- int i;
- unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
- if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
- return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
- if( mode == MBEDTLS_BLOWFISH_DECRYPT )
- {
- while( length > 0 )
- {
- memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE );
- mbedtls_blowfish_crypt_ecb( ctx, mode, input, output );
- for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
- memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE );
- input += MBEDTLS_BLOWFISH_BLOCKSIZE;
- output += MBEDTLS_BLOWFISH_BLOCKSIZE;
- length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
- }
- }
- else
- {
- while( length > 0 )
- {
- for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
- mbedtls_blowfish_crypt_ecb( ctx, mode, output, output );
- memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE );
- input += MBEDTLS_BLOWFISH_BLOCKSIZE;
- output += MBEDTLS_BLOWFISH_BLOCKSIZE;
- length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
- }
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- /*
- * Blowfish CFB buffer encryption/decryption
- */
- int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
- int mode,
- size_t length,
- size_t *iv_off,
- unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
- const unsigned char *input,
- unsigned char *output )
- {
- int c;
- size_t n = *iv_off;
- if( mode == MBEDTLS_BLOWFISH_DECRYPT )
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
- c = *input++;
- *output++ = (unsigned char)( c ^ iv[n] );
- iv[n] = (unsigned char) c;
- n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
- }
- }
- else
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
- iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
- n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
- }
- }
- *iv_off = n;
- return( 0 );
- }
- #endif /*MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * Blowfish CTR buffer encryption/decryption
- */
- int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
- size_t length,
- size_t *nc_off,
- unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
- unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
- const unsigned char *input,
- unsigned char *output )
- {
- int c, i;
- size_t n = *nc_off;
- while( length-- )
- {
- if( n == 0 ) {
- mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter,
- stream_block );
- for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- )
- if( ++nonce_counter[i - 1] != 0 )
- break;
- }
- c = *input++;
- *output++ = (unsigned char)( c ^ stream_block[n] );
- n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
- }
- *nc_off = n;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- static const uint32_t S[4][256] = {
- { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
- 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
- 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
- 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
- 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
- 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
- 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
- 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
- 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
- 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
- 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
- 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
- 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
- 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
- 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
- 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
- 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
- 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
- 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
- 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
- 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
- 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
- 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
- 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
- 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
- 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
- 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
- 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
- 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
- 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
- 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
- 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
- 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
- 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
- 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
- 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
- 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
- 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
- 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
- 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
- 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
- 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
- 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
- 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
- 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
- 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
- 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
- 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
- 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
- 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
- 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
- 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
- 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
- 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
- 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
- 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
- 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
- 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
- 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
- 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
- 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
- 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
- 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
- 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL },
- { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
- 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
- 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
- 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
- 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
- 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
- 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
- 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
- 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
- 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
- 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
- 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
- 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
- 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
- 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
- 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
- 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
- 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
- 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
- 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
- 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
- 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
- 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
- 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
- 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
- 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
- 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
- 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
- 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
- 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
- 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
- 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
- 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
- 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
- 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
- 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
- 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
- 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
- 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
- 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
- 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
- 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
- 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
- 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
- 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
- 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
- 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
- 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
- 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
- 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
- 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
- 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
- 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
- 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
- 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
- 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
- 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
- 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
- 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
- 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
- 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
- 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
- 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
- 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L },
- { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
- 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
- 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
- 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
- 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
- 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
- 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
- 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
- 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
- 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
- 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
- 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
- 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
- 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
- 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
- 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
- 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
- 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
- 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
- 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
- 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
- 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
- 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
- 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
- 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
- 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
- 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
- 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
- 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
- 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
- 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
- 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
- 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
- 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
- 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
- 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
- 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
- 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
- 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
- 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
- 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
- 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
- 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
- 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
- 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
- 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
- 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
- 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
- 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
- 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
- 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
- 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
- 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
- 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
- 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
- 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
- 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
- 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
- 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
- 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
- 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
- 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
- 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
- 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L },
- { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
- 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
- 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
- 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
- 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
- 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
- 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
- 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
- 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
- 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
- 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
- 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
- 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
- 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
- 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
- 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
- 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
- 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
- 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
- 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
- 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
- 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
- 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
- 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
- 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
- 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
- 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
- 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
- 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
- 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
- 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
- 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
- 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
- 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
- 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
- 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
- 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
- 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
- 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
- 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
- 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
- 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
- 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
- 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
- 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
- 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
- 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
- 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
- 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
- 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
- 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
- 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
- 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
- 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
- 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
- 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
- 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
- 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
- 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
- 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
- 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
- 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
- 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
- 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L }
- };
- #endif /* !MBEDTLS_BLOWFISH_ALT */
- #endif /* MBEDTLS_BLOWFISH_C */
- /********* Start of file library/camellia.c ************/
- /*
- * Camellia implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The Camellia block cipher was designed by NTT and Mitsubishi Electric
- * Corporation.
- *
- * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_CAMELLIA_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #define FSb CAMELLIAFSb
- #if !defined(MBEDTLS_CAMELLIA_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void camellia_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- }
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- }
- #endif
- static const unsigned char SIGMA_CHARS[6][8] =
- {
- { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
- { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
- { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
- { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
- { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
- { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
- };
- #if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
- static const unsigned char FSb[256] =
- {
- 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
- 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
- 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
- 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
- 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
- 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
- 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
- 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
- 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
- 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
- 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
- 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
- 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
- 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
- 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
- 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
- };
- #define SBOX1(n) FSb[(n)]
- #define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
- #define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
- #define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
- #else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
- static const unsigned char FSb[256] =
- {
- 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
- 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
- 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
- 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
- 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
- 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
- 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
- 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
- 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
- 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
- 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
- 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
- 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
- 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
- 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
- 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
- };
- static const unsigned char FSb2[256] =
- {
- 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
- 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
- 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
- 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
- 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
- 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
- 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
- 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
- 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
- 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
- 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
- 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
- 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
- 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
- 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
- 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
- };
- static const unsigned char FSb3[256] =
- {
- 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
- 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
- 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
- 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
- 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
- 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
- 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
- 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
- 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
- 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
- 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
- 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
- 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
- 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
- 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
- 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
- };
- static const unsigned char FSb4[256] =
- {
- 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
- 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
- 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
- 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
- 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
- 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
- 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
- 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
- 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
- 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
- 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
- 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
- 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
- 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
- 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
- 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
- };
- #define SBOX1(n) FSb[(n)]
- #define SBOX2(n) FSb2[(n)]
- #define SBOX3(n) FSb3[(n)]
- #define SBOX4(n) FSb4[(n)]
- #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
- static const unsigned char shifts[2][4][4] =
- {
- {
- { 1, 1, 1, 1 }, /* KL */
- { 0, 0, 0, 0 }, /* KR */
- { 1, 1, 1, 1 }, /* KA */
- { 0, 0, 0, 0 } /* KB */
- },
- {
- { 1, 0, 1, 1 }, /* KL */
- { 1, 1, 0, 1 }, /* KR */
- { 1, 1, 1, 0 }, /* KA */
- { 1, 1, 0, 1 } /* KB */
- }
- };
- static const signed char indexes[2][4][20] =
- {
- {
- { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
- 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
- { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
- 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
- },
- {
- { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
- -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
- { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
- 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
- { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
- 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
- { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
- 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
- }
- };
- static const signed char transposes[2][20] =
- {
- {
- 21, 22, 23, 20,
- -1, -1, -1, -1,
- 18, 19, 16, 17,
- 11, 8, 9, 10,
- 15, 12, 13, 14
- },
- {
- 25, 26, 27, 24,
- 29, 30, 31, 28,
- 18, 19, 16, 17,
- -1, -1, -1, -1,
- -1, -1, -1, -1
- }
- };
- /* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
- #define ROTL(DEST, SRC, SHIFT) \
- { \
- (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
- (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
- (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
- (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
- }
- #define FL(XL, XR, KL, KR) \
- { \
- (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \
- (XL) = ((XR) | (KR)) ^ (XL); \
- }
- #define FLInv(YL, YR, KL, KR) \
- { \
- (YL) = ((YR) | (KR)) ^ (YL); \
- (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \
- }
- #define SHIFT_AND_PLACE(INDEX, OFFSET) \
- { \
- TK[0] = KC[(OFFSET) * 4 + 0]; \
- TK[1] = KC[(OFFSET) * 4 + 1]; \
- TK[2] = KC[(OFFSET) * 4 + 2]; \
- TK[3] = KC[(OFFSET) * 4 + 3]; \
- \
- for( i = 1; i <= 4; i++ ) \
- if( shifts[(INDEX)][(OFFSET)][i -1] ) \
- ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \
- \
- for( i = 0; i < 20; i++ ) \
- if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \
- RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \
- } \
- }
- static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
- uint32_t z[2])
- {
- uint32_t I0, I1;
- I0 = x[0] ^ k[0];
- I1 = x[1] ^ k[1];
- I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
- ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
- ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) |
- ((uint32_t) SBOX4((I0 ) & 0xFF) );
- I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
- ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
- ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) |
- ((uint32_t) SBOX1((I1 ) & 0xFF) );
- I0 ^= (I1 << 8) | (I1 >> 24);
- I1 ^= (I0 << 16) | (I0 >> 16);
- I0 ^= (I1 >> 8) | (I1 << 24);
- I1 ^= (I0 >> 8) | (I0 << 24);
- z[0] ^= I1;
- z[1] ^= I0;
- }
- void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
- }
- void mbedtls_camellia_free( mbedtls_camellia_context *ctx )
- {
- if( ctx == NULL )
- return;
- camellia_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
- }
- /*
- * Camellia key schedule (encryption)
- */
- int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
- unsigned int keybits )
- {
- int idx;
- size_t i;
- uint32_t *RK;
- unsigned char t[64];
- uint32_t SIGMA[6][2];
- uint32_t KC[16];
- uint32_t TK[20];
- RK = ctx->rk;
- memset( t, 0, 64 );
- memset( RK, 0, sizeof(ctx->rk) );
- switch( keybits )
- {
- case 128: ctx->nr = 3; idx = 0; break;
- case 192:
- case 256: ctx->nr = 4; idx = 1; break;
- default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH );
- }
- for( i = 0; i < keybits / 8; ++i )
- t[i] = key[i];
- if( keybits == 192 ) {
- for( i = 0; i < 8; i++ )
- t[24 + i] = ~t[16 + i];
- }
- /*
- * Prepare SIGMA values
- */
- for( i = 0; i < 6; i++ ) {
- GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
- GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
- }
- /*
- * Key storage in KC
- * Order: KL, KR, KA, KB
- */
- memset( KC, 0, sizeof(KC) );
- /* Store KL, KR */
- for( i = 0; i < 8; i++ )
- GET_UINT32_BE( KC[i], t, i * 4 );
- /* Generate KA */
- for( i = 0; i < 4; ++i )
- KC[8 + i] = KC[i] ^ KC[4 + i];
- camellia_feistel( KC + 8, SIGMA[0], KC + 10 );
- camellia_feistel( KC + 10, SIGMA[1], KC + 8 );
- for( i = 0; i < 4; ++i )
- KC[8 + i] ^= KC[i];
- camellia_feistel( KC + 8, SIGMA[2], KC + 10 );
- camellia_feistel( KC + 10, SIGMA[3], KC + 8 );
- if( keybits > 128 ) {
- /* Generate KB */
- for( i = 0; i < 4; ++i )
- KC[12 + i] = KC[4 + i] ^ KC[8 + i];
- camellia_feistel( KC + 12, SIGMA[4], KC + 14 );
- camellia_feistel( KC + 14, SIGMA[5], KC + 12 );
- }
- /*
- * Generating subkeys
- */
- /* Manipulating KL */
- SHIFT_AND_PLACE( idx, 0 );
- /* Manipulating KR */
- if( keybits > 128 ) {
- SHIFT_AND_PLACE( idx, 1 );
- }
- /* Manipulating KA */
- SHIFT_AND_PLACE( idx, 2 );
- /* Manipulating KB */
- if( keybits > 128 ) {
- SHIFT_AND_PLACE( idx, 3 );
- }
- /* Do transpositions */
- for( i = 0; i < 20; i++ ) {
- if( transposes[idx][i] != -1 ) {
- RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
- }
- }
- return( 0 );
- }
- /*
- * Camellia key schedule (decryption)
- */
- int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
- unsigned int keybits )
- {
- int idx, ret;
- size_t i;
- mbedtls_camellia_context cty;
- uint32_t *RK;
- uint32_t *SK;
- mbedtls_camellia_init( &cty );
- /* Also checks keybits */
- if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 )
- goto exit;
- ctx->nr = cty.nr;
- idx = ( ctx->nr == 4 );
- RK = ctx->rk;
- SK = cty.rk + 24 * 2 + 8 * idx * 2;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 )
- {
- *RK++ = *SK++;
- *RK++ = *SK++;
- }
- SK -= 2;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- exit:
- mbedtls_camellia_free( &cty );
- return( ret );
- }
- /*
- * Camellia-ECB block encryption/decryption
- */
- int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- int NR;
- uint32_t *RK, X[4];
- ( (void) mode );
- NR = ctx->nr;
- RK = ctx->rk;
- GET_UINT32_BE( X[0], input, 0 );
- GET_UINT32_BE( X[1], input, 4 );
- GET_UINT32_BE( X[2], input, 8 );
- GET_UINT32_BE( X[3], input, 12 );
- X[0] ^= *RK++;
- X[1] ^= *RK++;
- X[2] ^= *RK++;
- X[3] ^= *RK++;
- while( NR ) {
- --NR;
- camellia_feistel( X, RK, X + 2 );
- RK += 2;
- camellia_feistel( X + 2, RK, X );
- RK += 2;
- camellia_feistel( X, RK, X + 2 );
- RK += 2;
- camellia_feistel( X + 2, RK, X );
- RK += 2;
- camellia_feistel( X, RK, X + 2 );
- RK += 2;
- camellia_feistel( X + 2, RK, X );
- RK += 2;
- if( NR ) {
- FL(X[0], X[1], RK[0], RK[1]);
- RK += 2;
- FLInv(X[2], X[3], RK[0], RK[1]);
- RK += 2;
- }
- }
- X[2] ^= *RK++;
- X[3] ^= *RK++;
- X[0] ^= *RK++;
- X[1] ^= *RK++;
- PUT_UINT32_BE( X[2], output, 0 );
- PUT_UINT32_BE( X[3], output, 4 );
- PUT_UINT32_BE( X[0], output, 8 );
- PUT_UINT32_BE( X[1], output, 12 );
- return( 0 );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * Camellia-CBC buffer encryption/decryption
- */
- int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int i;
- unsigned char temp[16];
- if( length % 16 )
- return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
- if( mode == MBEDTLS_CAMELLIA_DECRYPT )
- {
- while( length > 0 )
- {
- memcpy( temp, input, 16 );
- mbedtls_camellia_crypt_ecb( ctx, mode, input, output );
- for( i = 0; i < 16; i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
- memcpy( iv, temp, 16 );
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- else
- {
- while( length > 0 )
- {
- for( i = 0; i < 16; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
- mbedtls_camellia_crypt_ecb( ctx, mode, output, output );
- memcpy( iv, output, 16 );
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- /*
- * Camellia-CFB128 buffer encryption/decryption
- */
- int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
- int mode,
- size_t length,
- size_t *iv_off,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int c;
- size_t n = *iv_off;
- if( mode == MBEDTLS_CAMELLIA_DECRYPT )
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
- c = *input++;
- *output++ = (unsigned char)( c ^ iv[n] );
- iv[n] = (unsigned char) c;
- n = ( n + 1 ) & 0x0F;
- }
- }
- else
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
- iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
- n = ( n + 1 ) & 0x0F;
- }
- }
- *iv_off = n;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * Camellia-CTR buffer encryption/decryption
- */
- int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
- size_t length,
- size_t *nc_off,
- unsigned char nonce_counter[16],
- unsigned char stream_block[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int c, i;
- size_t n = *nc_off;
- while( length-- )
- {
- if( n == 0 ) {
- mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
- stream_block );
- for( i = 16; i > 0; i-- )
- if( ++nonce_counter[i - 1] != 0 )
- break;
- }
- c = *input++;
- *output++ = (unsigned char)( c ^ stream_block[n] );
- n = ( n + 1 ) & 0x0F;
- }
- *nc_off = n;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #endif /* !MBEDTLS_CAMELLIA_ALT */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Camellia test vectors from:
- *
- * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
- * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
- * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
- * (For each bitlength: Key 0, Nr 39)
- */
- #define CAMELLIA_TESTS_ECB 2
- static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
- {
- {
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
- 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- },
- {
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
- 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- },
- {
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
- 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- },
- };
- static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
- {
- { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
- 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
- { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
- };
- static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
- {
- {
- { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
- 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
- { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
- 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
- },
- {
- { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
- 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
- { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
- 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
- },
- {
- { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
- 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
- { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
- 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
- }
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #define CAMELLIA_TESTS_CBC 3
- static const unsigned char camellia_test_cbc_key[3][32] =
- {
- { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
- 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
- ,
- { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
- 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
- 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
- ,
- { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
- 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
- 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
- 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
- };
- static const unsigned char camellia_test_cbc_iv[16] =
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
- ;
- static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
- {
- { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
- 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
- { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
- 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
- { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
- 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
- };
- static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
- {
- {
- { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
- 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
- { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
- 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
- { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
- 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
- },
- {
- { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
- 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
- { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
- 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
- { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
- 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
- },
- {
- { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
- 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
- { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
- 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
- { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
- 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
- }
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * Camellia-CTR test vectors from:
- *
- * http://www.faqs.org/rfcs/rfc5528.html
- */
- static const unsigned char camellia_test_ctr_key[3][16] =
- {
- { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
- 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
- { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
- 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
- { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
- 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
- };
- static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
- {
- { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
- 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
- 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
- };
- static const unsigned char camellia_test_ctr_pt[3][48] =
- {
- { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
- 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23 }
- };
- static const unsigned char camellia_test_ctr_ct[3][48] =
- {
- { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
- 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
- { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
- 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
- 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
- 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
- { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
- 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
- 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
- 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
- 0xDF, 0x50, 0x86, 0x96 }
- };
- static const int camellia_test_ctr_len[3] =
- { 16, 32, 36 };
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- /*
- * Checkup routine
- */
- int mbedtls_camellia_self_test( int verbose )
- {
- int i, j, u, v;
- unsigned char key[32];
- unsigned char buf[64];
- unsigned char src[16];
- unsigned char dst[16];
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- unsigned char iv[16];
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- size_t offset, len;
- unsigned char nonce_counter[16];
- unsigned char stream_block[16];
- #endif
- mbedtls_camellia_context ctx;
- memset( key, 0, 32 );
- for( j = 0; j < 6; j++ ) {
- u = j >> 1;
- v = j & 1;
- if( verbose != 0 )
- mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
- (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
- for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) {
- memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u );
- if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
- mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
- memcpy( src, camellia_test_ecb_cipher[u][i], 16 );
- memcpy( dst, camellia_test_ecb_plain[i], 16 );
- } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
- mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
- memcpy( src, camellia_test_ecb_plain[i], 16 );
- memcpy( dst, camellia_test_ecb_cipher[u][i], 16 );
- }
- mbedtls_camellia_crypt_ecb( &ctx, v, src, buf );
- if( memcmp( buf, dst, 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * CBC mode
- */
- for( j = 0; j < 6; j++ )
- {
- u = j >> 1;
- v = j & 1;
- if( verbose != 0 )
- mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
- ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
- memcpy( src, camellia_test_cbc_iv, 16 );
- memcpy( dst, camellia_test_cbc_iv, 16 );
- memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
- if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
- mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
- } else {
- mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
- }
- for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
- if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
- memcpy( iv , src, 16 );
- memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
- memcpy( dst, camellia_test_cbc_plain[i], 16 );
- } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
- memcpy( iv , dst, 16 );
- memcpy( src, camellia_test_cbc_plain[i], 16 );
- memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
- }
- mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
- if( memcmp( buf, dst, 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * CTR mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " CAMELLIA-CTR-128 (%s): ",
- ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
- memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 );
- memcpy( key, camellia_test_ctr_key[u], 16 );
- offset = 0;
- mbedtls_camellia_setkey_enc( &ctx, key, 128 );
- if( v == MBEDTLS_CAMELLIA_DECRYPT )
- {
- len = camellia_test_ctr_len[u];
- memcpy( buf, camellia_test_ctr_ct[u], len );
- mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
- buf, buf );
- if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- else
- {
- len = camellia_test_ctr_len[u];
- memcpy( buf, camellia_test_ctr_pt[u], len );
- mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
- buf, buf );
- if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef FSb
- #endif /* MBEDTLS_CAMELLIA_C */
- /********* Start of file library/ccm.c ************/
- /*
- * NIST SP800-38C compliant CCM implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * Definition of CCM:
- * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
- * RFC 3610 "Counter with CBC-MAC (CCM)"
- *
- * Related:
- * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_CCM_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
- /* Implementation that should never be optimized out by the compiler */
- static void ccm_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #define CCM_ENCRYPT 0
- #define CCM_DECRYPT 1
- /*
- * Initialize context
- */
- void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
- }
- int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
- mbedtls_cipher_id_t cipher,
- const unsigned char *key,
- unsigned int keybits )
- {
- int ret;
- const mbedtls_cipher_info_t *cipher_info;
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
- if( cipher_info->block_size != 16 )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
- mbedtls_cipher_free( &ctx->cipher_ctx );
- if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
- MBEDTLS_ENCRYPT ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- /*
- * Free context
- */
- void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
- {
- mbedtls_cipher_free( &ctx->cipher_ctx );
- ccm_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
- }
- /*
- * Macros for common operations.
- * Results in smaller compiled code than static inline functions.
- */
- /*
- * Update the CBC-MAC state in y using a block in b
- * (Always using b as the source helps the compiler optimise a bit better.)
- */
- #define UPDATE_CBC_MAC \
- for( i = 0; i < 16; i++ ) \
- y[i] ^= b[i]; \
- \
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
- return( ret );
- /*
- * Encrypt or decrypt a partial block with CTR
- * Warning: using b for temporary storage! src and dst must not be b!
- * This avoids allocating one more 16 bytes buffer while allowing src == dst.
- */
- #define CTR_CRYPT( dst, src, len ) \
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \
- return( ret ); \
- \
- for( i = 0; i < len; i++ ) \
- dst[i] = src[i] ^ b[i];
- /*
- * Authenticated encryption or decryption
- */
- static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *add, size_t add_len,
- const unsigned char *input, unsigned char *output,
- unsigned char *tag, size_t tag_len )
- {
- int ret;
- unsigned char i;
- unsigned char q;
- size_t len_left, olen;
- unsigned char b[16];
- unsigned char y[16];
- unsigned char ctr[16];
- const unsigned char *src;
- unsigned char *dst;
- /*
- * Check length requirements: SP800-38C A.1
- * Additional requirement: a < 2^16 - 2^8 to simplify the code.
- * 'length' checked later (when writing it to the first block)
- */
- if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
- /* Also implies q is within bounds */
- if( iv_len < 7 || iv_len > 13 )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
- if( add_len > 0xFF00 )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
- q = 16 - 1 - (unsigned char) iv_len;
- /*
- * First block B_0:
- * 0 .. 0 flags
- * 1 .. iv_len nonce (aka iv)
- * iv_len+1 .. 15 length
- *
- * With flags as (bits):
- * 7 0
- * 6 add present?
- * 5 .. 3 (t - 2) / 2
- * 2 .. 0 q - 1
- */
- b[0] = 0;
- b[0] |= ( add_len > 0 ) << 6;
- b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
- b[0] |= q - 1;
- memcpy( b + 1, iv, iv_len );
- for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
- b[15-i] = (unsigned char)( len_left & 0xFF );
- if( len_left > 0 )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
- /* Start CBC-MAC with first block */
- memset( y, 0, 16 );
- UPDATE_CBC_MAC;
- /*
- * If there is additional data, update CBC-MAC with
- * add_len, add, 0 (padding to a block boundary)
- */
- if( add_len > 0 )
- {
- size_t use_len;
- len_left = add_len;
- src = add;
- memset( b, 0, 16 );
- b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
- b[1] = (unsigned char)( ( add_len ) & 0xFF );
- use_len = len_left < 16 - 2 ? len_left : 16 - 2;
- memcpy( b + 2, src, use_len );
- len_left -= use_len;
- src += use_len;
- UPDATE_CBC_MAC;
- while( len_left > 0 )
- {
- use_len = len_left > 16 ? 16 : len_left;
- memset( b, 0, 16 );
- memcpy( b, src, use_len );
- UPDATE_CBC_MAC;
- len_left -= use_len;
- src += use_len;
- }
- }
- /*
- * Prepare counter block for encryption:
- * 0 .. 0 flags
- * 1 .. iv_len nonce (aka iv)
- * iv_len+1 .. 15 counter (initially 1)
- *
- * With flags as (bits):
- * 7 .. 3 0
- * 2 .. 0 q - 1
- */
- ctr[0] = q - 1;
- memcpy( ctr + 1, iv, iv_len );
- memset( ctr + 1 + iv_len, 0, q );
- ctr[15] = 1;
- /*
- * Authenticate and {en,de}crypt the message.
- *
- * The only difference between encryption and decryption is
- * the respective order of authentication and {en,de}cryption.
- */
- len_left = length;
- src = input;
- dst = output;
- while( len_left > 0 )
- {
- size_t use_len = len_left > 16 ? 16 : len_left;
- if( mode == CCM_ENCRYPT )
- {
- memset( b, 0, 16 );
- memcpy( b, src, use_len );
- UPDATE_CBC_MAC;
- }
- CTR_CRYPT( dst, src, use_len );
- if( mode == CCM_DECRYPT )
- {
- memset( b, 0, 16 );
- memcpy( b, dst, use_len );
- UPDATE_CBC_MAC;
- }
- dst += use_len;
- src += use_len;
- len_left -= use_len;
- /*
- * Increment counter.
- * No need to check for overflow thanks to the length check above.
- */
- for( i = 0; i < q; i++ )
- if( ++ctr[15-i] != 0 )
- break;
- }
- /*
- * Authentication: reset counter and crypt/mask internal tag
- */
- for( i = 0; i < q; i++ )
- ctr[15-i] = 0;
- CTR_CRYPT( y, y, 16 );
- memcpy( tag, y, tag_len );
- return( 0 );
- }
- /*
- * Authenticated encryption
- */
- int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *add, size_t add_len,
- const unsigned char *input, unsigned char *output,
- unsigned char *tag, size_t tag_len )
- {
- return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
- add, add_len, input, output, tag, tag_len ) );
- }
- /*
- * Authenticated decryption
- */
- int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *add, size_t add_len,
- const unsigned char *input, unsigned char *output,
- const unsigned char *tag, size_t tag_len )
- {
- int ret;
- unsigned char check_tag[16];
- unsigned char i;
- int diff;
- if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
- iv, iv_len, add, add_len,
- input, output, check_tag, tag_len ) ) != 0 )
- {
- return( ret );
- }
- /* Check tag in "constant-time" */
- for( diff = 0, i = 0; i < tag_len; i++ )
- diff |= tag[i] ^ check_tag[i];
- if( diff != 0 )
- {
- ccm_zeroize( output, length );
- return( MBEDTLS_ERR_CCM_AUTH_FAILED );
- }
- return( 0 );
- }
- #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
- /*
- * Examples 1 to 3 from SP800-38C Appendix C
- */
- #define NB_TESTS 3
- /*
- * The data is the same for all tests, only the used length changes
- */
- static const unsigned char key[] = {
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
- };
- static const unsigned char iv[] = {
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b
- };
- static const unsigned char ad[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13
- };
- static const unsigned char msg[] = {
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- };
- static const size_t iv_len [NB_TESTS] = { 7, 8, 12 };
- static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
- static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
- static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
- static const unsigned char res[NB_TESTS][32] = {
- { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
- { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
- 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
- 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
- { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
- 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
- 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
- 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
- };
- int mbedtls_ccm_self_test( int verbose )
- {
- mbedtls_ccm_context ctx;
- unsigned char out[32];
- size_t i;
- int ret;
- mbedtls_ccm_init( &ctx );
- if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( " CCM: setup failed" );
- return( 1 );
- }
- for( i = 0; i < NB_TESTS; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
- ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
- msg, out,
- out + msg_len[i], tag_len[i] );
- if( ret != 0 ||
- memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
- res[i], out,
- res[i] + msg_len[i], tag_len[i] );
- if( ret != 0 ||
- memcmp( out, msg, msg_len[i] ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- mbedtls_ccm_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
- #endif /* MBEDTLS_CCM_C */
- /********* Start of file library/certs.c ************/
- /*
- * X.509 test certificates
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_CERTS_C)
- #if defined(MBEDTLS_ECDSA_C)
- #define TEST_CA_CRT_EC \
- "-----BEGIN CERTIFICATE-----\r\n" \
- "MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \
- "Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \
- "QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \
- "Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \
- "QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \
- "ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \
- "aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \
- "JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \
- "NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \
- "AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \
- "CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \
- "t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \
- "uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \
- "-----END CERTIFICATE-----\r\n"
- const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC;
- const char mbedtls_test_ca_key_ec[] =
- "-----BEGIN EC PRIVATE KEY-----\r\n"
- "Proc-Type: 4,ENCRYPTED\r\n"
- "DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n"
- "\r\n"
- "IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n"
- "ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n"
- "UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n"
- "a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n"
- "-----END EC PRIVATE KEY-----\r\n";
- const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest";
- const char mbedtls_test_srv_crt_ec[] =
- "-----BEGIN CERTIFICATE-----\r\n"
- "MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n"
- "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n"
- "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n"
- "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n"
- "CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n"
- "2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n"
- "BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n"
- "PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n"
- "clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n"
- "CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n"
- "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n"
- "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n"
- "-----END CERTIFICATE-----\r\n";
- const char mbedtls_test_srv_key_ec[] =
- "-----BEGIN EC PRIVATE KEY-----\r\n"
- "MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n"
- "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n"
- "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n"
- "-----END EC PRIVATE KEY-----\r\n";
- const char mbedtls_test_cli_crt_ec[] =
- "-----BEGIN CERTIFICATE-----\r\n"
- "MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n"
- "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n"
- "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n"
- "A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n"
- "WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n"
- "9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n"
- "MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n"
- "IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n"
- "MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n"
- "CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n"
- "lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n"
- "LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n"
- "-----END CERTIFICATE-----\r\n";
- const char mbedtls_test_cli_key_ec[] =
- "-----BEGIN EC PRIVATE KEY-----\r\n"
- "MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n"
- "AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n"
- "wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n"
- "-----END EC PRIVATE KEY-----\r\n";
- const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec );
- const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec );
- const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1;
- const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec );
- const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec );
- const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec );
- const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec );
- #else
- #define TEST_CA_CRT_EC
- #endif /* MBEDTLS_ECDSA_C */
- #if defined(MBEDTLS_RSA_C)
- #define TEST_CA_CRT_RSA \
- "-----BEGIN CERTIFICATE-----\r\n" \
- "MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
- "MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
- "MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \
- "A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \
- "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \
- "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \
- "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \
- "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \
- "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \
- "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \
- "gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n" \
- "/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n" \
- "BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n" \
- "dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n" \
- "SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n" \
- "DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n" \
- "pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n" \
- "m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \
- "7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \
- "-----END CERTIFICATE-----\r\n"
- const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA;
- const char mbedtls_test_ca_key_rsa[] =
- "-----BEGIN RSA PRIVATE KEY-----\r\n"
- "Proc-Type: 4,ENCRYPTED\r\n"
- "DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n"
- "\r\n"
- "9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n"
- "7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n"
- "Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n"
- "PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n"
- "GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n"
- "gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n"
- "QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n"
- "PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n"
- "vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n"
- "WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n"
- "JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n"
- "KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n"
- "Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n"
- "9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n"
- "iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n"
- "tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n"
- "P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n"
- "1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n"
- "nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n"
- "X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n"
- "rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n"
- "L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n"
- "I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n"
- "wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n"
- "P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n"
- "-----END RSA PRIVATE KEY-----\r\n";
- const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest";
- const char mbedtls_test_srv_crt_rsa[] =
- "-----BEGIN CERTIFICATE-----\r\n"
- "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
- "MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
- "MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n"
- "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n"
- "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n"
- "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n"
- "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n"
- "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n"
- "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n"
- "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n"
- "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n"
- "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJxnXClY\r\n"
- "oHkbp70cqBrsGXLybA74czbO5RdLEgFs7rHVS9r+c293luS/KdliLScZqAzYVylw\r\n"
- "UfRWvKMoWhHYKp3dEIS4xTXk6/5zXxhv9Rw8SGc8qn6vITHk1S1mPevtekgasY5Y\r\n"
- "iWQuM3h4YVlRH3HHEMAD1TnAexfXHHDFQGe+Bd1iAbz1/sH9H8l4StwX6egvTK3M\r\n"
- "wXRwkKkvjKaEDA9ATbZx0mI8LGsxSuCqe9r9dyjmttd47J1p1Rulz3CLzaRcVIuS\r\n"
- "RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n"
- "zhuYwjVuX6JHG0c=\r\n"
- "-----END CERTIFICATE-----\r\n";
- const char mbedtls_test_srv_key_rsa[] =
- "-----BEGIN RSA PRIVATE KEY-----\r\n"
- "MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n"
- "lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n"
- "2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n"
- "Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n"
- "GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n"
- "y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n"
- "++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n"
- "Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n"
- "/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n"
- "WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n"
- "GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n"
- "TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n"
- "CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n"
- "nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n"
- "AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n"
- "sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n"
- "mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n"
- "BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n"
- "whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n"
- "vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n"
- "3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n"
- "3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n"
- "ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n"
- "4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n"
- "TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n"
- "-----END RSA PRIVATE KEY-----\r\n";
- const char mbedtls_test_cli_crt_rsa[] =
- "-----BEGIN CERTIFICATE-----\r\n"
- "MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
- "MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
- "MTEwMjEyMTQ0NDA3WhcNMjEwMjEyMTQ0NDA3WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
- "A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n"
- "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n"
- "M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n"
- "1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n"
- "MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n"
- "4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n"
- "/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n"
- "o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n"
- "BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n"
- "AQEAAn86isAM8X+mVwJqeItt6E9slhEQbAofyk+diH1Lh8Y9iLlWQSKbw/UXYjx5\r\n"
- "LLPZcniovxIcARC/BjyZR9g3UwTHNGNm+rwrqa15viuNOFBchykX/Orsk02EH7NR\r\n"
- "Alw5WLPorYjED6cdVQgBl9ot93HdJogRiXCxErM7NC8/eP511mjq+uLDjLKH8ZPQ\r\n"
- "8I4ekHJnroLsDkIwXKGIsvIBHQy2ac/NwHLCQOK6mfum1pRx52V4Utu5dLLjD5bM\r\n"
- "xOBC7KU4xZKuMXXZM6/93Yb51K/J4ahf1TxJlTWXtnzDr9saEYdNy2SKY/6ZiDNH\r\n"
- "D+stpAKiQLAWaAusIWKYEyw9MQ==\r\n"
- "-----END CERTIFICATE-----\r\n";
- const char mbedtls_test_cli_key_rsa[] =
- "-----BEGIN RSA PRIVATE KEY-----\r\n"
- "MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n"
- "B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n"
- "bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n"
- "Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n"
- "7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n"
- "dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n"
- "yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n"
- "4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n"
- "ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n"
- "zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n"
- "l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n"
- "DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n"
- "VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n"
- "Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n"
- "wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n"
- "c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n"
- "33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n"
- "ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n"
- "BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n"
- "KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n"
- "UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n"
- "7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n"
- "gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n"
- "bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n"
- "8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n"
- "-----END RSA PRIVATE KEY-----\r\n";
- const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa );
- const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa );
- const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1;
- const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa );
- const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa );
- const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa );
- const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa );
- #else
- #define TEST_CA_CRT_RSA
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_PEM_PARSE_C)
- /* Concatenation of all available CA certificates */
- const char mbedtls_test_cas_pem[] = TEST_CA_CRT_RSA TEST_CA_CRT_EC;
- const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem );
- #endif
- /* List of all available CA certificates */
- const char * mbedtls_test_cas[] = {
- #if defined(MBEDTLS_RSA_C)
- mbedtls_test_ca_crt_rsa,
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- mbedtls_test_ca_crt_ec,
- #endif
- NULL
- };
- const size_t mbedtls_test_cas_len[] = {
- #if defined(MBEDTLS_RSA_C)
- sizeof( mbedtls_test_ca_crt_rsa ),
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- sizeof( mbedtls_test_ca_crt_ec ),
- #endif
- 0
- };
- #if defined(MBEDTLS_RSA_C)
- const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa;
- const char *mbedtls_test_ca_key = mbedtls_test_ca_key_rsa;
- const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_rsa;
- const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa;
- const char *mbedtls_test_srv_key = mbedtls_test_srv_key_rsa;
- const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_rsa;
- const char *mbedtls_test_cli_key = mbedtls_test_cli_key_rsa;
- const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_rsa );
- const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_rsa );
- const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1;
- const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_rsa );
- const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_rsa );
- const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_rsa );
- const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_rsa );
- #else /* ! MBEDTLS_RSA_C, so MBEDTLS_ECDSA_C */
- const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_ec;
- const char *mbedtls_test_ca_key = mbedtls_test_ca_key_ec;
- const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_ec;
- const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_ec;
- const char *mbedtls_test_srv_key = mbedtls_test_srv_key_ec;
- const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_ec;
- const char *mbedtls_test_cli_key = mbedtls_test_cli_key_ec;
- const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_ec );
- const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_ec );
- const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1;
- const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_ec );
- const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_ec );
- const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_ec );
- const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec );
- #endif /* MBEDTLS_RSA_C */
- #endif /* MBEDTLS_CERTS_C */
- /********* Start of file library/cipher.c ************/
- /**
- * \file cipher.c
- *
- * \brief Generic cipher wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_CIPHER_C)
- #include <stdlib.h>
- #include <string.h>
- #if defined(MBEDTLS_GCM_C)
- #endif
- #if defined(MBEDTLS_CCM_C)
- #endif
- #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #define MBEDTLS_CIPHER_MODE_STREAM
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void cipher_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /* Amalgamated Release Mappings */
- #define supported_init cipher_supported_init
- static int supported_init = 0;
- const int *mbedtls_cipher_list( void )
- {
- const mbedtls_cipher_definition_t *def;
- int *type;
- if( ! supported_init )
- {
- def = mbedtls_cipher_definitions;
- type = mbedtls_cipher_supported;
- while( def->type != 0 )
- *type++ = (*def++).type;
- *type = 0;
- supported_init = 1;
- }
- return( mbedtls_cipher_supported );
- }
- const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
- {
- const mbedtls_cipher_definition_t *def;
- for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
- if( def->type == cipher_type )
- return( def->info );
- return( NULL );
- }
- const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
- {
- const mbedtls_cipher_definition_t *def;
- if( NULL == cipher_name )
- return( NULL );
- for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
- if( ! strcmp( def->info->name, cipher_name ) )
- return( def->info );
- return( NULL );
- }
- const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
- int key_bitlen,
- const mbedtls_cipher_mode_t mode )
- {
- const mbedtls_cipher_definition_t *def;
- for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
- if( def->info->base->cipher == cipher_id &&
- def->info->key_bitlen == (unsigned) key_bitlen &&
- def->info->mode == mode )
- return( def->info );
- return( NULL );
- }
- void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
- }
- void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
- {
- if( ctx == NULL )
- return;
- if( ctx->cipher_ctx )
- ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
- cipher_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
- }
- int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
- {
- if( NULL == cipher_info || NULL == ctx )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
- if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
- return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
- ctx->cipher_info = cipher_info;
- #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- /*
- * Ignore possible errors caused by a cipher mode that doesn't use padding
- */
- #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
- #else
- (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
- #endif
- #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
- return( 0 );
- }
- int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
- int key_bitlen, const mbedtls_operation_t operation )
- {
- if( NULL == ctx || NULL == ctx->cipher_info )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
- (int) ctx->cipher_info->key_bitlen != key_bitlen )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- ctx->key_bitlen = key_bitlen;
- ctx->operation = operation;
- /*
- * For CFB and CTR mode always use the encryption key schedule
- */
- if( MBEDTLS_ENCRYPT == operation ||
- MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
- MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
- {
- return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
- ctx->key_bitlen );
- }
- if( MBEDTLS_DECRYPT == operation )
- return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
- ctx->key_bitlen );
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len )
- {
- size_t actual_iv_size;
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- /* avoid buffer overflow in ctx->iv */
- if( iv_len > MBEDTLS_MAX_IV_LENGTH )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
- actual_iv_size = iv_len;
- else
- {
- actual_iv_size = ctx->cipher_info->iv_size;
- /* avoid reading past the end of input buffer */
- if( actual_iv_size > iv_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- memcpy( ctx->iv, iv, actual_iv_size );
- ctx->iv_size = actual_iv_size;
- return( 0 );
- }
- int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
- {
- if( NULL == ctx || NULL == ctx->cipher_info )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- ctx->unprocessed_len = 0;
- return( 0 );
- }
- #if defined(MBEDTLS_GCM_C)
- int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
- const unsigned char *ad, size_t ad_len )
- {
- if( NULL == ctx || NULL == ctx->cipher_info )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
- ctx->iv, ctx->iv_size, ad, ad_len );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_GCM_C */
- int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
- size_t ilen, unsigned char *output, size_t *olen )
- {
- int ret;
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- *olen = 0;
- if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
- {
- if( ilen != mbedtls_cipher_get_block_size( ctx ) )
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
- *olen = ilen;
- if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
- ctx->operation, input, output ) ) )
- {
- return( ret );
- }
- return( 0 );
- }
- #if defined(MBEDTLS_GCM_C)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
- {
- *olen = ilen;
- return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
- output );
- }
- #endif
- if( input == output &&
- ( ctx->unprocessed_len != 0 || ilen % mbedtls_cipher_get_block_size( ctx ) ) )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
- {
- size_t copy_len = 0;
- /*
- * If there is not enough data for a full block, cache it.
- */
- if( ( ctx->operation == MBEDTLS_DECRYPT &&
- ilen + ctx->unprocessed_len <= mbedtls_cipher_get_block_size( ctx ) ) ||
- ( ctx->operation == MBEDTLS_ENCRYPT &&
- ilen + ctx->unprocessed_len < mbedtls_cipher_get_block_size( ctx ) ) )
- {
- memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
- ilen );
- ctx->unprocessed_len += ilen;
- return( 0 );
- }
- /*
- * Process cached data first
- */
- if( ctx->unprocessed_len != 0 )
- {
- copy_len = mbedtls_cipher_get_block_size( ctx ) - ctx->unprocessed_len;
- memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
- copy_len );
- if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
- ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
- ctx->unprocessed_data, output ) ) )
- {
- return( ret );
- }
- *olen += mbedtls_cipher_get_block_size( ctx );
- output += mbedtls_cipher_get_block_size( ctx );
- ctx->unprocessed_len = 0;
- input += copy_len;
- ilen -= copy_len;
- }
- /*
- * Cache final, incomplete block
- */
- if( 0 != ilen )
- {
- copy_len = ilen % mbedtls_cipher_get_block_size( ctx );
- if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT )
- copy_len = mbedtls_cipher_get_block_size( ctx );
- memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
- copy_len );
- ctx->unprocessed_len += copy_len;
- ilen -= copy_len;
- }
- /*
- * Process remaining full blocks
- */
- if( ilen )
- {
- if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
- ctx->operation, ilen, ctx->iv, input, output ) ) )
- {
- return( ret );
- }
- *olen += ilen;
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
- {
- if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
- ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
- input, output ) ) )
- {
- return( ret );
- }
- *olen = ilen;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
- {
- if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
- ilen, &ctx->unprocessed_len, ctx->iv,
- ctx->unprocessed_data, input, output ) ) )
- {
- return( ret );
- }
- *olen = ilen;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
- {
- if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
- ilen, input, output ) ) )
- {
- return( ret );
- }
- *olen = ilen;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_STREAM */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
- #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- /*
- * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
- */
- static void add_pkcs_padding( unsigned char *output, size_t output_len,
- size_t data_len )
- {
- size_t padding_len = output_len - data_len;
- unsigned char i;
- for( i = 0; i < padding_len; i++ )
- output[data_len + i] = (unsigned char) padding_len;
- }
- static int get_pkcs_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
- {
- size_t i, pad_idx;
- unsigned char padding_len, bad = 0;
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- padding_len = input[input_len - 1];
- *data_len = input_len - padding_len;
- /* Avoid logical || since it results in a branch */
- bad |= padding_len > input_len;
- bad |= padding_len == 0;
- /* The number of bytes checked must be independent of padding_len,
- * so pick input_len, which is usually 8 or 16 (one block) */
- pad_idx = input_len - padding_len;
- for( i = 0; i < input_len; i++ )
- bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
- return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
- }
- #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
- #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
- /*
- * One and zeros padding: fill with 80 00 ... 00
- */
- static void add_one_and_zeros_padding( unsigned char *output,
- size_t output_len, size_t data_len )
- {
- size_t padding_len = output_len - data_len;
- unsigned char i = 0;
- output[data_len] = 0x80;
- for( i = 1; i < padding_len; i++ )
- output[data_len + i] = 0x00;
- }
- static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
- {
- size_t i;
- unsigned char done = 0, prev_done, bad;
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- bad = 0xFF;
- *data_len = 0;
- for( i = input_len; i > 0; i-- )
- {
- prev_done = done;
- done |= ( input[i-1] != 0 );
- *data_len |= ( i - 1 ) * ( done != prev_done );
- bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done );
- }
- return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
- }
- #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
- #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
- /*
- * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
- */
- static void add_zeros_and_len_padding( unsigned char *output,
- size_t output_len, size_t data_len )
- {
- size_t padding_len = output_len - data_len;
- unsigned char i = 0;
- for( i = 1; i < padding_len; i++ )
- output[data_len + i - 1] = 0x00;
- output[output_len - 1] = (unsigned char) padding_len;
- }
- static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
- {
- size_t i, pad_idx;
- unsigned char padding_len, bad = 0;
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- padding_len = input[input_len - 1];
- *data_len = input_len - padding_len;
- /* Avoid logical || since it results in a branch */
- bad |= padding_len > input_len;
- bad |= padding_len == 0;
- /* The number of bytes checked must be independent of padding_len */
- pad_idx = input_len - padding_len;
- for( i = 0; i < input_len - 1; i++ )
- bad |= input[i] * ( i >= pad_idx );
- return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
- }
- #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
- #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
- /*
- * Zero padding: fill with 00 ... 00
- */
- static void add_zeros_padding( unsigned char *output,
- size_t output_len, size_t data_len )
- {
- size_t i;
- for( i = data_len; i < output_len; i++ )
- output[i] = 0x00;
- }
- static int get_zeros_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
- {
- size_t i;
- unsigned char done = 0, prev_done;
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- *data_len = 0;
- for( i = input_len; i > 0; i-- )
- {
- prev_done = done;
- done |= ( input[i-1] != 0 );
- *data_len |= i * ( done != prev_done );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
- /*
- * No padding: don't pad :)
- *
- * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
- * but a trivial get_padding function
- */
- static int get_no_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
- {
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- *data_len = input_len;
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
- int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
- unsigned char *output, size_t *olen )
- {
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- *olen = 0;
- if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
- MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
- MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
- MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
- {
- return( 0 );
- }
- if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
- {
- if( ctx->unprocessed_len != 0 )
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
- return( 0 );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
- {
- int ret = 0;
- if( MBEDTLS_ENCRYPT == ctx->operation )
- {
- /* check for 'no padding' mode */
- if( NULL == ctx->add_padding )
- {
- if( 0 != ctx->unprocessed_len )
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
- return( 0 );
- }
- ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
- ctx->unprocessed_len );
- }
- else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
- {
- /*
- * For decrypt operations, expect a full block,
- * or an empty block if no padding
- */
- if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
- return( 0 );
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
- }
- /* cipher block */
- if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
- ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
- ctx->unprocessed_data, output ) ) )
- {
- return( ret );
- }
- /* Set output size for decryption */
- if( MBEDTLS_DECRYPT == ctx->operation )
- return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
- olen );
- /* Set output size for encryption */
- *olen = mbedtls_cipher_get_block_size( ctx );
- return( 0 );
- }
- #else
- ((void) output);
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
- #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode )
- {
- if( NULL == ctx ||
- MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- switch( mode )
- {
- #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- case MBEDTLS_PADDING_PKCS7:
- ctx->add_padding = add_pkcs_padding;
- ctx->get_padding = get_pkcs_padding;
- break;
- #endif
- #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
- case MBEDTLS_PADDING_ONE_AND_ZEROS:
- ctx->add_padding = add_one_and_zeros_padding;
- ctx->get_padding = get_one_and_zeros_padding;
- break;
- #endif
- #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
- case MBEDTLS_PADDING_ZEROS_AND_LEN:
- ctx->add_padding = add_zeros_and_len_padding;
- ctx->get_padding = get_zeros_and_len_padding;
- break;
- #endif
- #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
- case MBEDTLS_PADDING_ZEROS:
- ctx->add_padding = add_zeros_padding;
- ctx->get_padding = get_zeros_padding;
- break;
- #endif
- case MBEDTLS_PADDING_NONE:
- ctx->add_padding = NULL;
- ctx->get_padding = get_no_padding;
- break;
- default:
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
- #if defined(MBEDTLS_GCM_C)
- int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
- unsigned char *tag, size_t tag_len )
- {
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( MBEDTLS_ENCRYPT != ctx->operation )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
- return( 0 );
- }
- int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
- const unsigned char *tag, size_t tag_len )
- {
- int ret;
- if( NULL == ctx || NULL == ctx->cipher_info ||
- MBEDTLS_DECRYPT != ctx->operation )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- unsigned char check_tag[16];
- size_t i;
- int diff;
- if( tag_len > sizeof( check_tag ) )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
- check_tag, tag_len ) ) )
- {
- return( ret );
- }
- /* Check the tag in "constant-time" */
- for( diff = 0, i = 0; i < tag_len; i++ )
- diff |= tag[i] ^ check_tag[i];
- if( diff != 0 )
- return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
- return( 0 );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_GCM_C */
- /*
- * Packet-oriented wrapper for non-AEAD modes
- */
- int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen )
- {
- int ret;
- size_t finish_olen;
- if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
- return( ret );
- *olen += finish_olen;
- return( 0 );
- }
- #if defined(MBEDTLS_CIPHER_MODE_AEAD)
- /*
- * Packet-oriented encryption for AEAD modes
- */
- int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *ad, size_t ad_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen,
- unsigned char *tag, size_t tag_len )
- {
- #if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- *olen = ilen;
- return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
- iv, iv_len, ad, ad_len, input, output,
- tag_len, tag ) );
- }
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CCM_C)
- if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
- {
- *olen = ilen;
- return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
- iv, iv_len, ad, ad_len, input, output,
- tag, tag_len ) );
- }
- #endif /* MBEDTLS_CCM_C */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
- /*
- * Packet-oriented decryption for AEAD modes
- */
- int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *ad, size_t ad_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen,
- const unsigned char *tag, size_t tag_len )
- {
- #if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- int ret;
- *olen = ilen;
- ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
- iv, iv_len, ad, ad_len,
- tag, tag_len, input, output );
- if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
- ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
- return( ret );
- }
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CCM_C)
- if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
- {
- int ret;
- *olen = ilen;
- ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
- iv, iv_len, ad, ad_len,
- input, output, tag, tag_len );
- if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
- ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
- return( ret );
- }
- #endif /* MBEDTLS_CCM_C */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
- #endif /* MBEDTLS_CIPHER_MODE_AEAD */
- /* Amalgamated Release Mappings */
- #undef supported_init
- #endif /* MBEDTLS_CIPHER_C */
- /********* Start of file library/cipher_wrap.c ************/
- /**
- * \file cipher_wrap.c
- *
- * \brief Generic cipher wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_CIPHER_C)
- #if defined(MBEDTLS_AES_C)
- #endif
- #if defined(MBEDTLS_ARC4_C)
- #endif
- #if defined(MBEDTLS_CAMELLIA_C)
- #endif
- #if defined(MBEDTLS_DES_C)
- #endif
- #if defined(MBEDTLS_BLOWFISH_C)
- #endif
- #if defined(MBEDTLS_GCM_C)
- #endif
- #if defined(MBEDTLS_CCM_C)
- #endif
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #include <string.h>
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if defined(MBEDTLS_GCM_C)
- /* shared by all GCM ciphers */
- static void *gcm_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) );
- if( ctx != NULL )
- mbedtls_gcm_init( (mbedtls_gcm_context *) ctx );
- return( ctx );
- }
- static void gcm_ctx_free( void *ctx )
- {
- mbedtls_gcm_free( ctx );
- mbedtls_free( ctx );
- }
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CCM_C)
- /* shared by all CCM ciphers */
- static void *ccm_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) );
- if( ctx != NULL )
- mbedtls_ccm_init( (mbedtls_ccm_context *) ctx );
- return( ctx );
- }
- static void ccm_ctx_free( void *ctx )
- {
- mbedtls_ccm_free( ctx );
- mbedtls_free( ctx );
- }
- #endif /* MBEDTLS_CCM_C */
- #if defined(MBEDTLS_AES_C)
- static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
- {
- return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input,
- output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv,
- input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter,
- stream_block, input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen );
- }
- static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen );
- }
- static void * aes_ctx_alloc( void )
- {
- mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) );
- if( aes == NULL )
- return( NULL );
- mbedtls_aes_init( aes );
- return( aes );
- }
- static void aes_ctx_free( void *ctx )
- {
- mbedtls_aes_free( (mbedtls_aes_context *) ctx );
- mbedtls_free( ctx );
- }
- static const mbedtls_cipher_base_t aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- aes_crypt_ecb_wrap,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- aes_crypt_cbc_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- aes_crypt_cfb128_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- aes_crypt_ctr_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- aes_setkey_enc_wrap,
- aes_setkey_dec_wrap,
- aes_ctx_alloc,
- aes_ctx_free
- };
- static const mbedtls_cipher_info_t aes_128_ecb_info = {
- MBEDTLS_CIPHER_AES_128_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "AES-128-ECB",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_192_ecb_info = {
- MBEDTLS_CIPHER_AES_192_ECB,
- MBEDTLS_MODE_ECB,
- 192,
- "AES-192-ECB",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_256_ecb_info = {
- MBEDTLS_CIPHER_AES_256_ECB,
- MBEDTLS_MODE_ECB,
- 256,
- "AES-256-ECB",
- 16,
- 0,
- 16,
- &aes_info
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const mbedtls_cipher_info_t aes_128_cbc_info = {
- MBEDTLS_CIPHER_AES_128_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "AES-128-CBC",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_192_cbc_info = {
- MBEDTLS_CIPHER_AES_192_CBC,
- MBEDTLS_MODE_CBC,
- 192,
- "AES-192-CBC",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_256_cbc_info = {
- MBEDTLS_CIPHER_AES_256_CBC,
- MBEDTLS_MODE_CBC,
- 256,
- "AES-256-CBC",
- 16,
- 0,
- 16,
- &aes_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- static const mbedtls_cipher_info_t aes_128_cfb128_info = {
- MBEDTLS_CIPHER_AES_128_CFB128,
- MBEDTLS_MODE_CFB,
- 128,
- "AES-128-CFB128",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_192_cfb128_info = {
- MBEDTLS_CIPHER_AES_192_CFB128,
- MBEDTLS_MODE_CFB,
- 192,
- "AES-192-CFB128",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_256_cfb128_info = {
- MBEDTLS_CIPHER_AES_256_CFB128,
- MBEDTLS_MODE_CFB,
- 256,
- "AES-256-CFB128",
- 16,
- 0,
- 16,
- &aes_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- static const mbedtls_cipher_info_t aes_128_ctr_info = {
- MBEDTLS_CIPHER_AES_128_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "AES-128-CTR",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_192_ctr_info = {
- MBEDTLS_CIPHER_AES_192_CTR,
- MBEDTLS_MODE_CTR,
- 192,
- "AES-192-CTR",
- 16,
- 0,
- 16,
- &aes_info
- };
- static const mbedtls_cipher_info_t aes_256_ctr_info = {
- MBEDTLS_CIPHER_AES_256_CTR,
- MBEDTLS_MODE_CTR,
- 256,
- "AES-256-CTR",
- 16,
- 0,
- 16,
- &aes_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #if defined(MBEDTLS_GCM_C)
- static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
- key, key_bitlen );
- }
- static const mbedtls_cipher_base_t gcm_aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- NULL,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- gcm_aes_setkey_wrap,
- gcm_aes_setkey_wrap,
- gcm_ctx_alloc,
- gcm_ctx_free,
- };
- static const mbedtls_cipher_info_t aes_128_gcm_info = {
- MBEDTLS_CIPHER_AES_128_GCM,
- MBEDTLS_MODE_GCM,
- 128,
- "AES-128-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aes_info
- };
- static const mbedtls_cipher_info_t aes_192_gcm_info = {
- MBEDTLS_CIPHER_AES_192_GCM,
- MBEDTLS_MODE_GCM,
- 192,
- "AES-192-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aes_info
- };
- static const mbedtls_cipher_info_t aes_256_gcm_info = {
- MBEDTLS_CIPHER_AES_256_GCM,
- MBEDTLS_MODE_GCM,
- 256,
- "AES-256-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aes_info
- };
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CCM_C)
- static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
- key, key_bitlen );
- }
- static const mbedtls_cipher_base_t ccm_aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- NULL,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- ccm_aes_setkey_wrap,
- ccm_aes_setkey_wrap,
- ccm_ctx_alloc,
- ccm_ctx_free,
- };
- static const mbedtls_cipher_info_t aes_128_ccm_info = {
- MBEDTLS_CIPHER_AES_128_CCM,
- MBEDTLS_MODE_CCM,
- 128,
- "AES-128-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aes_info
- };
- static const mbedtls_cipher_info_t aes_192_ccm_info = {
- MBEDTLS_CIPHER_AES_192_CCM,
- MBEDTLS_MODE_CCM,
- 192,
- "AES-192-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aes_info
- };
- static const mbedtls_cipher_info_t aes_256_ccm_info = {
- MBEDTLS_CIPHER_AES_256_CCM,
- MBEDTLS_MODE_CCM,
- 256,
- "AES-256-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aes_info
- };
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input,
- output );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv,
- input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length,
- iv_off, iv, input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off,
- nonce_counter, stream_block, input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen );
- }
- static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen );
- }
- static void * camellia_ctx_alloc( void )
- {
- mbedtls_camellia_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) );
- if( ctx == NULL )
- return( NULL );
- mbedtls_camellia_init( ctx );
- return( ctx );
- }
- static void camellia_ctx_free( void *ctx )
- {
- mbedtls_camellia_free( (mbedtls_camellia_context *) ctx );
- mbedtls_free( ctx );
- }
- static const mbedtls_cipher_base_t camellia_info = {
- MBEDTLS_CIPHER_ID_CAMELLIA,
- camellia_crypt_ecb_wrap,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- camellia_crypt_cbc_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- camellia_crypt_cfb128_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- camellia_crypt_ctr_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- camellia_setkey_enc_wrap,
- camellia_setkey_dec_wrap,
- camellia_ctx_alloc,
- camellia_ctx_free
- };
- static const mbedtls_cipher_info_t camellia_128_ecb_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "CAMELLIA-128-ECB",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_192_ecb_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_ECB,
- MBEDTLS_MODE_ECB,
- 192,
- "CAMELLIA-192-ECB",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_256_ecb_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_ECB,
- MBEDTLS_MODE_ECB,
- 256,
- "CAMELLIA-256-ECB",
- 16,
- 0,
- 16,
- &camellia_info
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const mbedtls_cipher_info_t camellia_128_cbc_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "CAMELLIA-128-CBC",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_192_cbc_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CBC,
- MBEDTLS_MODE_CBC,
- 192,
- "CAMELLIA-192-CBC",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_256_cbc_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CBC,
- MBEDTLS_MODE_CBC,
- 256,
- "CAMELLIA-256-CBC",
- 16,
- 0,
- 16,
- &camellia_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- static const mbedtls_cipher_info_t camellia_128_cfb128_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
- MBEDTLS_MODE_CFB,
- 128,
- "CAMELLIA-128-CFB128",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_192_cfb128_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
- MBEDTLS_MODE_CFB,
- 192,
- "CAMELLIA-192-CFB128",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_256_cfb128_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
- MBEDTLS_MODE_CFB,
- 256,
- "CAMELLIA-256-CFB128",
- 16,
- 0,
- 16,
- &camellia_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- static const mbedtls_cipher_info_t camellia_128_ctr_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "CAMELLIA-128-CTR",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_192_ctr_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CTR,
- MBEDTLS_MODE_CTR,
- 192,
- "CAMELLIA-192-CTR",
- 16,
- 0,
- 16,
- &camellia_info
- };
- static const mbedtls_cipher_info_t camellia_256_ctr_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CTR,
- MBEDTLS_MODE_CTR,
- 256,
- "CAMELLIA-256-CTR",
- 16,
- 0,
- 16,
- &camellia_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #if defined(MBEDTLS_GCM_C)
- static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
- key, key_bitlen );
- }
- static const mbedtls_cipher_base_t gcm_camellia_info = {
- MBEDTLS_CIPHER_ID_CAMELLIA,
- NULL,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- gcm_camellia_setkey_wrap,
- gcm_camellia_setkey_wrap,
- gcm_ctx_alloc,
- gcm_ctx_free,
- };
- static const mbedtls_cipher_info_t camellia_128_gcm_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_GCM,
- MBEDTLS_MODE_GCM,
- 128,
- "CAMELLIA-128-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_camellia_info
- };
- static const mbedtls_cipher_info_t camellia_192_gcm_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_GCM,
- MBEDTLS_MODE_GCM,
- 192,
- "CAMELLIA-192-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_camellia_info
- };
- static const mbedtls_cipher_info_t camellia_256_gcm_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_GCM,
- MBEDTLS_MODE_GCM,
- 256,
- "CAMELLIA-256-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_camellia_info
- };
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CCM_C)
- static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
- key, key_bitlen );
- }
- static const mbedtls_cipher_base_t ccm_camellia_info = {
- MBEDTLS_CIPHER_ID_CAMELLIA,
- NULL,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- ccm_camellia_setkey_wrap,
- ccm_camellia_setkey_wrap,
- ccm_ctx_alloc,
- ccm_ctx_free,
- };
- static const mbedtls_cipher_info_t camellia_128_ccm_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CCM,
- MBEDTLS_MODE_CCM,
- 128,
- "CAMELLIA-128-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_camellia_info
- };
- static const mbedtls_cipher_info_t camellia_192_ccm_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CCM,
- MBEDTLS_MODE_CCM,
- 192,
- "CAMELLIA-192-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_camellia_info
- };
- static const mbedtls_cipher_info_t camellia_256_ccm_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CCM,
- MBEDTLS_MODE_CCM,
- 256,
- "CAMELLIA-256-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_camellia_info
- };
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
- {
- ((void) operation);
- return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output );
- }
- static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
- {
- ((void) operation);
- return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
- {
- return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input,
- output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
- {
- return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input,
- output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- static int des_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) key_bitlen);
- return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key );
- }
- static int des_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) key_bitlen);
- return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key );
- }
- static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) key_bitlen);
- return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key );
- }
- static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) key_bitlen);
- return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key );
- }
- static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) key_bitlen);
- return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key );
- }
- static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) key_bitlen);
- return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key );
- }
- static void * des_ctx_alloc( void )
- {
- mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) );
- if( des == NULL )
- return( NULL );
- mbedtls_des_init( des );
- return( des );
- }
- static void des_ctx_free( void *ctx )
- {
- mbedtls_des_free( (mbedtls_des_context *) ctx );
- mbedtls_free( ctx );
- }
- static void * des3_ctx_alloc( void )
- {
- mbedtls_des3_context *des3;
- des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) );
- if( des3 == NULL )
- return( NULL );
- mbedtls_des3_init( des3 );
- return( des3 );
- }
- static void des3_ctx_free( void *ctx )
- {
- mbedtls_des3_free( (mbedtls_des3_context *) ctx );
- mbedtls_free( ctx );
- }
- static const mbedtls_cipher_base_t des_info = {
- MBEDTLS_CIPHER_ID_DES,
- des_crypt_ecb_wrap,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- des_crypt_cbc_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- des_setkey_enc_wrap,
- des_setkey_dec_wrap,
- des_ctx_alloc,
- des_ctx_free
- };
- static const mbedtls_cipher_info_t des_ecb_info = {
- MBEDTLS_CIPHER_DES_ECB,
- MBEDTLS_MODE_ECB,
- MBEDTLS_KEY_LENGTH_DES,
- "DES-ECB",
- 8,
- 0,
- 8,
- &des_info
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const mbedtls_cipher_info_t des_cbc_info = {
- MBEDTLS_CIPHER_DES_CBC,
- MBEDTLS_MODE_CBC,
- MBEDTLS_KEY_LENGTH_DES,
- "DES-CBC",
- 8,
- 0,
- 8,
- &des_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- static const mbedtls_cipher_base_t des_ede_info = {
- MBEDTLS_CIPHER_ID_DES,
- des3_crypt_ecb_wrap,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- des3_crypt_cbc_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- des3_set2key_enc_wrap,
- des3_set2key_dec_wrap,
- des3_ctx_alloc,
- des3_ctx_free
- };
- static const mbedtls_cipher_info_t des_ede_ecb_info = {
- MBEDTLS_CIPHER_DES_EDE_ECB,
- MBEDTLS_MODE_ECB,
- MBEDTLS_KEY_LENGTH_DES_EDE,
- "DES-EDE-ECB",
- 8,
- 0,
- 8,
- &des_ede_info
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const mbedtls_cipher_info_t des_ede_cbc_info = {
- MBEDTLS_CIPHER_DES_EDE_CBC,
- MBEDTLS_MODE_CBC,
- MBEDTLS_KEY_LENGTH_DES_EDE,
- "DES-EDE-CBC",
- 8,
- 0,
- 8,
- &des_ede_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- static const mbedtls_cipher_base_t des_ede3_info = {
- MBEDTLS_CIPHER_ID_3DES,
- des3_crypt_ecb_wrap,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- des3_crypt_cbc_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- des3_set3key_enc_wrap,
- des3_set3key_dec_wrap,
- des3_ctx_alloc,
- des3_ctx_free
- };
- static const mbedtls_cipher_info_t des_ede3_ecb_info = {
- MBEDTLS_CIPHER_DES_EDE3_ECB,
- MBEDTLS_MODE_ECB,
- MBEDTLS_KEY_LENGTH_DES_EDE3,
- "DES-EDE3-ECB",
- 8,
- 0,
- 8,
- &des_ede3_info
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const mbedtls_cipher_info_t des_ede3_cbc_info = {
- MBEDTLS_CIPHER_DES_EDE3_CBC,
- MBEDTLS_MODE_CBC,
- MBEDTLS_KEY_LENGTH_DES_EDE3,
- "DES-EDE3-CBC",
- 8,
- 0,
- 8,
- &des_ede3_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_BLOWFISH_C)
- static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input,
- output );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, unsigned char *iv, const unsigned char *input,
- unsigned char *output )
- {
- return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv,
- input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length,
- iv_off, iv, input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
- {
- return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off,
- nonce_counter, stream_block, input, output );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- static int blowfish_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen );
- }
- static void * blowfish_ctx_alloc( void )
- {
- mbedtls_blowfish_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) );
- if( ctx == NULL )
- return( NULL );
- mbedtls_blowfish_init( ctx );
- return( ctx );
- }
- static void blowfish_ctx_free( void *ctx )
- {
- mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx );
- mbedtls_free( ctx );
- }
- static const mbedtls_cipher_base_t blowfish_info = {
- MBEDTLS_CIPHER_ID_BLOWFISH,
- blowfish_crypt_ecb_wrap,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- blowfish_crypt_cbc_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- blowfish_crypt_cfb64_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- blowfish_crypt_ctr_wrap,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
- #endif
- blowfish_setkey_wrap,
- blowfish_setkey_wrap,
- blowfish_ctx_alloc,
- blowfish_ctx_free
- };
- static const mbedtls_cipher_info_t blowfish_ecb_info = {
- MBEDTLS_CIPHER_BLOWFISH_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "BLOWFISH-ECB",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const mbedtls_cipher_info_t blowfish_cbc_info = {
- MBEDTLS_CIPHER_BLOWFISH_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "BLOWFISH-CBC",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- static const mbedtls_cipher_info_t blowfish_cfb64_info = {
- MBEDTLS_CIPHER_BLOWFISH_CFB64,
- MBEDTLS_MODE_CFB,
- 128,
- "BLOWFISH-CFB64",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- static const mbedtls_cipher_info_t blowfish_ctr_info = {
- MBEDTLS_CIPHER_BLOWFISH_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "BLOWFISH-CTR",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
- };
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #endif /* MBEDTLS_BLOWFISH_C */
- #if defined(MBEDTLS_ARC4_C)
- static int arc4_crypt_stream_wrap( void *ctx, size_t length,
- const unsigned char *input,
- unsigned char *output )
- {
- return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) );
- }
- static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- /* we get key_bitlen in bits, arc4 expects it in bytes */
- if( key_bitlen % 8 != 0 )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 );
- return( 0 );
- }
- static void * arc4_ctx_alloc( void )
- {
- mbedtls_arc4_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) );
- if( ctx == NULL )
- return( NULL );
- mbedtls_arc4_init( ctx );
- return( ctx );
- }
- static void arc4_ctx_free( void *ctx )
- {
- mbedtls_arc4_free( (mbedtls_arc4_context *) ctx );
- mbedtls_free( ctx );
- }
- static const mbedtls_cipher_base_t arc4_base_info = {
- MBEDTLS_CIPHER_ID_ARC4,
- NULL,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- arc4_crypt_stream_wrap,
- #endif
- arc4_setkey_wrap,
- arc4_setkey_wrap,
- arc4_ctx_alloc,
- arc4_ctx_free
- };
- static const mbedtls_cipher_info_t arc4_128_info = {
- MBEDTLS_CIPHER_ARC4_128,
- MBEDTLS_MODE_STREAM,
- 128,
- "ARC4-128",
- 0,
- 0,
- 1,
- &arc4_base_info
- };
- #endif /* MBEDTLS_ARC4_C */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- static int null_crypt_stream( void *ctx, size_t length,
- const unsigned char *input,
- unsigned char *output )
- {
- ((void) ctx);
- memmove( output, input, length );
- return( 0 );
- }
- static int null_setkey( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
- {
- ((void) ctx);
- ((void) key);
- ((void) key_bitlen);
- return( 0 );
- }
- static void * null_ctx_alloc( void )
- {
- return( (void *) 1 );
- }
- static void null_ctx_free( void *ctx )
- {
- ((void) ctx);
- }
- static const mbedtls_cipher_base_t null_base_info = {
- MBEDTLS_CIPHER_ID_NULL,
- NULL,
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_STREAM)
- null_crypt_stream,
- #endif
- null_setkey,
- null_setkey,
- null_ctx_alloc,
- null_ctx_free
- };
- static const mbedtls_cipher_info_t null_cipher_info = {
- MBEDTLS_CIPHER_NULL,
- MBEDTLS_MODE_STREAM,
- 0,
- "NULL",
- 0,
- 0,
- 1,
- &null_base_info
- };
- #endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
- const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
- {
- #if defined(MBEDTLS_AES_C)
- { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info },
- { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info },
- { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info },
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info },
- { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info },
- { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info },
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info },
- { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info },
- { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info },
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info },
- { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info },
- { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info },
- #endif
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info },
- { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info },
- { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info },
- #endif
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info },
- { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info },
- { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info },
- #endif
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_ARC4_C)
- { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info },
- #endif
- #if defined(MBEDTLS_BLOWFISH_C)
- { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info },
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info },
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info },
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info },
- #endif
- #endif /* MBEDTLS_BLOWFISH_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info },
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info },
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info },
- #endif
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info },
- #endif
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info },
- #endif
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info },
- #endif
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info },
- { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info },
- { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info },
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info },
- { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info },
- { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info },
- #endif
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- { MBEDTLS_CIPHER_NULL, &null_cipher_info },
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- { MBEDTLS_CIPHER_NONE, NULL }
- };
- #define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0]
- int mbedtls_cipher_supported[NUM_CIPHERS];
- #endif /* MBEDTLS_CIPHER_C */
- /********* Start of file library/ctr_drbg.c ************/
- /*
- * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The NIST SP 800-90 DRBGs are described in the following publucation.
- *
- * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_CTR_DRBG_C)
- #include <string.h>
- #if defined(MBEDTLS_FS_IO)
- #include <stdio.h>
- #endif
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- /* Implementation that should never be optimized out by the compiler */
- static void ctr_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * CTR_DRBG context initialization
- */
- void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- }
- /*
- * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
- * tests to succeed (which require known length fixed entropy)
- */
- int mbedtls_ctr_drbg_seed_entropy_len(
- mbedtls_ctr_drbg_context *ctx,
- int (*f_entropy)(void *, unsigned char *, size_t),
- void *p_entropy,
- const unsigned char *custom,
- size_t len,
- size_t entropy_len )
- {
- int ret;
- unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
- memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
- mbedtls_aes_init( &ctx->aes_ctx );
- ctx->f_entropy = f_entropy;
- ctx->p_entropy = p_entropy;
- ctx->entropy_len = entropy_len;
- ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
- /*
- * Initialize with an empty key
- */
- mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
- if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
- return( ret );
- return( 0 );
- }
- int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
- int (*f_entropy)(void *, unsigned char *, size_t),
- void *p_entropy,
- const unsigned char *custom,
- size_t len )
- {
- return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
- MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
- }
- void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
- {
- if( ctx == NULL )
- return;
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &ctx->mutex );
- #endif
- mbedtls_aes_free( &ctx->aes_ctx );
- ctr_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
- }
- void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
- {
- ctx->prediction_resistance = resistance;
- }
- void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
- {
- ctx->entropy_len = len;
- }
- void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
- {
- ctx->reseed_interval = interval;
- }
- static int block_cipher_df( unsigned char *output,
- const unsigned char *data, size_t data_len )
- {
- unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
- unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
- unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
- unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
- unsigned char *p, *iv;
- mbedtls_aes_context aes_ctx;
- int i, j;
- size_t buf_len, use_len;
- if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
- return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
- mbedtls_aes_init( &aes_ctx );
- /*
- * Construct IV (16 bytes) and S in buffer
- * IV = Counter (in 32-bits) padded to 16 with zeroes
- * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
- * data || 0x80
- * (Total is padded to a multiple of 16-bytes with zeroes)
- */
- p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
- *p++ = ( data_len >> 24 ) & 0xff;
- *p++ = ( data_len >> 16 ) & 0xff;
- *p++ = ( data_len >> 8 ) & 0xff;
- *p++ = ( data_len ) & 0xff;
- p += 3;
- *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
- memcpy( p, data, data_len );
- p[data_len] = 0x80;
- buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
- for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
- key[i] = i;
- mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS );
- /*
- * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
- */
- for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
- {
- p = buf;
- memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
- use_len = buf_len;
- while( use_len > 0 )
- {
- for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
- chain[i] ^= p[i];
- p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
- use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
- MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
- mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain );
- }
- memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
- /*
- * Update IV
- */
- buf[3]++;
- }
- /*
- * Do final encryption with reduced data
- */
- mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS );
- iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
- p = output;
- for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
- {
- mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
- memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
- p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
- }
- mbedtls_aes_free( &aes_ctx );
- return( 0 );
- }
- static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
- const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
- {
- unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
- unsigned char *p = tmp;
- int i, j;
- memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
- for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
- {
- /*
- * Increase counter
- */
- for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
- if( ++ctx->counter[i - 1] != 0 )
- break;
- /*
- * Crypt counter block
- */
- mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p );
- p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
- }
- for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
- tmp[i] ^= data[i];
- /*
- * Update key and counter
- */
- mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS );
- memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
- return( 0 );
- }
- void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
- const unsigned char *additional, size_t add_len )
- {
- unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
- if( add_len > 0 )
- {
- /* MAX_INPUT would be more logical here, but we have to match
- * block_cipher_df()'s limits since we can't propagate errors */
- if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
- add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
- block_cipher_df( add_input, additional, add_len );
- ctr_drbg_update_internal( ctx, add_input );
- }
- }
- int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
- const unsigned char *additional, size_t len )
- {
- unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
- size_t seedlen = 0;
- if( ctx->entropy_len + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
- return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
- /*
- * Gather entropy_len bytes of entropy to seed state
- */
- if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
- ctx->entropy_len ) )
- {
- return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
- }
- seedlen += ctx->entropy_len;
- /*
- * Add additional data
- */
- if( additional && len )
- {
- memcpy( seed + seedlen, additional, len );
- seedlen += len;
- }
- /*
- * Reduce to 384 bits
- */
- block_cipher_df( seed, seed, seedlen );
- /*
- * Update state
- */
- ctr_drbg_update_internal( ctx, seed );
- ctx->reseed_counter = 1;
- return( 0 );
- }
- int mbedtls_ctr_drbg_random_with_add( void *p_rng,
- unsigned char *output, size_t output_len,
- const unsigned char *additional, size_t add_len )
- {
- int ret = 0;
- mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
- unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
- unsigned char *p = output;
- unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
- int i;
- size_t use_len;
- if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
- return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
- if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
- return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
- if( ctx->reseed_counter > ctx->reseed_interval ||
- ctx->prediction_resistance )
- {
- if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
- return( ret );
- add_len = 0;
- }
- if( add_len > 0 )
- {
- block_cipher_df( add_input, additional, add_len );
- ctr_drbg_update_internal( ctx, add_input );
- }
- while( output_len > 0 )
- {
- /*
- * Increase counter
- */
- for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
- if( ++ctx->counter[i - 1] != 0 )
- break;
- /*
- * Crypt counter block
- */
- mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp );
- use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
- output_len;
- /*
- * Copy random block to destination
- */
- memcpy( p, tmp, use_len );
- p += use_len;
- output_len -= use_len;
- }
- ctr_drbg_update_internal( ctx, add_input );
- ctx->reseed_counter++;
- return( 0 );
- }
- int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
- {
- int ret;
- mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- #if defined(MBEDTLS_FS_IO)
- int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
- {
- int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
- FILE *f;
- unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
- if( ( f = fopen( path, "wb" ) ) == NULL )
- return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
- if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
- goto exit;
- if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
- {
- ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
- goto exit;
- }
- ret = 0;
- exit:
- fclose( f );
- return( ret );
- }
- int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
- {
- FILE *f;
- size_t n;
- unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
- fseek( f, 0, SEEK_END );
- n = (size_t) ftell( f );
- fseek( f, 0, SEEK_SET );
- if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
- {
- fclose( f );
- return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- }
- if( fread( buf, 1, n, f ) != n )
- {
- fclose( f );
- return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
- }
- fclose( f );
- mbedtls_ctr_drbg_update( ctx, buf, n );
- return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
- }
- #endif /* MBEDTLS_FS_IO */
- #if defined(MBEDTLS_SELF_TEST)
- static const unsigned char entropy_source_pr[96] =
- { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
- 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
- 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
- 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
- 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
- 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
- 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
- 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
- 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
- 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
- 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
- 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
- static const unsigned char entropy_source_nopr[64] =
- { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
- 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
- 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
- 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
- 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
- 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
- 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
- 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
- static const unsigned char nonce_pers_pr[16] =
- { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
- 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
- static const unsigned char nonce_pers_nopr[16] =
- { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
- 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
- static const unsigned char result_pr[16] =
- { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
- 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
- static const unsigned char result_nopr[16] =
- { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
- 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
- static size_t test_offset;
- static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
- size_t len )
- {
- const unsigned char *p = data;
- memcpy( buf, p + test_offset, len );
- test_offset += len;
- return( 0 );
- }
- #define CHK( c ) if( (c) != 0 ) \
- { \
- if( verbose != 0 ) \
- mbedtls_printf( "failed\n" ); \
- return( 1 ); \
- }
- /*
- * Checkup routine
- */
- int mbedtls_ctr_drbg_self_test( int verbose )
- {
- mbedtls_ctr_drbg_context ctx;
- unsigned char buf[16];
- mbedtls_ctr_drbg_init( &ctx );
- /*
- * Based on a NIST CTR_DRBG test vector (PR = True)
- */
- if( verbose != 0 )
- mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
- test_offset = 0;
- CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
- (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
- mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- mbedtls_ctr_drbg_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- /*
- * Based on a NIST CTR_DRBG test vector (PR = FALSE)
- */
- if( verbose != 0 )
- mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
- mbedtls_ctr_drbg_init( &ctx );
- test_offset = 0;
- CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
- (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
- CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
- CHK( memcmp( buf, result_nopr, 16 ) );
- mbedtls_ctr_drbg_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_CTR_DRBG_C */
- /********* Start of file library/debug.c ************/
- /*
- * Debugging routines
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_DEBUG_C)
- #include <stdarg.h>
- #include <stdio.h>
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #define mbedtls_snprintf snprintf
- #endif
- #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
- #define inline __inline
- #endif
- #define DEBUG_BUF_SIZE 512
- static int debug_threshold = 0;
- void mbedtls_debug_set_threshold( int threshold )
- {
- debug_threshold = threshold;
- }
- /*
- * All calls to f_dbg must be made via this function
- */
- static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *str )
- {
- /*
- * If in a threaded environment, we need a thread identifier.
- * Since there is no portable way to get one, use the address of the ssl
- * context instead, as it shouldn't be shared between threads.
- */
- #if defined(MBEDTLS_THREADING_C)
- char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
- mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", ssl, str );
- ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr );
- #else
- ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str );
- #endif
- }
- void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *format, ... )
- {
- va_list argp;
- char str[DEBUG_BUF_SIZE];
- int ret;
- if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
- return;
- va_start( argp, format );
- #if defined(_WIN32)
- #if defined(_TRUNCATE)
- ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
- #else
- ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
- if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE )
- {
- str[DEBUG_BUF_SIZE-1] = '\0';
- ret = -1;
- }
- #endif
- #else
- ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
- #endif
- va_end( argp );
- if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 )
- {
- str[ret] = '\n';
- str[ret + 1] = '\0';
- }
- debug_send_line( ssl, level, file, line, str );
- }
- void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *text, int ret )
- {
- char str[DEBUG_BUF_SIZE];
- if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
- return;
- /*
- * With non-blocking I/O and examples that just retry immediately,
- * the logs would be quickly flooded with WANT_READ, so ignore that.
- * Don't ignore WANT_WRITE however, since is is usually rare.
- */
- if( ret == MBEDTLS_ERR_SSL_WANT_READ )
- return;
- mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n",
- text, ret, -ret );
- debug_send_line( ssl, level, file, line, str );
- }
- void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line, const char *text,
- const unsigned char *buf, size_t len )
- {
- char str[DEBUG_BUF_SIZE];
- char txt[17];
- size_t i, idx = 0;
- if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
- return;
- mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n",
- text, (unsigned int) len );
- debug_send_line( ssl, level, file, line, str );
- idx = 0;
- memset( txt, 0, sizeof( txt ) );
- for( i = 0; i < len; i++ )
- {
- if( i >= 4096 )
- break;
- if( i % 16 == 0 )
- {
- if( i > 0 )
- {
- mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt );
- debug_send_line( ssl, level, file, line, str );
- idx = 0;
- memset( txt, 0, sizeof( txt ) );
- }
- idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ",
- (unsigned int) i );
- }
- idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x",
- (unsigned int) buf[i] );
- txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ;
- }
- if( len > 0 )
- {
- for( /* i = i */; i % 16 != 0; i++ )
- idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " " );
- mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt );
- debug_send_line( ssl, level, file, line, str );
- }
- }
- #if defined(MBEDTLS_ECP_C)
- void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *text, const mbedtls_ecp_point *X )
- {
- char str[DEBUG_BUF_SIZE];
- if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
- return;
- mbedtls_snprintf( str, sizeof( str ), "%s(X)", text );
- mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X );
- mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text );
- mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y );
- }
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_BIGNUM_C)
- void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *text, const mbedtls_mpi *X )
- {
- char str[DEBUG_BUF_SIZE];
- int j, k, zeros = 1;
- size_t i, n, idx = 0;
- if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold )
- return;
- for( n = X->n - 1; n > 0; n-- )
- if( X->p[n] != 0 )
- break;
- for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- )
- if( ( ( X->p[n] >> j ) & 1 ) != 0 )
- break;
- mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n",
- text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );
- debug_send_line( ssl, level, file, line, str );
- idx = 0;
- for( i = n + 1, j = 0; i > 0; i-- )
- {
- if( zeros && X->p[i - 1] == 0 )
- continue;
- for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- )
- {
- if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 )
- continue;
- else
- zeros = 0;
- if( j % 16 == 0 )
- {
- if( j > 0 )
- {
- mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
- debug_send_line( ssl, level, file, line, str );
- idx = 0;
- }
- }
- idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int)
- ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF );
- j++;
- }
- }
- if( zeros == 1 )
- idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" );
- mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
- debug_send_line( ssl, level, file, line, str );
- }
- #endif /* MBEDTLS_BIGNUM_C */
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- static void debug_print_pk( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *text, const mbedtls_pk_context *pk )
- {
- size_t i;
- mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS];
- char name[16];
- memset( items, 0, sizeof( items ) );
- if( mbedtls_pk_debug( pk, items ) != 0 )
- {
- debug_send_line( ssl, level, file, line,
- "invalid PK context\n" );
- return;
- }
- for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ )
- {
- if( items[i].type == MBEDTLS_PK_DEBUG_NONE )
- return;
- mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name );
- name[sizeof( name ) - 1] = '\0';
- if( items[i].type == MBEDTLS_PK_DEBUG_MPI )
- mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value );
- else
- #if defined(MBEDTLS_ECP_C)
- if( items[i].type == MBEDTLS_PK_DEBUG_ECP )
- mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value );
- else
- #endif
- debug_send_line( ssl, level, file, line,
- "should not happen\n" );
- }
- }
- static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line, const char *text )
- {
- char str[DEBUG_BUF_SIZE];
- const char *start, *cur;
- start = text;
- for( cur = text; *cur != '\0'; cur++ )
- {
- if( *cur == '\n' )
- {
- size_t len = cur - start + 1;
- if( len > DEBUG_BUF_SIZE - 1 )
- len = DEBUG_BUF_SIZE - 1;
- memcpy( str, start, len );
- str[len] = '\0';
- debug_send_line( ssl, level, file, line, str );
- start = cur + 1;
- }
- }
- }
- void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
- const char *file, int line,
- const char *text, const mbedtls_x509_crt *crt )
- {
- char str[DEBUG_BUF_SIZE];
- int i = 0;
- if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold )
- return;
- while( crt != NULL )
- {
- char buf[1024];
- mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i );
- debug_send_line( ssl, level, file, line, str );
- mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
- debug_print_line_by_line( ssl, level, file, line, buf );
- debug_print_pk( ssl, level, file, line, "crt->", &crt->pk );
- crt = crt->next;
- }
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- #endif /* MBEDTLS_DEBUG_C */
- /********* Start of file library/des.c ************/
- /*
- * FIPS-46-3 compliant Triple-DES implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * DES, on which TDES is based, was originally designed by Horst Feistel
- * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
- *
- * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_DES_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_DES_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void des_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- }
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- }
- #endif
- /*
- * Expanded DES S-boxes
- */
- static const uint32_t SB1[64] =
- {
- 0x01010400, 0x00000000, 0x00010000, 0x01010404,
- 0x01010004, 0x00010404, 0x00000004, 0x00010000,
- 0x00000400, 0x01010400, 0x01010404, 0x00000400,
- 0x01000404, 0x01010004, 0x01000000, 0x00000004,
- 0x00000404, 0x01000400, 0x01000400, 0x00010400,
- 0x00010400, 0x01010000, 0x01010000, 0x01000404,
- 0x00010004, 0x01000004, 0x01000004, 0x00010004,
- 0x00000000, 0x00000404, 0x00010404, 0x01000000,
- 0x00010000, 0x01010404, 0x00000004, 0x01010000,
- 0x01010400, 0x01000000, 0x01000000, 0x00000400,
- 0x01010004, 0x00010000, 0x00010400, 0x01000004,
- 0x00000400, 0x00000004, 0x01000404, 0x00010404,
- 0x01010404, 0x00010004, 0x01010000, 0x01000404,
- 0x01000004, 0x00000404, 0x00010404, 0x01010400,
- 0x00000404, 0x01000400, 0x01000400, 0x00000000,
- 0x00010004, 0x00010400, 0x00000000, 0x01010004
- };
- static const uint32_t SB2[64] =
- {
- 0x80108020, 0x80008000, 0x00008000, 0x00108020,
- 0x00100000, 0x00000020, 0x80100020, 0x80008020,
- 0x80000020, 0x80108020, 0x80108000, 0x80000000,
- 0x80008000, 0x00100000, 0x00000020, 0x80100020,
- 0x00108000, 0x00100020, 0x80008020, 0x00000000,
- 0x80000000, 0x00008000, 0x00108020, 0x80100000,
- 0x00100020, 0x80000020, 0x00000000, 0x00108000,
- 0x00008020, 0x80108000, 0x80100000, 0x00008020,
- 0x00000000, 0x00108020, 0x80100020, 0x00100000,
- 0x80008020, 0x80100000, 0x80108000, 0x00008000,
- 0x80100000, 0x80008000, 0x00000020, 0x80108020,
- 0x00108020, 0x00000020, 0x00008000, 0x80000000,
- 0x00008020, 0x80108000, 0x00100000, 0x80000020,
- 0x00100020, 0x80008020, 0x80000020, 0x00100020,
- 0x00108000, 0x00000000, 0x80008000, 0x00008020,
- 0x80000000, 0x80100020, 0x80108020, 0x00108000
- };
- static const uint32_t SB3[64] =
- {
- 0x00000208, 0x08020200, 0x00000000, 0x08020008,
- 0x08000200, 0x00000000, 0x00020208, 0x08000200,
- 0x00020008, 0x08000008, 0x08000008, 0x00020000,
- 0x08020208, 0x00020008, 0x08020000, 0x00000208,
- 0x08000000, 0x00000008, 0x08020200, 0x00000200,
- 0x00020200, 0x08020000, 0x08020008, 0x00020208,
- 0x08000208, 0x00020200, 0x00020000, 0x08000208,
- 0x00000008, 0x08020208, 0x00000200, 0x08000000,
- 0x08020200, 0x08000000, 0x00020008, 0x00000208,
- 0x00020000, 0x08020200, 0x08000200, 0x00000000,
- 0x00000200, 0x00020008, 0x08020208, 0x08000200,
- 0x08000008, 0x00000200, 0x00000000, 0x08020008,
- 0x08000208, 0x00020000, 0x08000000, 0x08020208,
- 0x00000008, 0x00020208, 0x00020200, 0x08000008,
- 0x08020000, 0x08000208, 0x00000208, 0x08020000,
- 0x00020208, 0x00000008, 0x08020008, 0x00020200
- };
- static const uint32_t SB4[64] =
- {
- 0x00802001, 0x00002081, 0x00002081, 0x00000080,
- 0x00802080, 0x00800081, 0x00800001, 0x00002001,
- 0x00000000, 0x00802000, 0x00802000, 0x00802081,
- 0x00000081, 0x00000000, 0x00800080, 0x00800001,
- 0x00000001, 0x00002000, 0x00800000, 0x00802001,
- 0x00000080, 0x00800000, 0x00002001, 0x00002080,
- 0x00800081, 0x00000001, 0x00002080, 0x00800080,
- 0x00002000, 0x00802080, 0x00802081, 0x00000081,
- 0x00800080, 0x00800001, 0x00802000, 0x00802081,
- 0x00000081, 0x00000000, 0x00000000, 0x00802000,
- 0x00002080, 0x00800080, 0x00800081, 0x00000001,
- 0x00802001, 0x00002081, 0x00002081, 0x00000080,
- 0x00802081, 0x00000081, 0x00000001, 0x00002000,
- 0x00800001, 0x00002001, 0x00802080, 0x00800081,
- 0x00002001, 0x00002080, 0x00800000, 0x00802001,
- 0x00000080, 0x00800000, 0x00002000, 0x00802080
- };
- static const uint32_t SB5[64] =
- {
- 0x00000100, 0x02080100, 0x02080000, 0x42000100,
- 0x00080000, 0x00000100, 0x40000000, 0x02080000,
- 0x40080100, 0x00080000, 0x02000100, 0x40080100,
- 0x42000100, 0x42080000, 0x00080100, 0x40000000,
- 0x02000000, 0x40080000, 0x40080000, 0x00000000,
- 0x40000100, 0x42080100, 0x42080100, 0x02000100,
- 0x42080000, 0x40000100, 0x00000000, 0x42000000,
- 0x02080100, 0x02000000, 0x42000000, 0x00080100,
- 0x00080000, 0x42000100, 0x00000100, 0x02000000,
- 0x40000000, 0x02080000, 0x42000100, 0x40080100,
- 0x02000100, 0x40000000, 0x42080000, 0x02080100,
- 0x40080100, 0x00000100, 0x02000000, 0x42080000,
- 0x42080100, 0x00080100, 0x42000000, 0x42080100,
- 0x02080000, 0x00000000, 0x40080000, 0x42000000,
- 0x00080100, 0x02000100, 0x40000100, 0x00080000,
- 0x00000000, 0x40080000, 0x02080100, 0x40000100
- };
- static const uint32_t SB6[64] =
- {
- 0x20000010, 0x20400000, 0x00004000, 0x20404010,
- 0x20400000, 0x00000010, 0x20404010, 0x00400000,
- 0x20004000, 0x00404010, 0x00400000, 0x20000010,
- 0x00400010, 0x20004000, 0x20000000, 0x00004010,
- 0x00000000, 0x00400010, 0x20004010, 0x00004000,
- 0x00404000, 0x20004010, 0x00000010, 0x20400010,
- 0x20400010, 0x00000000, 0x00404010, 0x20404000,
- 0x00004010, 0x00404000, 0x20404000, 0x20000000,
- 0x20004000, 0x00000010, 0x20400010, 0x00404000,
- 0x20404010, 0x00400000, 0x00004010, 0x20000010,
- 0x00400000, 0x20004000, 0x20000000, 0x00004010,
- 0x20000010, 0x20404010, 0x00404000, 0x20400000,
- 0x00404010, 0x20404000, 0x00000000, 0x20400010,
- 0x00000010, 0x00004000, 0x20400000, 0x00404010,
- 0x00004000, 0x00400010, 0x20004010, 0x00000000,
- 0x20404000, 0x20000000, 0x00400010, 0x20004010
- };
- static const uint32_t SB7[64] =
- {
- 0x00200000, 0x04200002, 0x04000802, 0x00000000,
- 0x00000800, 0x04000802, 0x00200802, 0x04200800,
- 0x04200802, 0x00200000, 0x00000000, 0x04000002,
- 0x00000002, 0x04000000, 0x04200002, 0x00000802,
- 0x04000800, 0x00200802, 0x00200002, 0x04000800,
- 0x04000002, 0x04200000, 0x04200800, 0x00200002,
- 0x04200000, 0x00000800, 0x00000802, 0x04200802,
- 0x00200800, 0x00000002, 0x04000000, 0x00200800,
- 0x04000000, 0x00200800, 0x00200000, 0x04000802,
- 0x04000802, 0x04200002, 0x04200002, 0x00000002,
- 0x00200002, 0x04000000, 0x04000800, 0x00200000,
- 0x04200800, 0x00000802, 0x00200802, 0x04200800,
- 0x00000802, 0x04000002, 0x04200802, 0x04200000,
- 0x00200800, 0x00000000, 0x00000002, 0x04200802,
- 0x00000000, 0x00200802, 0x04200000, 0x00000800,
- 0x04000002, 0x04000800, 0x00000800, 0x00200002
- };
- static const uint32_t SB8[64] =
- {
- 0x10001040, 0x00001000, 0x00040000, 0x10041040,
- 0x10000000, 0x10001040, 0x00000040, 0x10000000,
- 0x00040040, 0x10040000, 0x10041040, 0x00041000,
- 0x10041000, 0x00041040, 0x00001000, 0x00000040,
- 0x10040000, 0x10000040, 0x10001000, 0x00001040,
- 0x00041000, 0x00040040, 0x10040040, 0x10041000,
- 0x00001040, 0x00000000, 0x00000000, 0x10040040,
- 0x10000040, 0x10001000, 0x00041040, 0x00040000,
- 0x00041040, 0x00040000, 0x10041000, 0x00001000,
- 0x00000040, 0x10040040, 0x00001000, 0x00041040,
- 0x10001000, 0x00000040, 0x10000040, 0x10040000,
- 0x10040040, 0x10000000, 0x00040000, 0x10001040,
- 0x00000000, 0x10041040, 0x00040040, 0x10000040,
- 0x10040000, 0x10001000, 0x10001040, 0x00000000,
- 0x10041040, 0x00041000, 0x00041000, 0x00001040,
- 0x00001040, 0x00040040, 0x10000000, 0x10041000
- };
- /*
- * PC1: left and right halves bit-swap
- */
- static const uint32_t LHs[16] =
- {
- 0x00000000, 0x00000001, 0x00000100, 0x00000101,
- 0x00010000, 0x00010001, 0x00010100, 0x00010101,
- 0x01000000, 0x01000001, 0x01000100, 0x01000101,
- 0x01010000, 0x01010001, 0x01010100, 0x01010101
- };
- static const uint32_t RHs[16] =
- {
- 0x00000000, 0x01000000, 0x00010000, 0x01010000,
- 0x00000100, 0x01000100, 0x00010100, 0x01010100,
- 0x00000001, 0x01000001, 0x00010001, 0x01010001,
- 0x00000101, 0x01000101, 0x00010101, 0x01010101,
- };
- /*
- * Initial Permutation macro
- */
- #define DES_IP(X,Y) \
- { \
- T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
- T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
- T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
- T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
- Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
- T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
- X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
- }
- /*
- * Final Permutation macro
- */
- #define DES_FP(X,Y) \
- { \
- X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
- T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
- Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
- T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
- T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
- T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
- T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
- }
- /*
- * DES round macro
- */
- #define DES_ROUND(X,Y) \
- { \
- T = *SK++ ^ X; \
- Y ^= SB8[ (T ) & 0x3F ] ^ \
- SB6[ (T >> 8) & 0x3F ] ^ \
- SB4[ (T >> 16) & 0x3F ] ^ \
- SB2[ (T >> 24) & 0x3F ]; \
- \
- T = *SK++ ^ ((X << 28) | (X >> 4)); \
- Y ^= SB7[ (T ) & 0x3F ] ^ \
- SB5[ (T >> 8) & 0x3F ] ^ \
- SB3[ (T >> 16) & 0x3F ] ^ \
- SB1[ (T >> 24) & 0x3F ]; \
- }
- #define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
- void mbedtls_des_init( mbedtls_des_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_des_context ) );
- }
- void mbedtls_des_free( mbedtls_des_context *ctx )
- {
- if( ctx == NULL )
- return;
- des_zeroize( ctx, sizeof( mbedtls_des_context ) );
- }
- void mbedtls_des3_init( mbedtls_des3_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_des3_context ) );
- }
- void mbedtls_des3_free( mbedtls_des3_context *ctx )
- {
- if( ctx == NULL )
- return;
- des_zeroize( ctx, sizeof( mbedtls_des3_context ) );
- }
- static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
- 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
- 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
- 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
- 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
- 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
- 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
- 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
- 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
- 254 };
- void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
- {
- int i;
- for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
- key[i] = odd_parity_table[key[i] / 2];
- }
- /*
- * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
- */
- int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
- {
- int i;
- for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
- if( key[i] != odd_parity_table[key[i] / 2] )
- return( 1 );
- return( 0 );
- }
- /*
- * Table of weak and semi-weak keys
- *
- * Source: http://en.wikipedia.org/wiki/Weak_key
- *
- * Weak:
- * Alternating ones + zeros (0x0101010101010101)
- * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
- * '0xE0E0E0E0F1F1F1F1'
- * '0x1F1F1F1F0E0E0E0E'
- *
- * Semi-weak:
- * 0x011F011F010E010E and 0x1F011F010E010E01
- * 0x01E001E001F101F1 and 0xE001E001F101F101
- * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
- * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
- * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
- * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
- *
- */
- #define WEAK_KEY_COUNT 16
- static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
- {
- { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
- { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
- { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
- { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
- { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
- { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
- { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
- { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
- { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
- { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
- { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
- { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
- { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
- { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
- { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
- { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
- };
- int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
- {
- int i;
- for( i = 0; i < WEAK_KEY_COUNT; i++ )
- if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
- return( 1 );
- return( 0 );
- }
- #if !defined(MBEDTLS_DES_SETKEY_ALT)
- void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
- {
- int i;
- uint32_t X, Y, T;
- GET_UINT32_BE( X, key, 0 );
- GET_UINT32_BE( Y, key, 4 );
- /*
- * Permuted Choice 1
- */
- T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
- T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
- X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
- | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
- | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
- | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
- Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
- | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
- | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
- | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
- X &= 0x0FFFFFFF;
- Y &= 0x0FFFFFFF;
- /*
- * calculate subkeys
- */
- for( i = 0; i < 16; i++ )
- {
- if( i < 2 || i == 8 || i == 15 )
- {
- X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
- Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
- }
- else
- {
- X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
- Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
- }
- *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
- | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
- | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
- | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
- | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
- | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
- | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
- | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
- | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
- | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
- | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
- *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
- | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
- | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
- | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
- | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
- | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
- | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
- | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
- | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
- | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
- | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
- }
- }
- #endif /* !MBEDTLS_DES_SETKEY_ALT */
- /*
- * DES key schedule (56-bit, encryption)
- */
- int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
- {
- mbedtls_des_setkey( ctx->sk, key );
- return( 0 );
- }
- /*
- * DES key schedule (56-bit, decryption)
- */
- int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
- {
- int i;
- mbedtls_des_setkey( ctx->sk, key );
- for( i = 0; i < 16; i += 2 )
- {
- SWAP( ctx->sk[i ], ctx->sk[30 - i] );
- SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
- }
- return( 0 );
- }
- static void des3_set2key( uint32_t esk[96],
- uint32_t dsk[96],
- const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
- {
- int i;
- mbedtls_des_setkey( esk, key );
- mbedtls_des_setkey( dsk + 32, key + 8 );
- for( i = 0; i < 32; i += 2 )
- {
- dsk[i ] = esk[30 - i];
- dsk[i + 1] = esk[31 - i];
- esk[i + 32] = dsk[62 - i];
- esk[i + 33] = dsk[63 - i];
- esk[i + 64] = esk[i ];
- esk[i + 65] = esk[i + 1];
- dsk[i + 64] = dsk[i ];
- dsk[i + 65] = dsk[i + 1];
- }
- }
- /*
- * Triple-DES key schedule (112-bit, encryption)
- */
- int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
- const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
- {
- uint32_t sk[96];
- des3_set2key( ctx->sk, sk, key );
- des_zeroize( sk, sizeof( sk ) );
- return( 0 );
- }
- /*
- * Triple-DES key schedule (112-bit, decryption)
- */
- int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
- const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
- {
- uint32_t sk[96];
- des3_set2key( sk, ctx->sk, key );
- des_zeroize( sk, sizeof( sk ) );
- return( 0 );
- }
- static void des3_set3key( uint32_t esk[96],
- uint32_t dsk[96],
- const unsigned char key[24] )
- {
- int i;
- mbedtls_des_setkey( esk, key );
- mbedtls_des_setkey( dsk + 32, key + 8 );
- mbedtls_des_setkey( esk + 64, key + 16 );
- for( i = 0; i < 32; i += 2 )
- {
- dsk[i ] = esk[94 - i];
- dsk[i + 1] = esk[95 - i];
- esk[i + 32] = dsk[62 - i];
- esk[i + 33] = dsk[63 - i];
- dsk[i + 64] = esk[30 - i];
- dsk[i + 65] = esk[31 - i];
- }
- }
- /*
- * Triple-DES key schedule (168-bit, encryption)
- */
- int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
- const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
- {
- uint32_t sk[96];
- des3_set3key( ctx->sk, sk, key );
- des_zeroize( sk, sizeof( sk ) );
- return( 0 );
- }
- /*
- * Triple-DES key schedule (168-bit, decryption)
- */
- int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
- const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
- {
- uint32_t sk[96];
- des3_set3key( sk, ctx->sk, key );
- des_zeroize( sk, sizeof( sk ) );
- return( 0 );
- }
- /*
- * DES-ECB block encryption/decryption
- */
- #if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
- int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
- const unsigned char input[8],
- unsigned char output[8] )
- {
- int i;
- uint32_t X, Y, T, *SK;
- SK = ctx->sk;
- GET_UINT32_BE( X, input, 0 );
- GET_UINT32_BE( Y, input, 4 );
- DES_IP( X, Y );
- for( i = 0; i < 8; i++ )
- {
- DES_ROUND( Y, X );
- DES_ROUND( X, Y );
- }
- DES_FP( Y, X );
- PUT_UINT32_BE( Y, output, 0 );
- PUT_UINT32_BE( X, output, 4 );
- return( 0 );
- }
- #endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * DES-CBC buffer encryption/decryption
- */
- int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[8],
- const unsigned char *input,
- unsigned char *output )
- {
- int i;
- unsigned char temp[8];
- if( length % 8 )
- return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
- if( mode == MBEDTLS_DES_ENCRYPT )
- {
- while( length > 0 )
- {
- for( i = 0; i < 8; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
- mbedtls_des_crypt_ecb( ctx, output, output );
- memcpy( iv, output, 8 );
- input += 8;
- output += 8;
- length -= 8;
- }
- }
- else /* MBEDTLS_DES_DECRYPT */
- {
- while( length > 0 )
- {
- memcpy( temp, input, 8 );
- mbedtls_des_crypt_ecb( ctx, input, output );
- for( i = 0; i < 8; i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
- memcpy( iv, temp, 8 );
- input += 8;
- output += 8;
- length -= 8;
- }
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- /*
- * 3DES-ECB block encryption/decryption
- */
- #if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
- int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
- const unsigned char input[8],
- unsigned char output[8] )
- {
- int i;
- uint32_t X, Y, T, *SK;
- SK = ctx->sk;
- GET_UINT32_BE( X, input, 0 );
- GET_UINT32_BE( Y, input, 4 );
- DES_IP( X, Y );
- for( i = 0; i < 8; i++ )
- {
- DES_ROUND( Y, X );
- DES_ROUND( X, Y );
- }
- for( i = 0; i < 8; i++ )
- {
- DES_ROUND( X, Y );
- DES_ROUND( Y, X );
- }
- for( i = 0; i < 8; i++ )
- {
- DES_ROUND( Y, X );
- DES_ROUND( X, Y );
- }
- DES_FP( Y, X );
- PUT_UINT32_BE( Y, output, 0 );
- PUT_UINT32_BE( X, output, 4 );
- return( 0 );
- }
- #endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * 3DES-CBC buffer encryption/decryption
- */
- int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[8],
- const unsigned char *input,
- unsigned char *output )
- {
- int i;
- unsigned char temp[8];
- if( length % 8 )
- return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
- if( mode == MBEDTLS_DES_ENCRYPT )
- {
- while( length > 0 )
- {
- for( i = 0; i < 8; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
- mbedtls_des3_crypt_ecb( ctx, output, output );
- memcpy( iv, output, 8 );
- input += 8;
- output += 8;
- length -= 8;
- }
- }
- else /* MBEDTLS_DES_DECRYPT */
- {
- while( length > 0 )
- {
- memcpy( temp, input, 8 );
- mbedtls_des3_crypt_ecb( ctx, input, output );
- for( i = 0; i < 8; i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
- memcpy( iv, temp, 8 );
- input += 8;
- output += 8;
- length -= 8;
- }
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* !MBEDTLS_DES_ALT */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * DES and 3DES test vectors from:
- *
- * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
- */
- static const unsigned char des3_test_keys[24] =
- {
- 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
- 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
- 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
- };
- static const unsigned char des3_test_buf[8] =
- {
- 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
- };
- static const unsigned char des3_test_ecb_dec[3][8] =
- {
- { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
- { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
- { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
- };
- static const unsigned char des3_test_ecb_enc[3][8] =
- {
- { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
- { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
- { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
- };
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- static const unsigned char des3_test_iv[8] =
- {
- 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
- };
- static const unsigned char des3_test_cbc_dec[3][8] =
- {
- { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
- { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
- { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
- };
- static const unsigned char des3_test_cbc_enc[3][8] =
- {
- { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
- { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
- { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
- };
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- /*
- * Checkup routine
- */
- int mbedtls_des_self_test( int verbose )
- {
- int i, j, u, v, ret = 0;
- mbedtls_des_context ctx;
- mbedtls_des3_context ctx3;
- unsigned char buf[8];
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- unsigned char prv[8];
- unsigned char iv[8];
- #endif
- mbedtls_des_init( &ctx );
- mbedtls_des3_init( &ctx3 );
- /*
- * ECB mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " DES%c-ECB-%3d (%s): ",
- ( u == 0 ) ? ' ' : '3', 56 + u * 56,
- ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
- memcpy( buf, des3_test_buf, 8 );
- switch( i )
- {
- case 0:
- mbedtls_des_setkey_dec( &ctx, des3_test_keys );
- break;
- case 1:
- mbedtls_des_setkey_enc( &ctx, des3_test_keys );
- break;
- case 2:
- mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
- break;
- case 3:
- mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
- break;
- case 4:
- mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
- break;
- case 5:
- mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
- break;
- default:
- return( 1 );
- }
- for( j = 0; j < 10000; j++ )
- {
- if( u == 0 )
- mbedtls_des_crypt_ecb( &ctx, buf, buf );
- else
- mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
- }
- if( ( v == MBEDTLS_DES_DECRYPT &&
- memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
- ( v != MBEDTLS_DES_DECRYPT &&
- memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * CBC mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- v = i & 1;
- if( verbose != 0 )
- mbedtls_printf( " DES%c-CBC-%3d (%s): ",
- ( u == 0 ) ? ' ' : '3', 56 + u * 56,
- ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
- memcpy( iv, des3_test_iv, 8 );
- memcpy( prv, des3_test_iv, 8 );
- memcpy( buf, des3_test_buf, 8 );
- switch( i )
- {
- case 0:
- mbedtls_des_setkey_dec( &ctx, des3_test_keys );
- break;
- case 1:
- mbedtls_des_setkey_enc( &ctx, des3_test_keys );
- break;
- case 2:
- mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
- break;
- case 3:
- mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
- break;
- case 4:
- mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
- break;
- case 5:
- mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
- break;
- default:
- return( 1 );
- }
- if( v == MBEDTLS_DES_DECRYPT )
- {
- for( j = 0; j < 10000; j++ )
- {
- if( u == 0 )
- mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
- else
- mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
- }
- }
- else
- {
- for( j = 0; j < 10000; j++ )
- {
- unsigned char tmp[8];
- if( u == 0 )
- mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
- else
- mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
- memcpy( tmp, prv, 8 );
- memcpy( prv, buf, 8 );
- memcpy( buf, tmp, 8 );
- }
- memcpy( buf, prv, 8 );
- }
- if( ( v == MBEDTLS_DES_DECRYPT &&
- memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
- ( v != MBEDTLS_DES_DECRYPT &&
- memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- exit:
- mbedtls_des_free( &ctx );
- mbedtls_des3_free( &ctx3 );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_DES_C */
- /********* Start of file library/dhm.c ************/
- /*
- * Diffie-Hellman-Merkle key exchange
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * Reference:
- *
- * http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_DHM_C)
- #include <string.h>
- #if defined(MBEDTLS_PEM_PARSE_C)
- #endif
- #if defined(MBEDTLS_ASN1_PARSE_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #include <stdio.h>
- #define mbedtls_printf printf
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void dhm_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * helper to validate the mbedtls_mpi size and import it
- */
- static int dhm_read_bignum( mbedtls_mpi *X,
- unsigned char **p,
- const unsigned char *end )
- {
- int ret, n;
- if( end - *p < 2 )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- n = ( (*p)[0] << 8 ) | (*p)[1];
- (*p) += 2;
- if( (int)( end - *p ) < n )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
- return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
- (*p) += n;
- return( 0 );
- }
- /*
- * Verify sanity of parameter with regards to P
- *
- * Parameter should be: 2 <= public_param <= P - 2
- *
- * For more information on the attack, see:
- * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
- * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
- */
- static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
- {
- mbedtls_mpi L, U;
- int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
- mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
- if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 &&
- mbedtls_mpi_cmp_mpi( param, &U ) <= 0 )
- {
- ret = 0;
- }
- cleanup:
- mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
- return( ret );
- }
- void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
- }
- /*
- * Parse the ServerKeyExchange parameters
- */
- int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
- unsigned char **p,
- const unsigned char *end )
- {
- int ret;
- if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
- ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
- ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
- return( ret );
- if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
- return( ret );
- ctx->len = mbedtls_mpi_size( &ctx->P );
- return( 0 );
- }
- /*
- * Setup and write the ServerKeyExchange parameters
- */
- int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
- unsigned char *output, size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret, count = 0;
- size_t n1, n2, n3;
- unsigned char *p;
- if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- /*
- * Generate X as large as possible ( < P )
- */
- do
- {
- mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
- while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
- if( count++ > 10 )
- return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
- }
- while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
- /*
- * Calculate GX = G^X mod P
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
- &ctx->P , &ctx->RP ) );
- if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
- return( ret );
- /*
- * export P, G, GX
- */
- #define DHM_MPI_EXPORT(X,n) \
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \
- *p++ = (unsigned char)( n >> 8 ); \
- *p++ = (unsigned char)( n ); p += n;
- n1 = mbedtls_mpi_size( &ctx->P );
- n2 = mbedtls_mpi_size( &ctx->G );
- n3 = mbedtls_mpi_size( &ctx->GX );
- p = output;
- DHM_MPI_EXPORT( &ctx->P , n1 );
- DHM_MPI_EXPORT( &ctx->G , n2 );
- DHM_MPI_EXPORT( &ctx->GX, n3 );
- *olen = p - output;
- ctx->len = n1;
- cleanup:
- if( ret != 0 )
- return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
- return( 0 );
- }
- /*
- * Import the peer's public value G^Y
- */
- int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
- const unsigned char *input, size_t ilen )
- {
- int ret;
- if( ctx == NULL || ilen < 1 || ilen > ctx->len )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
- return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
- return( 0 );
- }
- /*
- * Create own private value X and export G^X
- */
- int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
- unsigned char *output, size_t olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret, count = 0;
- if( ctx == NULL || olen < 1 || olen > ctx->len )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- /*
- * generate X and calculate GX = G^X mod P
- */
- do
- {
- mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
- while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
- if( count++ > 10 )
- return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
- }
- while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
- &ctx->P , &ctx->RP ) );
- if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
- return( ret );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
- cleanup:
- if( ret != 0 )
- return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
- return( 0 );
- }
- /*
- * Use the blinding method and optimisation suggested in section 10 of:
- * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
- * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
- * Berlin Heidelberg, 1996. p. 104-113.
- */
- static int dhm_update_blinding( mbedtls_dhm_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret, count;
- /*
- * Don't use any blinding the first time a particular X is used,
- * but remember it to use blinding next time.
- */
- if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
- return( 0 );
- }
- /*
- * Ok, we need blinding. Can we re-use existing values?
- * If yes, just update them by squaring them.
- */
- if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
- return( 0 );
- }
- /*
- * We need to generate blinding values from scratch
- */
- /* Vi = random( 2, P-1 ) */
- count = 0;
- do
- {
- mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng );
- while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
- if( count++ > 10 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
- }
- while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
- /* Vf = Vi^-X mod P */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
- cleanup:
- return( ret );
- }
- /*
- * Derive and export the shared secret (G^Y)^X mod P
- */
- int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
- unsigned char *output, size_t output_size, size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_mpi GYb;
- if( ctx == NULL || output_size < ctx->len )
- return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
- if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
- return( ret );
- mbedtls_mpi_init( &GYb );
- /* Blind peer's value */
- if( f_rng != NULL )
- {
- MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
- }
- else
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
- /* Do modular exponentiation */
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
- &ctx->P, &ctx->RP ) );
- /* Unblind secret value */
- if( f_rng != NULL )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
- }
- *olen = mbedtls_mpi_size( &ctx->K );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
- cleanup:
- mbedtls_mpi_free( &GYb );
- if( ret != 0 )
- return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
- return( 0 );
- }
- /*
- * Free the components of a DHM key
- */
- void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
- {
- mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi );
- mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
- mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G );
- mbedtls_mpi_free( &ctx->P );
- dhm_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
- }
- #if defined(MBEDTLS_ASN1_PARSE_C)
- /*
- * Parse DHM parameters
- */
- int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
- size_t dhminlen )
- {
- int ret;
- size_t len;
- unsigned char *p, *end;
- #if defined(MBEDTLS_PEM_PARSE_C)
- mbedtls_pem_context pem;
- mbedtls_pem_init( &pem );
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN DH PARAMETERS-----",
- "-----END DH PARAMETERS-----",
- dhmin, NULL, 0, &dhminlen );
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- dhminlen = pem.buflen;
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- goto exit;
- p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
- #else
- p = (unsigned char *) dhmin;
- #endif /* MBEDTLS_PEM_PARSE_C */
- end = p + dhminlen;
- /*
- * DHParams ::= SEQUENCE {
- * prime INTEGER, -- P
- * generator INTEGER, -- g
- * privateValueLength INTEGER OPTIONAL
- * }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
- goto exit;
- }
- end = p + len;
- if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
- {
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
- goto exit;
- }
- if( p != end )
- {
- /* This might be the optional privateValueLength.
- * If so, we can cleanly discard it */
- mbedtls_mpi rec;
- mbedtls_mpi_init( &rec );
- ret = mbedtls_asn1_get_mpi( &p, end, &rec );
- mbedtls_mpi_free( &rec );
- if ( ret != 0 )
- {
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
- goto exit;
- }
- if ( p != end )
- {
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
- goto exit;
- }
- }
- ret = 0;
- dhm->len = mbedtls_mpi_size( &dhm->P );
- exit:
- #if defined(MBEDTLS_PEM_PARSE_C)
- mbedtls_pem_free( &pem );
- #endif
- if( ret != 0 )
- mbedtls_dhm_free( dhm );
- return( ret );
- }
- #if defined(MBEDTLS_FS_IO)
- /*
- * Load all data from a file into a given buffer.
- *
- * The file is expected to contain either PEM or DER encoded data.
- * A terminating null byte is always appended. It is included in the announced
- * length only if the data looks like it is PEM encoded.
- */
- static int load_file( const char *path, unsigned char **buf, size_t *n )
- {
- FILE *f;
- long size;
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
- fseek( f, 0, SEEK_END );
- if( ( size = ftell( f ) ) == -1 )
- {
- fclose( f );
- return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
- }
- fseek( f, 0, SEEK_SET );
- *n = (size_t) size;
- if( *n + 1 == 0 ||
- ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
- {
- fclose( f );
- return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
- }
- if( fread( *buf, 1, *n, f ) != *n )
- {
- fclose( f );
- mbedtls_free( *buf );
- return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
- }
- fclose( f );
- (*buf)[*n] = '\0';
- if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
- ++*n;
- return( 0 );
- }
- /*
- * Load and parse DHM parameters
- */
- int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
- {
- int ret;
- size_t n;
- unsigned char *buf;
- if( ( ret = load_file( path, &buf, &n ) ) != 0 )
- return( ret );
- ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
- dhm_zeroize( buf, n );
- mbedtls_free( buf );
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- #endif /* MBEDTLS_ASN1_PARSE_C */
- #if defined(MBEDTLS_SELF_TEST)
- static const char mbedtls_test_dhm_params[] =
- "-----BEGIN DH PARAMETERS-----\r\n"
- "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
- "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
- "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
- "-----END DH PARAMETERS-----\r\n";
- static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
- /*
- * Checkup routine
- */
- int mbedtls_dhm_self_test( int verbose )
- {
- int ret;
- mbedtls_dhm_context dhm;
- mbedtls_dhm_init( &dhm );
- if( verbose != 0 )
- mbedtls_printf( " DHM parameter load: " );
- if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
- (const unsigned char *) mbedtls_test_dhm_params,
- mbedtls_test_dhm_params_len ) ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n\n" );
- exit:
- mbedtls_dhm_free( &dhm );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_DHM_C */
- /********* Start of file library/ecdh.c ************/
- /*
- * Elliptic curve Diffie-Hellman
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * References:
- *
- * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
- * RFC 4492
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ECDH_C)
- #include <string.h>
- /*
- * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
- */
- int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
- }
- /*
- * Compute shared secret (SEC1 3.3.1)
- */
- int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
- const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_ecp_point P;
- mbedtls_ecp_point_init( &P );
- /*
- * Make sure Q is a valid pubkey before using it
- */
- MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
- if( mbedtls_ecp_is_zero( &P ) )
- {
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) );
- cleanup:
- mbedtls_ecp_point_free( &P );
- return( ret );
- }
- /*
- * Initialize context
- */
- void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
- }
- /*
- * Free context
- */
- void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
- {
- if( ctx == NULL )
- return;
- mbedtls_ecp_group_free( &ctx->grp );
- mbedtls_ecp_point_free( &ctx->Q );
- mbedtls_ecp_point_free( &ctx->Qp );
- mbedtls_ecp_point_free( &ctx->Vi );
- mbedtls_ecp_point_free( &ctx->Vf );
- mbedtls_mpi_free( &ctx->d );
- mbedtls_mpi_free( &ctx->z );
- mbedtls_mpi_free( &ctx->_d );
- }
- /*
- * Setup and write the ServerKeyExhange parameters (RFC 4492)
- * struct {
- * ECParameters curve_params;
- * ECPoint public;
- * } ServerECDHParams;
- */
- int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
- unsigned char *buf, size_t blen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- size_t grp_len, pt_len;
- if( ctx == NULL || ctx->grp.pbits == 0 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
- != 0 )
- return( ret );
- if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
- != 0 )
- return( ret );
- buf += grp_len;
- blen -= grp_len;
- if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
- &pt_len, buf, blen ) ) != 0 )
- return( ret );
- *olen = grp_len + pt_len;
- return( 0 );
- }
- /*
- * Read the ServerKeyExhange parameters (RFC 4492)
- * struct {
- * ECParameters curve_params;
- * ECPoint public;
- * } ServerECDHParams;
- */
- int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
- const unsigned char **buf, const unsigned char *end )
- {
- int ret;
- if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
- != 0 )
- return( ret );
- return( 0 );
- }
- /*
- * Get parameters from a keypair
- */
- int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
- mbedtls_ecdh_side side )
- {
- int ret;
- if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
- return( ret );
- /* If it's not our key, just import the public part as Qp */
- if( side == MBEDTLS_ECDH_THEIRS )
- return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) );
- /* Our key: import public (as Q) and private parts */
- if( side != MBEDTLS_ECDH_OURS )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
- ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 )
- return( ret );
- return( 0 );
- }
- /*
- * Setup and export the client public value
- */
- int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
- unsigned char *buf, size_t blen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- if( ctx == NULL || ctx->grp.pbits == 0 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
- != 0 )
- return( ret );
- return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
- olen, buf, blen );
- }
- /*
- * Parse and import the client's public value
- */
- int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
- const unsigned char *buf, size_t blen )
- {
- int ret;
- const unsigned char *p = buf;
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
- return( ret );
- if( (size_t)( p - buf ) != blen )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- return( 0 );
- }
- /*
- * Derive and export the shared secret
- */
- int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
- unsigned char *buf, size_t blen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- if( ctx == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
- f_rng, p_rng ) ) != 0 )
- {
- return( ret );
- }
- if( mbedtls_mpi_size( &ctx->z ) > blen )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
- return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
- }
- #endif /* MBEDTLS_ECDH_C */
- /********* Start of file library/ecdsa.c ************/
- /*
- * Elliptic curve DSA
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * References:
- *
- * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- #include <string.h>
- #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- #endif
- /*
- * Derive a suitable integer for group grp from a buffer of length len
- * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
- */
- static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
- const unsigned char *buf, size_t blen )
- {
- int ret;
- size_t n_size = ( grp->nbits + 7 ) / 8;
- size_t use_size = blen > n_size ? n_size : blen;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) );
- if( use_size * 8 > grp->nbits )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) );
- /* While at it, reduce modulo N */
- if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) );
- cleanup:
- return( ret );
- }
- /*
- * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
- * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
- */
- int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
- const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret, key_tries, sign_tries, blind_tries;
- mbedtls_ecp_point R;
- mbedtls_mpi k, e, t;
- /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
- if( grp->N.p == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- mbedtls_ecp_point_init( &R );
- mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
- sign_tries = 0;
- do
- {
- /*
- * Steps 1-3: generate a suitable ephemeral keypair
- * and set r = xR mod n
- */
- key_tries = 0;
- do
- {
- MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) );
- if( key_tries++ > 10 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
- }
- while( mbedtls_mpi_cmp_int( r, 0 ) == 0 );
- /*
- * Step 5: derive MPI from hashed message
- */
- MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
- /*
- * Generate a random value to blind inv_mod in next step,
- * avoiding a potential timing leak.
- */
- blind_tries = 0;
- do
- {
- size_t n_size = ( grp->nbits + 7 ) / 8;
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t, n_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t, 8 * n_size - grp->nbits ) );
- /* See mbedtls_ecp_gen_keypair() */
- if( ++blind_tries > 30 )
- return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
- }
- while( mbedtls_mpi_cmp_int( &t, 1 ) < 0 ||
- mbedtls_mpi_cmp_mpi( &t, &grp->N ) >= 0 );
- /*
- * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, r, d ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k, &k, &t ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
- if( sign_tries++ > 10 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
- }
- while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
- cleanup:
- mbedtls_ecp_point_free( &R );
- mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
- return( ret );
- }
- #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- /*
- * Deterministic signature wrapper
- */
- int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
- const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg )
- {
- int ret;
- mbedtls_hmac_drbg_context rng_ctx;
- unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
- size_t grp_len = ( grp->nbits + 7 ) / 8;
- const mbedtls_md_info_t *md_info;
- mbedtls_mpi h;
- if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- mbedtls_mpi_init( &h );
- mbedtls_hmac_drbg_init( &rng_ctx );
- /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
- MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
- mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len );
- ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
- mbedtls_hmac_drbg_random, &rng_ctx );
- cleanup:
- mbedtls_hmac_drbg_free( &rng_ctx );
- mbedtls_mpi_free( &h );
- return( ret );
- }
- #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
- /*
- * Verify ECDSA signature of hashed message (SEC1 4.1.4)
- * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
- */
- int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
- const unsigned char *buf, size_t blen,
- const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
- {
- int ret;
- mbedtls_mpi e, s_inv, u1, u2;
- mbedtls_ecp_point R;
- mbedtls_ecp_point_init( &R );
- mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
- /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
- if( grp->N.p == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * Step 1: make sure r and s are in range 1..n-1
- */
- if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 ||
- mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 )
- {
- ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
- goto cleanup;
- }
- /*
- * Additional precaution: make sure Q is valid
- */
- MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
- /*
- * Step 3: derive MPI from hashed message
- */
- MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
- /*
- * Step 4: u1 = e / s mod n, u2 = r / s mod n
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1, &e, &s_inv ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &u1, &grp->N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2, r, &s_inv ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &u2, &grp->N ) );
- /*
- * Step 5: R = u1 G + u2 Q
- *
- * Since we're not using any secret data, no need to pass a RNG to
- * mbedtls_ecp_mul() for countermesures.
- */
- MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, &R, &u1, &grp->G, &u2, Q ) );
- if( mbedtls_ecp_is_zero( &R ) )
- {
- ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
- goto cleanup;
- }
- /*
- * Step 6: convert xR to an integer (no-op)
- * Step 7: reduce xR mod n (gives v)
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) );
- /*
- * Step 8: check if v (that is, R.X) is equal to r
- */
- if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 )
- {
- ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
- goto cleanup;
- }
- cleanup:
- mbedtls_ecp_point_free( &R );
- mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
- return( ret );
- }
- /*
- * Convert a signature (given by context) to ASN.1
- */
- static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
- unsigned char *sig, size_t *slen )
- {
- int ret;
- unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
- unsigned char *p = buf + sizeof( buf );
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
- memcpy( sig, p, len );
- *slen = len;
- return( 0 );
- }
- /*
- * Compute and write signature
- */
- int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hlen,
- unsigned char *sig, size_t *slen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_mpi r, s;
- mbedtls_mpi_init( &r );
- mbedtls_mpi_init( &s );
- #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- (void) f_rng;
- (void) p_rng;
- MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx->grp, &r, &s, &ctx->d,
- hash, hlen, md_alg ) );
- #else
- (void) md_alg;
- MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
- hash, hlen, f_rng, p_rng ) );
- #endif
- MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
- cleanup:
- mbedtls_mpi_free( &r );
- mbedtls_mpi_free( &s );
- return( ret );
- }
- #if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \
- defined(MBEDTLS_ECDSA_DETERMINISTIC)
- int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
- const unsigned char *hash, size_t hlen,
- unsigned char *sig, size_t *slen,
- mbedtls_md_type_t md_alg )
- {
- return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
- NULL, NULL ) );
- }
- #endif
- /*
- * Read and check signature
- */
- int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
- const unsigned char *hash, size_t hlen,
- const unsigned char *sig, size_t slen )
- {
- int ret;
- unsigned char *p = (unsigned char *) sig;
- const unsigned char *end = sig + slen;
- size_t len;
- mbedtls_mpi r, s;
- mbedtls_mpi_init( &r );
- mbedtls_mpi_init( &s );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- if( p + len != end )
- {
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
- goto cleanup;
- }
- if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
- {
- ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
- &ctx->Q, &r, &s ) ) != 0 )
- goto cleanup;
- if( p != end )
- ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
- cleanup:
- mbedtls_mpi_free( &r );
- mbedtls_mpi_free( &s );
- return( ret );
- }
- /*
- * Generate key pair
- */
- int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
- mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
- }
- /*
- * Set context from an mbedtls_ecp_keypair
- */
- int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
- {
- int ret;
- if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
- ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
- ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 )
- {
- mbedtls_ecdsa_free( ctx );
- }
- return( ret );
- }
- /*
- * Initialize context
- */
- void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
- {
- mbedtls_ecp_keypair_init( ctx );
- }
- /*
- * Free context
- */
- void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
- {
- mbedtls_ecp_keypair_free( ctx );
- }
- #endif /* MBEDTLS_ECDSA_C */
- /********* Start of file library/ecjpake.c ************/
- /*
- * Elliptic curve J-PAKE
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * References in the code are to the Thread v1.0 Specification,
- * available to members of the Thread Group http://threadgroup.org/
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ECJPAKE_C)
- #include <string.h>
- /*
- * Convert a mbedtls_ecjpake_role to identifier string
- */
- static const char * const ecjpake_id[] = {
- "client",
- "server"
- };
- #define ID_MINE ( ecjpake_id[ ctx->role ] )
- #define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
- /*
- * Initialize context
- */
- void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
- {
- if( ctx == NULL )
- return;
- ctx->md_info = NULL;
- mbedtls_ecp_group_init( &ctx->grp );
- ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
- mbedtls_ecp_point_init( &ctx->Xm1 );
- mbedtls_ecp_point_init( &ctx->Xm2 );
- mbedtls_ecp_point_init( &ctx->Xp1 );
- mbedtls_ecp_point_init( &ctx->Xp2 );
- mbedtls_ecp_point_init( &ctx->Xp );
- mbedtls_mpi_init( &ctx->xm1 );
- mbedtls_mpi_init( &ctx->xm2 );
- mbedtls_mpi_init( &ctx->s );
- }
- /*
- * Free context
- */
- void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
- {
- if( ctx == NULL )
- return;
- ctx->md_info = NULL;
- mbedtls_ecp_group_free( &ctx->grp );
- mbedtls_ecp_point_free( &ctx->Xm1 );
- mbedtls_ecp_point_free( &ctx->Xm2 );
- mbedtls_ecp_point_free( &ctx->Xp1 );
- mbedtls_ecp_point_free( &ctx->Xp2 );
- mbedtls_ecp_point_free( &ctx->Xp );
- mbedtls_mpi_free( &ctx->xm1 );
- mbedtls_mpi_free( &ctx->xm2 );
- mbedtls_mpi_free( &ctx->s );
- }
- /*
- * Setup context
- */
- int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
- mbedtls_ecjpake_role role,
- mbedtls_md_type_t hash,
- mbedtls_ecp_group_id curve,
- const unsigned char *secret,
- size_t len )
- {
- int ret;
- ctx->role = role;
- if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
- return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
- MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
- cleanup:
- if( ret != 0 )
- mbedtls_ecjpake_free( ctx );
- return( ret );
- }
- /*
- * Check if context is ready for use
- */
- int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
- {
- if( ctx->md_info == NULL ||
- ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
- ctx->s.p == NULL )
- {
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- return( 0 );
- }
- /*
- * Write a point plus its length to a buffer
- */
- static int ecjpake_write_len_point( unsigned char **p,
- const unsigned char *end,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *P )
- {
- int ret;
- size_t len;
- /* Need at least 4 for length plus 1 for point */
- if( end < *p || end - *p < 5 )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- ret = mbedtls_ecp_point_write_binary( grp, P, pf,
- &len, *p + 4, end - ( *p + 4 ) );
- if( ret != 0 )
- return( ret );
- (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
- (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
- (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
- (*p)[3] = (unsigned char)( ( len ) & 0xFF );
- *p += 4 + len;
- return( 0 );
- }
- /*
- * Size of the temporary buffer for ecjpake_hash:
- * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
- */
- #define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
- /*
- * Compute hash for ZKP (7.4.2.2.2.1)
- */
- static int ecjpake_hash( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- const mbedtls_ecp_point *V,
- const mbedtls_ecp_point *X,
- const char *id,
- mbedtls_mpi *h )
- {
- int ret;
- unsigned char buf[ECJPAKE_HASH_BUF_LEN];
- unsigned char *p = buf;
- const unsigned char *end = buf + sizeof( buf );
- const size_t id_len = strlen( id );
- unsigned char hash[MBEDTLS_MD_MAX_SIZE];
- /* Write things to temporary buffer */
- MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
- MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
- MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
- if( end - p < 4 )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len ) & 0xFF );
- if( end < p || (size_t)( end - p ) < id_len )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- memcpy( p, id, id_len );
- p += id_len;
- /* Compute hash */
- mbedtls_md( md_info, buf, p - buf, hash );
- /* Turn it into an integer mod n */
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
- mbedtls_md_get_size( md_info ) ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
- cleanup:
- return( ret );
- }
- /*
- * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
- */
- static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- const mbedtls_ecp_point *X,
- const char *id,
- const unsigned char **p,
- const unsigned char *end )
- {
- int ret;
- mbedtls_ecp_point V, VV;
- mbedtls_mpi r, h;
- size_t r_len;
- mbedtls_ecp_point_init( &V );
- mbedtls_ecp_point_init( &VV );
- mbedtls_mpi_init( &r );
- mbedtls_mpi_init( &h );
- /*
- * struct {
- * ECPoint V;
- * opaque r<1..2^8-1>;
- * } ECSchnorrZKP;
- */
- if( end < *p )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
- if( end < *p || (size_t)( end - *p ) < 1 )
- {
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- r_len = *(*p)++;
- if( end < *p || (size_t)( end - *p ) < r_len )
- {
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
- *p += r_len;
- /*
- * Verification
- */
- MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
- &VV, &h, X, &r, G ) );
- if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
- {
- ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
- goto cleanup;
- }
- cleanup:
- mbedtls_ecp_point_free( &V );
- mbedtls_ecp_point_free( &VV );
- mbedtls_mpi_free( &r );
- mbedtls_mpi_free( &h );
- return( ret );
- }
- /*
- * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
- */
- static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- const mbedtls_mpi *x,
- const mbedtls_ecp_point *X,
- const char *id,
- unsigned char **p,
- const unsigned char *end,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_ecp_point V;
- mbedtls_mpi v;
- mbedtls_mpi h; /* later recycled to hold r */
- size_t len;
- if( end < *p )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- mbedtls_ecp_point_init( &V );
- mbedtls_mpi_init( &v );
- mbedtls_mpi_init( &h );
- /* Compute signature */
- MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
- G, &v, &V, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
- /* Write it out */
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
- pf, &len, *p, end - *p ) );
- *p += len;
- len = mbedtls_mpi_size( &h ); /* actually r */
- if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
- {
- ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
- goto cleanup;
- }
- *(*p)++ = (unsigned char)( len & 0xFF );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
- *p += len;
- cleanup:
- mbedtls_ecp_point_free( &V );
- mbedtls_mpi_free( &v );
- mbedtls_mpi_free( &h );
- return( ret );
- }
- /*
- * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
- * Output: verified public key X
- */
- static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- mbedtls_ecp_point *X,
- const char *id,
- const unsigned char **p,
- const unsigned char *end )
- {
- int ret;
- if( end < *p )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * struct {
- * ECPoint X;
- * ECSchnorrZKP zkp;
- * } ECJPAKEKeyKP;
- */
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
- if( mbedtls_ecp_is_zero( X ) )
- {
- ret = MBEDTLS_ERR_ECP_INVALID_KEY;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
- cleanup:
- return( ret );
- }
- /*
- * Generate an ECJPAKEKeyKP
- * Output: the serialized structure, plus private/public key pair
- */
- static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- mbedtls_mpi *x,
- mbedtls_ecp_point *X,
- const char *id,
- unsigned char **p,
- const unsigned char *end,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- size_t len;
- if( end < *p )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- /* Generate key (7.4.2.3.1) and write it out */
- MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
- f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
- pf, &len, *p, end - *p ) );
- *p += len;
- /* Generate and write proof */
- MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
- p, end, f_rng, p_rng ) );
- cleanup:
- return( ret );
- }
- /*
- * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
- * Ouputs: verified peer public keys Xa, Xb
- */
- static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- mbedtls_ecp_point *Xa,
- mbedtls_ecp_point *Xb,
- const char *id,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- const unsigned char *p = buf;
- const unsigned char *end = buf + len;
- /*
- * struct {
- * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
- * } ECJPAKEKeyKPPairList;
- */
- MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
- MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
- if( p != end )
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- cleanup:
- return( ret );
- }
- /*
- * Generate a ECJPAKEKeyKPPairList
- * Outputs: the serialized structure, plus two private/public key pairs
- */
- static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
- const mbedtls_ecp_group *grp,
- const int pf,
- const mbedtls_ecp_point *G,
- mbedtls_mpi *xm1,
- mbedtls_ecp_point *Xa,
- mbedtls_mpi *xm2,
- mbedtls_ecp_point *Xb,
- const char *id,
- unsigned char *buf,
- size_t len,
- size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- unsigned char *p = buf;
- const unsigned char *end = buf + len;
- MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
- &p, end, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
- &p, end, f_rng, p_rng ) );
- *olen = p - buf;
- cleanup:
- return( ret );
- }
- /*
- * Read and process the first round message
- */
- int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
- const unsigned char *buf,
- size_t len )
- {
- return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
- &ctx->grp.G,
- &ctx->Xp1, &ctx->Xp2, ID_PEER,
- buf, len ) );
- }
- /*
- * Generate and write the first round message
- */
- int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
- unsigned char *buf, size_t len, size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
- &ctx->grp.G,
- &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
- ID_MINE, buf, len, olen, f_rng, p_rng ) );
- }
- /*
- * Compute the sum of three points R = A + B + C
- */
- static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_ecp_point *A,
- const mbedtls_ecp_point *B,
- const mbedtls_ecp_point *C )
- {
- int ret;
- mbedtls_mpi one;
- mbedtls_mpi_init( &one );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
- cleanup:
- mbedtls_mpi_free( &one );
- return( ret );
- }
- /*
- * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
- */
- int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- const unsigned char *p = buf;
- const unsigned char *end = buf + len;
- mbedtls_ecp_group grp;
- mbedtls_ecp_point G; /* C: GB, S: GA */
- mbedtls_ecp_group_init( &grp );
- mbedtls_ecp_point_init( &G );
- /*
- * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
- * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
- * Unified: G = Xm1 + Xm2 + Xp1
- * We need that before parsing in order to check Xp as we read it
- */
- MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
- &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
- /*
- * struct {
- * ECParameters curve_params; // only client reading server msg
- * ECJPAKEKeyKP ecjpake_key_kp;
- * } Client/ServerECJPAKEParams;
- */
- if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
- {
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
- if( grp.id != ctx->grp.id )
- {
- ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
- goto cleanup;
- }
- }
- MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
- ctx->point_format,
- &G, &ctx->Xp, ID_PEER, &p, end ) );
- if( p != end )
- {
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- cleanup:
- mbedtls_ecp_group_free( &grp );
- mbedtls_ecp_point_free( &G );
- return( ret );
- }
- /*
- * Compute R = +/- X * S mod N, taking care not to leak S
- */
- static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
- const mbedtls_mpi *X,
- const mbedtls_mpi *S,
- const mbedtls_mpi *N,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_mpi b; /* Blinding value, then s + N * blinding */
- mbedtls_mpi_init( &b );
- /* b = s + rnd-128-bit * N */
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
- /* R = sign * X * b mod N */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
- R->s *= sign;
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
- cleanup:
- mbedtls_mpi_free( &b );
- return( ret );
- }
- /*
- * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
- */
- int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
- unsigned char *buf, size_t len, size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_ecp_point G; /* C: GA, S: GB */
- mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
- mbedtls_mpi xm; /* C: xc, S: xs */
- unsigned char *p = buf;
- const unsigned char *end = buf + len;
- size_t ec_len;
- mbedtls_ecp_point_init( &G );
- mbedtls_ecp_point_init( &Xm );
- mbedtls_mpi_init( &xm );
- /*
- * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
- *
- * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
- * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
- * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
- */
- MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
- &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
- MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
- &ctx->grp.N, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
- /*
- * Now write things out
- *
- * struct {
- * ECParameters curve_params; // only server writing its message
- * ECJPAKEKeyKP ecjpake_key_kp;
- * } Client/ServerECJPAKEParams;
- */
- if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
- {
- if( end < p )
- {
- ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
- p, end - p ) );
- p += ec_len;
- }
- if( end < p )
- {
- ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
- ctx->point_format, &ec_len, p, end - p ) );
- p += ec_len;
- MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
- ctx->point_format,
- &G, &xm, &Xm, ID_MINE,
- &p, end, f_rng, p_rng ) );
- *olen = p - buf;
- cleanup:
- mbedtls_ecp_point_free( &G );
- mbedtls_ecp_point_free( &Xm );
- mbedtls_mpi_free( &xm );
- return( ret );
- }
- /*
- * Derive PMS (7.4.2.7 / 7.4.2.8)
- */
- int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
- unsigned char *buf, size_t len, size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_ecp_point K;
- mbedtls_mpi m_xm2_s, one;
- unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
- size_t x_bytes;
- *olen = mbedtls_md_get_size( ctx->md_info );
- if( len < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- mbedtls_ecp_point_init( &K );
- mbedtls_mpi_init( &m_xm2_s );
- mbedtls_mpi_init( &one );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
- /*
- * Client: K = ( Xs - X4 * x2 * s ) * x2
- * Server: K = ( Xc - X2 * x4 * s ) * x4
- * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
- */
- MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
- &ctx->grp.N, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
- &one, &ctx->Xp,
- &m_xm2_s, &ctx->Xp2 ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
- f_rng, p_rng ) );
- /* PMS = SHA-256( K.X ) */
- x_bytes = ( ctx->grp.pbits + 7 ) / 8;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
- MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
- cleanup:
- mbedtls_ecp_point_free( &K );
- mbedtls_mpi_free( &m_xm2_s );
- mbedtls_mpi_free( &one );
- return( ret );
- }
- #undef ID_MINE
- #undef ID_PEER
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif
- #if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
- !defined(MBEDTLS_SHA256_C)
- int mbedtls_ecjpake_self_test( int verbose )
- {
- (void) verbose;
- return( 0 );
- }
- #else
- static const unsigned char ecjpake_test_password[] = {
- 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
- 0x65, 0x73, 0x74
- };
- static const unsigned char ecjpake_test_x1[] = {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
- };
- static const unsigned char ecjpake_test_x2[] = {
- 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
- 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
- };
- static const unsigned char ecjpake_test_x3[] = {
- 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
- 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
- };
- static const unsigned char ecjpake_test_x4[] = {
- 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
- 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
- 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
- };
- static const unsigned char ecjpake_test_cli_one[] = {
- 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
- 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
- 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
- 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
- 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
- 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
- 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
- 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
- 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
- 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
- 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
- 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
- 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
- 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
- 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
- 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
- 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
- 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
- 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
- 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
- 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
- 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
- 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
- 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
- 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
- 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
- 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
- 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
- };
- static const unsigned char ecjpake_test_srv_one[] = {
- 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
- 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
- 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
- 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
- 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
- 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
- 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
- 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
- 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
- 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
- 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
- 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
- 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
- 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
- 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
- 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
- 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
- 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
- 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
- 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
- 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
- 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
- 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
- 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
- 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
- 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
- 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
- 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
- };
- static const unsigned char ecjpake_test_srv_two[] = {
- 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
- 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
- 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
- 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
- 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
- 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
- 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
- 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
- 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
- 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
- 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
- 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
- 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
- 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
- };
- static const unsigned char ecjpake_test_cli_two[] = {
- 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
- 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
- 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
- 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
- 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
- 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
- 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
- 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
- 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
- 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
- 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
- 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
- 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
- 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
- };
- static const unsigned char ecjpake_test_pms[] = {
- 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
- 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
- 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
- };
- /* Load my private keys and generate the correponding public keys */
- static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
- const unsigned char *xm1, size_t len1,
- const unsigned char *xm2, size_t len2 )
- {
- int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
- &ctx->grp.G, NULL, NULL ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
- &ctx->grp.G, NULL, NULL ) );
- cleanup:
- return( ret );
- }
- /* For tests we don't need a secure RNG;
- * use the LGC from Numerical Recipes for simplicity */
- static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
- {
- static uint32_t x = 42;
- (void) p;
- while( len > 0 )
- {
- size_t use_len = len > 4 ? 4 : len;
- x = 1664525 * x + 1013904223;
- memcpy( out, &x, use_len );
- out += use_len;
- len -= use_len;
- }
- return( 0 );
- }
- #define TEST_ASSERT( x ) \
- do { \
- if( x ) \
- ret = 0; \
- else \
- { \
- ret = 1; \
- goto cleanup; \
- } \
- } while( 0 )
- /*
- * Checkup routine
- */
- int mbedtls_ecjpake_self_test( int verbose )
- {
- int ret;
- mbedtls_ecjpake_context cli;
- mbedtls_ecjpake_context srv;
- unsigned char buf[512], pms[32];
- size_t len, pmslen;
- mbedtls_ecjpake_init( &cli );
- mbedtls_ecjpake_init( &srv );
- if( verbose != 0 )
- mbedtls_printf( " ECJPAKE test #0 (setup): " );
- TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
- MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
- ecjpake_test_password,
- sizeof( ecjpake_test_password ) ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
- MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
- ecjpake_test_password,
- sizeof( ecjpake_test_password ) ) == 0 );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
- TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
- pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( len == pmslen );
- TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
- /* Simulate generation of round one */
- MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
- ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
- ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
- MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
- ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
- ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
- /* Read round one */
- TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
- ecjpake_test_cli_one,
- sizeof( ecjpake_test_cli_one ) ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
- ecjpake_test_srv_one,
- sizeof( ecjpake_test_srv_one ) ) == 0 );
- /* Skip generation of round two, read round two */
- TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
- ecjpake_test_srv_two,
- sizeof( ecjpake_test_srv_two ) ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
- ecjpake_test_cli_two,
- sizeof( ecjpake_test_cli_two ) ) == 0 );
- /* Server derives PMS */
- TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
- TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
- memset( buf, 0, len ); /* Avoid interferences with next step */
- /* Client derives PMS */
- TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
- buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
- TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
- TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- cleanup:
- mbedtls_ecjpake_free( &cli );
- mbedtls_ecjpake_free( &srv );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( ret );
- }
- #undef TEST_ASSERT
- #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_ECJPAKE_C */
- /********* Start of file library/ecp.c ************/
- /*
- * Elliptic curves over GF(p): generic functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * References:
- *
- * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
- * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
- * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
- * RFC 4492 for the related TLS structures and constants
- *
- * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
- *
- * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
- * for elliptic curve cryptosystems. In : Cryptographic Hardware and
- * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
- * <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
- *
- * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
- * render ECC resistant against Side Channel Attacks. IACR Cryptology
- * ePrint Archive, 2004, vol. 2004, p. 342.
- * <http://eprint.iacr.org/2004/342.pdf>
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ECP_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #include <stdio.h>
- #define mbedtls_printf printf
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
- #define inline __inline
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void ecp_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Counts of point addition and doubling, and field multiplications.
- * Used to test resistance of point multiplication to simple timing attacks.
- */
- static unsigned long add_count, dbl_count, mul_count;
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- #define ECP_SHORTWEIERSTRASS
- #endif
- #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- #define ECP_MONTGOMERY
- #endif
- /*
- * Curve types: internal for now, might be exposed later
- */
- typedef enum
- {
- ECP_TYPE_NONE = 0,
- ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
- ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
- } ecp_curve_type;
- /*
- * List of supported curves:
- * - internal ID
- * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
- * - size in bits
- * - readable name
- *
- * Curves are listed in order: largest curves first, and for a given size,
- * fastest curves first. This provides the default order for the SSL module.
- *
- * Reminder: update profiles in x509_crt.c when adding a new curves!
- */
- static const mbedtls_ecp_curve_info ecp_supported_curves[] =
- {
- #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
- { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
- { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
- { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
- { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
- { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" },
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
- { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" },
- #endif
- { MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
- };
- #define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \
- sizeof( ecp_supported_curves[0] )
- static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES];
- /*
- * List of supported curves and associated info
- */
- const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void )
- {
- return( ecp_supported_curves );
- }
- /*
- * List of supported curves, group ID only
- */
- const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void )
- {
- static int init_done = 0;
- if( ! init_done )
- {
- size_t i = 0;
- const mbedtls_ecp_curve_info *curve_info;
- for( curve_info = mbedtls_ecp_curve_list();
- curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
- curve_info++ )
- {
- ecp_supported_grp_id[i++] = curve_info->grp_id;
- }
- ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE;
- init_done = 1;
- }
- return( ecp_supported_grp_id );
- }
- /*
- * Get the curve info for the internal identifier
- */
- const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id )
- {
- const mbedtls_ecp_curve_info *curve_info;
- for( curve_info = mbedtls_ecp_curve_list();
- curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
- curve_info++ )
- {
- if( curve_info->grp_id == grp_id )
- return( curve_info );
- }
- return( NULL );
- }
- /*
- * Get the curve info from the TLS identifier
- */
- const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id )
- {
- const mbedtls_ecp_curve_info *curve_info;
- for( curve_info = mbedtls_ecp_curve_list();
- curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
- curve_info++ )
- {
- if( curve_info->tls_id == tls_id )
- return( curve_info );
- }
- return( NULL );
- }
- /*
- * Get the curve info from the name
- */
- const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name )
- {
- const mbedtls_ecp_curve_info *curve_info;
- for( curve_info = mbedtls_ecp_curve_list();
- curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
- curve_info++ )
- {
- if( strcmp( curve_info->name, name ) == 0 )
- return( curve_info );
- }
- return( NULL );
- }
- /*
- * Get the type of a curve
- */
- static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
- {
- if( grp->G.X.p == NULL )
- return( ECP_TYPE_NONE );
- if( grp->G.Y.p == NULL )
- return( ECP_TYPE_MONTGOMERY );
- else
- return( ECP_TYPE_SHORT_WEIERSTRASS );
- }
- /*
- * Initialize (the components of) a point
- */
- void mbedtls_ecp_point_init( mbedtls_ecp_point *pt )
- {
- if( pt == NULL )
- return;
- mbedtls_mpi_init( &pt->X );
- mbedtls_mpi_init( &pt->Y );
- mbedtls_mpi_init( &pt->Z );
- }
- /*
- * Initialize (the components of) a group
- */
- void mbedtls_ecp_group_init( mbedtls_ecp_group *grp )
- {
- if( grp == NULL )
- return;
- memset( grp, 0, sizeof( mbedtls_ecp_group ) );
- }
- /*
- * Initialize (the components of) a key pair
- */
- void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key )
- {
- if( key == NULL )
- return;
- mbedtls_ecp_group_init( &key->grp );
- mbedtls_mpi_init( &key->d );
- mbedtls_ecp_point_init( &key->Q );
- }
- /*
- * Unallocate (the components of) a point
- */
- void mbedtls_ecp_point_free( mbedtls_ecp_point *pt )
- {
- if( pt == NULL )
- return;
- mbedtls_mpi_free( &( pt->X ) );
- mbedtls_mpi_free( &( pt->Y ) );
- mbedtls_mpi_free( &( pt->Z ) );
- }
- /*
- * Unallocate (the components of) a group
- */
- void mbedtls_ecp_group_free( mbedtls_ecp_group *grp )
- {
- size_t i;
- if( grp == NULL )
- return;
- if( grp->h != 1 )
- {
- mbedtls_mpi_free( &grp->P );
- mbedtls_mpi_free( &grp->A );
- mbedtls_mpi_free( &grp->B );
- mbedtls_ecp_point_free( &grp->G );
- mbedtls_mpi_free( &grp->N );
- }
- if( grp->T != NULL )
- {
- for( i = 0; i < grp->T_size; i++ )
- mbedtls_ecp_point_free( &grp->T[i] );
- mbedtls_free( grp->T );
- }
- ecp_zeroize( grp, sizeof( mbedtls_ecp_group ) );
- }
- /*
- * Unallocate (the components of) a key pair
- */
- void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key )
- {
- if( key == NULL )
- return;
- mbedtls_ecp_group_free( &key->grp );
- mbedtls_mpi_free( &key->d );
- mbedtls_ecp_point_free( &key->Q );
- }
- /*
- * Copy the contents of a point
- */
- int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
- {
- int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) );
- cleanup:
- return( ret );
- }
- /*
- * Copy the contents of a group object
- */
- int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src )
- {
- return mbedtls_ecp_group_load( dst, src->id );
- }
- /*
- * Set point to zero
- */
- int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
- {
- int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) );
- cleanup:
- return( ret );
- }
- /*
- * Tell if a point is zero
- */
- int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
- {
- return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
- }
- /*
- * Compare two points lazyly
- */
- int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
- const mbedtls_ecp_point *Q )
- {
- if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
- mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
- mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
- {
- return( 0 );
- }
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- /*
- * Import a non-zero point from ASCII strings
- */
- int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
- const char *x, const char *y )
- {
- int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
- cleanup:
- return( ret );
- }
- /*
- * Export a point into unsigned binary data (SEC1 2.3.3)
- */
- int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
- int format, size_t *olen,
- unsigned char *buf, size_t buflen )
- {
- int ret = 0;
- size_t plen;
- if( format != MBEDTLS_ECP_PF_UNCOMPRESSED &&
- format != MBEDTLS_ECP_PF_COMPRESSED )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * Common case: P == 0
- */
- if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
- {
- if( buflen < 1 )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- buf[0] = 0x00;
- *olen = 1;
- return( 0 );
- }
- plen = mbedtls_mpi_size( &grp->P );
- if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
- {
- *olen = 2 * plen + 1;
- if( buflen < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- buf[0] = 0x04;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
- }
- else if( format == MBEDTLS_ECP_PF_COMPRESSED )
- {
- *olen = plen + 1;
- if( buflen < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
- }
- cleanup:
- return( ret );
- }
- /*
- * Import a point from unsigned binary data (SEC1 2.3.4)
- */
- int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
- const unsigned char *buf, size_t ilen )
- {
- int ret;
- size_t plen;
- if( ilen < 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( buf[0] == 0x00 )
- {
- if( ilen == 1 )
- return( mbedtls_ecp_set_zero( pt ) );
- else
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- plen = mbedtls_mpi_size( &grp->P );
- if( buf[0] != 0x04 )
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
- if( ilen != 2 * plen + 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
- cleanup:
- return( ret );
- }
- /*
- * Import a point from a TLS ECPoint record (RFC 4492)
- * struct {
- * opaque point <1..2^8-1>;
- * } ECPoint;
- */
- int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
- const unsigned char **buf, size_t buf_len )
- {
- unsigned char data_len;
- const unsigned char *buf_start;
- /*
- * We must have at least two bytes (1 for length, at least one for data)
- */
- if( buf_len < 2 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- data_len = *(*buf)++;
- if( data_len < 1 || data_len > buf_len - 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * Save buffer start for read_binary and update buf
- */
- buf_start = *buf;
- *buf += data_len;
- return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len );
- }
- /*
- * Export a point as a TLS ECPoint record (RFC 4492)
- * struct {
- * opaque point <1..2^8-1>;
- * } ECPoint;
- */
- int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
- int format, size_t *olen,
- unsigned char *buf, size_t blen )
- {
- int ret;
- /*
- * buffer length must be at least one, for our length byte
- */
- if( blen < 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format,
- olen, buf + 1, blen - 1) ) != 0 )
- return( ret );
- /*
- * write length to the first byte and update total length
- */
- buf[0] = (unsigned char) *olen;
- ++*olen;
- return( 0 );
- }
- /*
- * Set a group from an ECParameters record (RFC 4492)
- */
- int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len )
- {
- uint16_t tls_id;
- const mbedtls_ecp_curve_info *curve_info;
- /*
- * We expect at least three bytes (see below)
- */
- if( len < 3 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * First byte is curve_type; only named_curve is handled
- */
- if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * Next two bytes are the namedcurve value
- */
- tls_id = *(*buf)++;
- tls_id <<= 8;
- tls_id |= *(*buf)++;
- if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL )
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
- return mbedtls_ecp_group_load( grp, curve_info->grp_id );
- }
- /*
- * Write the ECParameters record corresponding to a group (RFC 4492)
- */
- int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
- unsigned char *buf, size_t blen )
- {
- const mbedtls_ecp_curve_info *curve_info;
- if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * We are going to write 3 bytes (see below)
- */
- *olen = 3;
- if( blen < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- /*
- * First byte is curve_type, always named_curve
- */
- *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
- /*
- * Next two bytes are the namedcurve value
- */
- buf[0] = curve_info->tls_id >> 8;
- buf[1] = curve_info->tls_id & 0xFF;
- return( 0 );
- }
- /*
- * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi.
- * See the documentation of struct mbedtls_ecp_group.
- *
- * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf.
- */
- static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp )
- {
- int ret;
- if( grp->modp == NULL )
- return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) );
- /* N->s < 0 is a much faster test, which fails only if N is 0 */
- if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) ||
- mbedtls_mpi_bitlen( N ) > 2 * grp->pbits )
- {
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- MBEDTLS_MPI_CHK( grp->modp( N ) );
- /* N->s < 0 is a much faster test, which fails only if N is 0 */
- while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) );
- while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 )
- /* we known P, N and the result are positive */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) );
- cleanup:
- return( ret );
- }
- /*
- * Fast mod-p functions expect their argument to be in the 0..p^2 range.
- *
- * In order to guarantee that, we need to ensure that operands of
- * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will
- * bring the result back to this range.
- *
- * The following macros are shortcuts for doing that.
- */
- /*
- * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi
- */
- #if defined(MBEDTLS_SELF_TEST)
- #define INC_MUL_COUNT mul_count++;
- #else
- #define INC_MUL_COUNT
- #endif
- #define MOD_MUL( N ) do { MBEDTLS_MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \
- while( 0 )
- /*
- * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
- * N->s < 0 is a very fast test, which fails only if N is 0
- */
- #define MOD_SUB( N ) \
- while( N.s < 0 && mbedtls_mpi_cmp_int( &N, 0 ) != 0 ) \
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &N, &N, &grp->P ) )
- /*
- * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
- * We known P, N and the result are positive, so sub_abs is correct, and
- * a bit faster.
- */
- #define MOD_ADD( N ) \
- while( mbedtls_mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &N, &N, &grp->P ) )
- #if defined(ECP_SHORTWEIERSTRASS)
- /*
- * For curves in short Weierstrass form, we do all the internal operations in
- * Jacobian coordinates.
- *
- * For multiplication, we'll use a comb method with coutermeasueres against
- * SPA, hence timing attacks.
- */
- /*
- * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1)
- * Cost: 1N := 1I + 3M + 1S
- */
- static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
- {
- int ret;
- mbedtls_mpi Zi, ZZi;
- if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
- return( 0 );
- mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
- /*
- * X = X / Z^2 mod p
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
- /*
- * Y = Y / Z^3 mod p
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
- /*
- * Z = 1
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
- cleanup:
- mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
- return( ret );
- }
- /*
- * Normalize jacobian coordinates of an array of (pointers to) points,
- * using Montgomery's trick to perform only one inversion mod P.
- * (See for example Cohen's "A Course in Computational Algebraic Number
- * Theory", Algorithm 10.3.4.)
- *
- * Warning: fails (returning an error) if one of the points is zero!
- * This should never happen, see choice of w in ecp_mul_comb().
- *
- * Cost: 1N(t) := 1I + (6t - 3)M + 1S
- */
- static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
- mbedtls_ecp_point *T[], size_t t_len )
- {
- int ret;
- size_t i;
- mbedtls_mpi *c, u, Zi, ZZi;
- if( t_len < 2 )
- return( ecp_normalize_jac( grp, *T ) );
- if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL )
- return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
- mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
- /*
- * c[i] = Z_0 * ... * Z_i
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
- for( i = 1; i < t_len; i++ )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) );
- MOD_MUL( c[i] );
- }
- /*
- * u = 1 / (Z_0 * ... * Z_n) mod P
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[t_len-1], &grp->P ) );
- for( i = t_len - 1; ; i-- )
- {
- /*
- * Zi = 1 / Z_i mod p
- * u = 1 / (Z_0 * ... * Z_i) mod P
- */
- if( i == 0 ) {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) );
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u );
- }
- /*
- * proceed as in normalize()
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y );
- /*
- * Post-precessing: reclaim some memory by shrinking coordinates
- * - not storing Z (always 1)
- * - shrinking other coordinates, but still keeping the same number of
- * limbs as P, as otherwise it will too likely be regrown too fast.
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) );
- mbedtls_mpi_free( &T[i]->Z );
- if( i == 0 )
- break;
- }
- cleanup:
- mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
- for( i = 0; i < t_len; i++ )
- mbedtls_mpi_free( &c[i] );
- mbedtls_free( c );
- return( ret );
- }
- /*
- * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak.
- * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid
- */
- static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp,
- mbedtls_ecp_point *Q,
- unsigned char inv )
- {
- int ret;
- unsigned char nonzero;
- mbedtls_mpi mQY;
- mbedtls_mpi_init( &mQY );
- /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) );
- nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) );
- cleanup:
- mbedtls_mpi_free( &mQY );
- return( ret );
- }
- /*
- * Point doubling R = 2 P, Jacobian coordinates
- *
- * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
- *
- * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
- * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
- *
- * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
- *
- * Cost: 1D := 3M + 4S (A == 0)
- * 4M + 4S (A == -3)
- * 3M + 6S + 1a otherwise
- */
- static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_ecp_point *P )
- {
- int ret;
- mbedtls_mpi M, S, T, U;
- #if defined(MBEDTLS_SELF_TEST)
- dbl_count++;
- #endif
- mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
- /* Special case for A = -3 */
- if( grp->A.p == NULL )
- {
- /* M = 3(X + Z^2)(X - Z^2) */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
- }
- else
- {
- /* M = 3.X^2 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
- /* Optimize away for "koblitz" curves with A = 0 */
- if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
- {
- /* M += A.Z^4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M );
- }
- }
- /* S = 4.X.Y^2 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S );
- /* U = 8.Y^4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
- /* T = M^2 - 2.S */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
- /* S = M(S - T) - U */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S );
- /* U = 2.Y.Z */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) );
- cleanup:
- mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
- return( ret );
- }
- /*
- * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22)
- *
- * The coordinates of Q must be normalized (= affine),
- * but those of P don't need to. R is not normalized.
- *
- * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q.
- * None of these cases can happen as intermediate step in ecp_mul_comb():
- * - at each step, P, Q and R are multiples of the base point, the factor
- * being less than its order, so none of them is zero;
- * - Q is an odd multiple of the base point, P an even multiple,
- * due to the choice of precomputed points in the modified comb method.
- * So branches for these cases do not leak secret information.
- *
- * We accept Q->Z being unset (saving memory in tables) as meaning 1.
- *
- * Cost: 1A := 8M + 3S
- */
- static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
- {
- int ret;
- mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
- #if defined(MBEDTLS_SELF_TEST)
- add_count++;
- #endif
- /*
- * Trivial cases: P == 0 or Q == 0 (case 1)
- */
- if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
- return( mbedtls_ecp_copy( R, Q ) );
- if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 )
- return( mbedtls_ecp_copy( R, P ) );
- /*
- * Make sure Q coordinates are normalized
- */
- if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
- mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
- /* Special cases (2) and (3) */
- if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
- {
- if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 )
- {
- ret = ecp_double_jac( grp, R, P );
- goto cleanup;
- }
- else
- {
- ret = mbedtls_ecp_set_zero( R );
- goto cleanup;
- }
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) );
- cleanup:
- mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 );
- mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
- return( ret );
- }
- /*
- * Randomize jacobian coordinates:
- * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
- * This is sort of the reverse operation of ecp_normalize_jac().
- *
- * This countermeasure was first suggested in [2].
- */
- static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret;
- mbedtls_mpi l, ll;
- size_t p_size = ( grp->pbits + 7 ) / 8;
- int count = 0;
- mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
- /* Generate l such that 1 < l < p */
- do
- {
- mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng );
- while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
- if( count++ > 10 )
- return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
- }
- while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
- /* Z = l * Z */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
- /* X = l^2 * X */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
- /* Y = l^3 * Y */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
- cleanup:
- mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
- return( ret );
- }
- /*
- * Check and define parameters used by the comb method (see below for details)
- */
- #if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7
- #error "MBEDTLS_ECP_WINDOW_SIZE out of bounds"
- #endif
- /* d = ceil( n / w ) */
- #define COMB_MAX_D ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2
- /* number of precomputed points */
- #define COMB_MAX_PRE ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
- /*
- * Compute the representation of m that will be used with our comb method.
- *
- * The basic comb method is described in GECC 3.44 for example. We use a
- * modified version that provides resistance to SPA by avoiding zero
- * digits in the representation as in [3]. We modify the method further by
- * requiring that all K_i be odd, which has the small cost that our
- * representation uses one more K_i, due to carries.
- *
- * Also, for the sake of compactness, only the seven low-order bits of x[i]
- * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in
- * the paper): it is set if and only if if s_i == -1;
- *
- * Calling conventions:
- * - x is an array of size d + 1
- * - w is the size, ie number of teeth, of the comb, and must be between
- * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE)
- * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d
- * (the result will be incorrect if these assumptions are not satisfied)
- */
- static void ecp_comb_fixed( unsigned char x[], size_t d,
- unsigned char w, const mbedtls_mpi *m )
- {
- size_t i, j;
- unsigned char c, cc, adjust;
- memset( x, 0, d+1 );
- /* First get the classical comb values (except for x_d = 0) */
- for( i = 0; i < d; i++ )
- for( j = 0; j < w; j++ )
- x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j;
- /* Now make sure x_1 .. x_d are odd */
- c = 0;
- for( i = 1; i <= d; i++ )
- {
- /* Add carry and update it */
- cc = x[i] & c;
- x[i] = x[i] ^ c;
- c = cc;
- /* Adjust if needed, avoiding branches */
- adjust = 1 - ( x[i] & 0x01 );
- c |= x[i] & ( x[i-1] * adjust );
- x[i] = x[i] ^ ( x[i-1] * adjust );
- x[i-1] |= adjust << 7;
- }
- }
- /*
- * Precompute points for the comb method
- *
- * If i = i_{w-1} ... i_1 is the binary representation of i, then
- * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P
- *
- * T must be able to hold 2^{w - 1} elements
- *
- * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1)
- */
- static int ecp_precompute_comb( const mbedtls_ecp_group *grp,
- mbedtls_ecp_point T[], const mbedtls_ecp_point *P,
- unsigned char w, size_t d )
- {
- int ret;
- unsigned char i, k;
- size_t j;
- mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1];
- /*
- * Set T[0] = P and
- * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value)
- */
- MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) );
- k = 0;
- for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 )
- {
- cur = T + i;
- MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) );
- for( j = 0; j < d; j++ )
- MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) );
- TT[k++] = cur;
- }
- MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) );
- /*
- * Compute the remaining ones using the minimal number of additions
- * Be careful to update T[2^l] only after using it!
- */
- k = 0;
- for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 )
- {
- j = i;
- while( j-- )
- {
- MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) );
- TT[k++] = &T[i + j];
- }
- }
- MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) );
- cleanup:
- return( ret );
- }
- /*
- * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ]
- */
- static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_ecp_point T[], unsigned char t_len,
- unsigned char i )
- {
- int ret;
- unsigned char ii, j;
- /* Ignore the "sign" bit and scale down */
- ii = ( i & 0x7Fu ) >> 1;
- /* Read the whole table to thwart cache-based timing attacks */
- for( j = 0; j < t_len; j++ )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) );
- }
- /* Safely invert result if i is "negative" */
- MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) );
- cleanup:
- return( ret );
- }
- /*
- * Core multiplication algorithm for the (modified) comb method.
- * This part is actually common with the basic comb method (GECC 3.44)
- *
- * Cost: d A + d D + 1 R
- */
- static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_ecp_point T[], unsigned char t_len,
- const unsigned char x[], size_t d,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- mbedtls_ecp_point Txi;
- size_t i;
- mbedtls_ecp_point_init( &Txi );
- /* Start with a non-zero point and randomize its coordinates */
- i = d;
- MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
- if( f_rng != 0 )
- MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
- while( i-- != 0 )
- {
- MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) );
- MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) );
- MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) );
- }
- cleanup:
- mbedtls_ecp_point_free( &Txi );
- return( ret );
- }
- /*
- * Multiplication using the comb method,
- * for curves in short Weierstrass form
- */
- static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_mpi *m, const mbedtls_ecp_point *P,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- unsigned char w, m_is_odd, p_eq_g, pre_len, i;
- size_t d;
- unsigned char k[COMB_MAX_D + 1];
- mbedtls_ecp_point *T;
- mbedtls_mpi M, mm;
- mbedtls_mpi_init( &M );
- mbedtls_mpi_init( &mm );
- /* we need N to be odd to trnaform m in an odd number, check now */
- if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- /*
- * Minimize the number of multiplications, that is minimize
- * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w )
- * (see costs of the various parts, with 1S = 1M)
- */
- w = grp->nbits >= 384 ? 5 : 4;
- /*
- * If P == G, pre-compute a bit more, since this may be re-used later.
- * Just adding one avoids upping the cost of the first mul too much,
- * and the memory cost too.
- */
- #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
- p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
- mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
- if( p_eq_g )
- w++;
- #else
- p_eq_g = 0;
- #endif
- /*
- * Make sure w is within bounds.
- * (The last test is useful only for very small curves in the test suite.)
- */
- if( w > MBEDTLS_ECP_WINDOW_SIZE )
- w = MBEDTLS_ECP_WINDOW_SIZE;
- if( w >= grp->nbits )
- w = 2;
- /* Other sizes that depend on w */
- pre_len = 1U << ( w - 1 );
- d = ( grp->nbits + w - 1 ) / w;
- /*
- * Prepare precomputed points: if P == G we want to
- * use grp->T if already initialized, or initialize it.
- */
- T = p_eq_g ? grp->T : NULL;
- if( T == NULL )
- {
- T = mbedtls_calloc( pre_len, sizeof( mbedtls_ecp_point ) );
- if( T == NULL )
- {
- ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
- goto cleanup;
- }
- MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) );
- if( p_eq_g )
- {
- grp->T = T;
- grp->T_size = pre_len;
- }
- }
- /*
- * Make sure M is odd (M = m or M = N - m, since N is odd)
- * using the fact that m * P = - (N - m) * P
- */
- m_is_odd = ( mbedtls_mpi_get_bit( m, 0 ) == 1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) );
- /*
- * Go for comb multiplication, R = M * P
- */
- ecp_comb_fixed( k, d, w, &M );
- MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) );
- /*
- * Now get m * P from M * P and normalize it
- */
- MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) );
- MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
- cleanup:
- if( T != NULL && ! p_eq_g )
- {
- for( i = 0; i < pre_len; i++ )
- mbedtls_ecp_point_free( &T[i] );
- mbedtls_free( T );
- }
- mbedtls_mpi_free( &M );
- mbedtls_mpi_free( &mm );
- if( ret != 0 )
- mbedtls_ecp_point_free( R );
- return( ret );
- }
- #endif /* ECP_SHORTWEIERSTRASS */
- #if defined(ECP_MONTGOMERY)
- /*
- * For Montgomery curves, we do all the internal arithmetic in projective
- * coordinates. Import/export of points uses only the x coordinates, which is
- * internaly represented as X / Z.
- *
- * For scalar multiplication, we'll use a Montgomery ladder.
- */
- /*
- * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1
- * Cost: 1M + 1I
- */
- static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P )
- {
- int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
- cleanup:
- return( ret );
- }
- /*
- * Randomize projective x/z coordinates:
- * (X, Z) -> (l X, l Z) for random l
- * This is sort of the reverse operation of ecp_normalize_mxz().
- *
- * This countermeasure was first suggested in [2].
- * Cost: 2M
- */
- static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret;
- mbedtls_mpi l;
- size_t p_size = ( grp->pbits + 7 ) / 8;
- int count = 0;
- mbedtls_mpi_init( &l );
- /* Generate l such that 1 < l < p */
- do
- {
- mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng );
- while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
- if( count++ > 10 )
- return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
- }
- while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
- cleanup:
- mbedtls_mpi_free( &l );
- return( ret );
- }
- /*
- * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q),
- * for Montgomery curves in x/z coordinates.
- *
- * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3
- * with
- * d = X1
- * P = (X2, Z2)
- * Q = (X3, Z3)
- * R = (X4, Z4)
- * S = (X5, Z5)
- * and eliminating temporary variables tO, ..., t4.
- *
- * Cost: 5M + 4S
- */
- static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
- mbedtls_ecp_point *R, mbedtls_ecp_point *S,
- const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
- const mbedtls_mpi *d )
- {
- int ret;
- mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
- mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
- mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
- mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z );
- cleanup:
- mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
- mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C );
- mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
- return( ret );
- }
- /*
- * Multiplication with Montgomery ladder in x/z coordinates,
- * for curves in Montgomery form
- */
- static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_mpi *m, const mbedtls_ecp_point *P,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- size_t i;
- unsigned char b;
- mbedtls_ecp_point RP;
- mbedtls_mpi PX;
- mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
- /* Save PX and read from P before writing to R, in case P == R */
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) );
- /* Set R to zero in modified x/z coordinates */
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
- mbedtls_mpi_free( &R->Y );
- /* RP.X might be sligtly larger than P, so reduce it */
- MOD_ADD( RP.X );
- /* Randomize coordinates of the starting point */
- if( f_rng != NULL )
- MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
- /* Loop invariant: R = result so far, RP = R + P */
- i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
- while( i-- > 0 )
- {
- b = mbedtls_mpi_get_bit( m, i );
- /*
- * if (b) R = 2R + P else R = 2R,
- * which is:
- * if (b) double_add( RP, R, RP, R )
- * else double_add( R, RP, R, RP )
- * but using safe conditional swaps to avoid leaks
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
- MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
- }
- MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
- cleanup:
- mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
- return( ret );
- }
- #endif /* ECP_MONTGOMERY */
- /*
- * Multiplication R = m * P
- */
- int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_mpi *m, const mbedtls_ecp_point *P,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret;
- /* Common sanity checks */
- if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ( ret = mbedtls_ecp_check_privkey( grp, m ) ) != 0 ||
- ( ret = mbedtls_ecp_check_pubkey( grp, P ) ) != 0 )
- return( ret );
- #if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
- return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
- #endif
- #if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
- return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) );
- #endif
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- #if defined(ECP_SHORTWEIERSTRASS)
- /*
- * Check that an affine point is valid as a public key,
- * short weierstrass curves (SEC1 3.2.3.1)
- */
- static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
- {
- int ret;
- mbedtls_mpi YY, RHS;
- /* pt coordinates must be normalized for our checks */
- if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 ||
- mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 ||
- mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
- mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
- return( MBEDTLS_ERR_ECP_INVALID_KEY );
- mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS );
- /*
- * YY = Y^2
- * RHS = X (X^2 + A) + B = X^3 + A X + B
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
- /* Special case for A = -3 */
- if( grp->A.p == NULL )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS );
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
- if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
- ret = MBEDTLS_ERR_ECP_INVALID_KEY;
- cleanup:
- mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS );
- return( ret );
- }
- #endif /* ECP_SHORTWEIERSTRASS */
- /*
- * R = m * P with shortcuts for m == 1 and m == -1
- * NOT constant-time - ONLY for short Weierstrass!
- */
- static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
- mbedtls_ecp_point *R,
- const mbedtls_mpi *m,
- const mbedtls_ecp_point *P )
- {
- int ret;
- if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
- }
- else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
- {
- MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
- if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
- }
- else
- {
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
- }
- cleanup:
- return( ret );
- }
- /*
- * Linear combination
- * NOT constant-time
- */
- int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
- const mbedtls_mpi *m, const mbedtls_ecp_point *P,
- const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
- {
- int ret;
- mbedtls_ecp_point mP;
- if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
- mbedtls_ecp_point_init( &mP );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) );
- MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) );
- MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
- cleanup:
- mbedtls_ecp_point_free( &mP );
- return( ret );
- }
- #if defined(ECP_MONTGOMERY)
- /*
- * Check validity of a public key for Montgomery curves with x-only schemes
- */
- static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
- {
- /* [Curve25519 p. 5] Just check X is the correct number of bytes */
- if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
- return( MBEDTLS_ERR_ECP_INVALID_KEY );
- return( 0 );
- }
- #endif /* ECP_MONTGOMERY */
- /*
- * Check that a point is valid as a public key
- */
- int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
- {
- /* Must use affine coordinates */
- if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
- return( MBEDTLS_ERR_ECP_INVALID_KEY );
- #if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
- return( ecp_check_pubkey_mx( grp, pt ) );
- #endif
- #if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
- return( ecp_check_pubkey_sw( grp, pt ) );
- #endif
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- /*
- * Check that an mbedtls_mpi is valid as a private key
- */
- int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d )
- {
- #if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
- {
- /* see [Curve25519] page 5 */
- if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
- mbedtls_mpi_get_bit( d, 1 ) != 0 ||
- mbedtls_mpi_get_bit( d, 2 ) != 0 ||
- mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */
- return( MBEDTLS_ERR_ECP_INVALID_KEY );
- else
- return( 0 );
- }
- #endif /* ECP_MONTGOMERY */
- #if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
- {
- /* see SEC1 3.2 */
- if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
- mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
- return( MBEDTLS_ERR_ECP_INVALID_KEY );
- else
- return( 0 );
- }
- #endif /* ECP_SHORTWEIERSTRASS */
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- /*
- * Generate a keypair with configurable base point
- */
- int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
- const mbedtls_ecp_point *G,
- mbedtls_mpi *d, mbedtls_ecp_point *Q,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- size_t n_size = ( grp->nbits + 7 ) / 8;
- #if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
- {
- /* [M225] page 5 */
- size_t b;
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
- /* Make sure the most significant bit is nbits */
- b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
- if( b > grp->nbits )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
- else
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
- /* Make sure the last three bits are unset */
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
- }
- else
- #endif /* ECP_MONTGOMERY */
- #if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
- {
- /* SEC1 3.2.1: Generate d such that 1 <= n < N */
- int count = 0;
- unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
- /*
- * Match the procedure given in RFC 6979 (deterministic ECDSA):
- * - use the same byte ordering;
- * - keep the leftmost nbits bits of the generated octet string;
- * - try until result is in the desired range.
- * This also avoids any biais, which is especially important for ECDSA.
- */
- do
- {
- MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
- /*
- * Each try has at worst a probability 1/2 of failing (the msb has
- * a probability 1/2 of being 0, and then the result will be < N),
- * so after 30 tries failure probability is a most 2**(-30).
- *
- * For most curves, 1 try is enough with overwhelming probability,
- * since N starts with a lot of 1s in binary, but some curves
- * such as secp224k1 are actually very close to the worst case.
- */
- if( ++count > 30 )
- return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
- }
- while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
- mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
- }
- else
- #endif /* ECP_SHORTWEIERSTRASS */
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- cleanup:
- if( ret != 0 )
- return( ret );
- return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
- }
- /*
- * Generate key pair, wrapper for conventional base point
- */
- int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
- mbedtls_mpi *d, mbedtls_ecp_point *Q,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
- }
- /*
- * Generate a keypair, prettier wrapper
- */
- int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret;
- if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
- return( ret );
- return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
- }
- /*
- * Check a public-private key pair
- */
- int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
- {
- int ret;
- mbedtls_ecp_point Q;
- mbedtls_ecp_group grp;
- if( pub->grp.id == MBEDTLS_ECP_DP_NONE ||
- pub->grp.id != prv->grp.id ||
- mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) ||
- mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) ||
- mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) )
- {
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- mbedtls_ecp_point_init( &Q );
- mbedtls_ecp_group_init( &grp );
- /* mbedtls_ecp_mul() needs a non-const group... */
- mbedtls_ecp_group_copy( &grp, &prv->grp );
- /* Also checks d is valid */
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
- if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
- mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
- mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) )
- {
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- goto cleanup;
- }
- cleanup:
- mbedtls_ecp_point_free( &Q );
- mbedtls_ecp_group_free( &grp );
- return( ret );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Checkup routine
- */
- int mbedtls_ecp_self_test( int verbose )
- {
- int ret;
- size_t i;
- mbedtls_ecp_group grp;
- mbedtls_ecp_point R, P;
- mbedtls_mpi m;
- unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
- /* exponents especially adapted for secp192r1 */
- const char *exponents[] =
- {
- "000000000000000000000000000000000000000000000001", /* one */
- "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */
- "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
- "400000000000000000000000000000000000000000000000", /* one and zeros */
- "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
- "555555555555555555555555555555555555555555555555", /* 101010... */
- };
- mbedtls_ecp_group_init( &grp );
- mbedtls_ecp_point_init( &R );
- mbedtls_ecp_point_init( &P );
- mbedtls_mpi_init( &m );
- /* Use secp192r1 if available, or any available curve */
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
- #else
- MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) );
- #endif
- if( verbose != 0 )
- mbedtls_printf( " ECP test #1 (constant op_count, base point G): " );
- /* Do a dummy multiplication first to trigger precomputation */
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
- for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
- {
- add_c_prev = add_count;
- dbl_c_prev = dbl_count;
- mul_c_prev = mul_count;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
- if( add_count != add_c_prev ||
- dbl_count != dbl_c_prev ||
- mul_count != mul_c_prev )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (%u)\n", (unsigned int) i );
- ret = 1;
- goto cleanup;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " ECP test #2 (constant op_count, other point): " );
- /* We computed P = 2G last time, use it */
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
- for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
- {
- add_c_prev = add_count;
- dbl_c_prev = dbl_count;
- mul_c_prev = mul_count;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
- if( add_count != add_c_prev ||
- dbl_count != dbl_c_prev ||
- mul_count != mul_c_prev )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (%u)\n", (unsigned int) i );
- ret = 1;
- goto cleanup;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- cleanup:
- if( ret < 0 && verbose != 0 )
- mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
- mbedtls_ecp_group_free( &grp );
- mbedtls_ecp_point_free( &R );
- mbedtls_ecp_point_free( &P );
- mbedtls_mpi_free( &m );
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_ECP_C */
- /********* Start of file library/ecp_curves.c ************/
- /*
- * Elliptic curves over GF(p): curve-specific data and functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ECP_C)
- #include <string.h>
- #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
- #define inline __inline
- #endif
- /* Amalgamated Release Mappings */
- #undef ADD
- /*
- * Conversion macros for embedded constants:
- * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
- */
- #if defined(MBEDTLS_HAVE_INT32)
- #define BYTES_TO_T_UINT_4( a, b, c, d ) \
- ( (mbedtls_mpi_uint) a << 0 ) | \
- ( (mbedtls_mpi_uint) b << 8 ) | \
- ( (mbedtls_mpi_uint) c << 16 ) | \
- ( (mbedtls_mpi_uint) d << 24 )
- #define BYTES_TO_T_UINT_2( a, b ) \
- BYTES_TO_T_UINT_4( a, b, 0, 0 )
- #define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
- BYTES_TO_T_UINT_4( a, b, c, d ), \
- BYTES_TO_T_UINT_4( e, f, g, h )
- #else /* 64-bits */
- #define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
- ( (mbedtls_mpi_uint) a << 0 ) | \
- ( (mbedtls_mpi_uint) b << 8 ) | \
- ( (mbedtls_mpi_uint) c << 16 ) | \
- ( (mbedtls_mpi_uint) d << 24 ) | \
- ( (mbedtls_mpi_uint) e << 32 ) | \
- ( (mbedtls_mpi_uint) f << 40 ) | \
- ( (mbedtls_mpi_uint) g << 48 ) | \
- ( (mbedtls_mpi_uint) h << 56 )
- #define BYTES_TO_T_UINT_4( a, b, c, d ) \
- BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
- #define BYTES_TO_T_UINT_2( a, b ) \
- BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
- #endif /* bits in mbedtls_mpi_uint */
- /*
- * Note: the constants are in little-endian order
- * to be directly usable in MPIs
- */
- /*
- * Domain parameters for secp192r1
- */
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- static const mbedtls_mpi_uint secp192r1_p[] = {
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- static const mbedtls_mpi_uint secp192r1_b[] = {
- BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
- BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
- BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
- };
- static const mbedtls_mpi_uint secp192r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
- BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
- BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
- };
- static const mbedtls_mpi_uint secp192r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
- BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
- BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
- };
- static const mbedtls_mpi_uint secp192r1_n[] = {
- BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
- BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
- /*
- * Domain parameters for secp224r1
- */
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
- static const mbedtls_mpi_uint secp224r1_p[] = {
- BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
- BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
- };
- static const mbedtls_mpi_uint secp224r1_b[] = {
- BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
- BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
- BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
- BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
- };
- static const mbedtls_mpi_uint secp224r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
- BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
- BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
- BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
- };
- static const mbedtls_mpi_uint secp224r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
- BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
- BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
- BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
- };
- static const mbedtls_mpi_uint secp224r1_n[] = {
- BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
- BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
- /*
- * Domain parameters for secp256r1
- */
- #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- static const mbedtls_mpi_uint secp256r1_p[] = {
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
- BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
- BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- static const mbedtls_mpi_uint secp256r1_b[] = {
- BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
- BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
- BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
- BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
- };
- static const mbedtls_mpi_uint secp256r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
- BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
- BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
- BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
- };
- static const mbedtls_mpi_uint secp256r1_gy[] = {
- BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
- BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
- BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
- BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
- };
- static const mbedtls_mpi_uint secp256r1_n[] = {
- BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
- BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
- /*
- * Domain parameters for secp384r1
- */
- #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- static const mbedtls_mpi_uint secp384r1_p[] = {
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
- BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- static const mbedtls_mpi_uint secp384r1_b[] = {
- BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
- BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
- BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
- BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
- BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
- BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
- };
- static const mbedtls_mpi_uint secp384r1_gx[] = {
- BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
- BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
- BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
- BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
- BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
- BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
- };
- static const mbedtls_mpi_uint secp384r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
- BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
- BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
- BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
- BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
- BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
- };
- static const mbedtls_mpi_uint secp384r1_n[] = {
- BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
- BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
- BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
- /*
- * Domain parameters for secp521r1
- */
- #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- static const mbedtls_mpi_uint secp521r1_p[] = {
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
- };
- static const mbedtls_mpi_uint secp521r1_b[] = {
- BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
- BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
- BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
- BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
- BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
- BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
- BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
- BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
- BYTES_TO_T_UINT_2( 0x51, 0x00 ),
- };
- static const mbedtls_mpi_uint secp521r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
- BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
- BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
- BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
- BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
- BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
- BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
- BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
- BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
- };
- static const mbedtls_mpi_uint secp521r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
- BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
- BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
- BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
- BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
- BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
- BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
- BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
- BYTES_TO_T_UINT_2( 0x18, 0x01 ),
- };
- static const mbedtls_mpi_uint secp521r1_n[] = {
- BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
- BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
- BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
- BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
- BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
- static const mbedtls_mpi_uint secp192k1_p[] = {
- BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- static const mbedtls_mpi_uint secp192k1_a[] = {
- BYTES_TO_T_UINT_2( 0x00, 0x00 ),
- };
- static const mbedtls_mpi_uint secp192k1_b[] = {
- BYTES_TO_T_UINT_2( 0x03, 0x00 ),
- };
- static const mbedtls_mpi_uint secp192k1_gx[] = {
- BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
- BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
- BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
- };
- static const mbedtls_mpi_uint secp192k1_gy[] = {
- BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
- BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
- BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
- };
- static const mbedtls_mpi_uint secp192k1_n[] = {
- BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
- BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
- static const mbedtls_mpi_uint secp224k1_p[] = {
- BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- static const mbedtls_mpi_uint secp224k1_a[] = {
- BYTES_TO_T_UINT_2( 0x00, 0x00 ),
- };
- static const mbedtls_mpi_uint secp224k1_b[] = {
- BYTES_TO_T_UINT_2( 0x05, 0x00 ),
- };
- static const mbedtls_mpi_uint secp224k1_gx[] = {
- BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
- BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
- BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
- BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
- };
- static const mbedtls_mpi_uint secp224k1_gy[] = {
- BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
- BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
- BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
- BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
- };
- static const mbedtls_mpi_uint secp224k1_n[] = {
- BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
- BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
- BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
- BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- static const mbedtls_mpi_uint secp256k1_p[] = {
- BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- static const mbedtls_mpi_uint secp256k1_a[] = {
- BYTES_TO_T_UINT_2( 0x00, 0x00 ),
- };
- static const mbedtls_mpi_uint secp256k1_b[] = {
- BYTES_TO_T_UINT_2( 0x07, 0x00 ),
- };
- static const mbedtls_mpi_uint secp256k1_gx[] = {
- BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
- BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
- BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
- BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
- };
- static const mbedtls_mpi_uint secp256k1_gy[] = {
- BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
- BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
- BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
- BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
- };
- static const mbedtls_mpi_uint secp256k1_n[] = {
- BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
- BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
- BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
- };
- #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
- /*
- * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
- */
- #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
- static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
- BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
- BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
- BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
- BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
- };
- static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
- BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
- BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
- BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
- BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
- };
- static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
- BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
- BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
- BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
- BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
- };
- static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
- BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
- BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
- BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
- };
- static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
- BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
- BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
- BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
- };
- static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
- BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
- BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
- BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
- BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
- };
- #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
- /*
- * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
- */
- #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
- static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
- BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
- BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
- BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
- BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
- BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
- BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
- };
- static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
- BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
- BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
- BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
- BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
- BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
- BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
- };
- static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
- BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
- BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
- BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
- BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
- BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
- BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
- };
- static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
- BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
- BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
- BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
- BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
- BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
- };
- static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
- BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
- BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
- BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
- BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
- BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
- };
- static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
- BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
- BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
- BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
- BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
- BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
- BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
- };
- #endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
- /*
- * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
- */
- #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
- static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
- BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
- BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
- BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
- BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
- BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
- BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
- BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
- BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
- };
- static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
- BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
- BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
- BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
- BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
- BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
- BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
- BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
- BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
- };
- static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
- BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
- BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
- BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
- BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
- BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
- BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
- BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
- BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
- };
- static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
- BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
- BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
- BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
- BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
- BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
- BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
- BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
- BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
- };
- static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
- BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
- BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
- BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
- BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
- BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
- BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
- BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
- BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
- };
- static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
- BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
- BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
- BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
- BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
- BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
- BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
- BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
- BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
- };
- #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
- /*
- * Create an MPI from embedded constants
- * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
- */
- static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
- {
- X->s = 1;
- X->n = len / sizeof( mbedtls_mpi_uint );
- X->p = (mbedtls_mpi_uint *) p;
- }
- /*
- * Set an MPI to static value 1
- */
- static inline void ecp_mpi_set1( mbedtls_mpi *X )
- {
- static mbedtls_mpi_uint one[] = { 1 };
- X->s = 1;
- X->n = 1;
- X->p = one;
- }
- /*
- * Make group available from embedded constants
- */
- static int ecp_group_load( mbedtls_ecp_group *grp,
- const mbedtls_mpi_uint *p, size_t plen,
- const mbedtls_mpi_uint *a, size_t alen,
- const mbedtls_mpi_uint *b, size_t blen,
- const mbedtls_mpi_uint *gx, size_t gxlen,
- const mbedtls_mpi_uint *gy, size_t gylen,
- const mbedtls_mpi_uint *n, size_t nlen)
- {
- ecp_mpi_load( &grp->P, p, plen );
- if( a != NULL )
- ecp_mpi_load( &grp->A, a, alen );
- ecp_mpi_load( &grp->B, b, blen );
- ecp_mpi_load( &grp->N, n, nlen );
- ecp_mpi_load( &grp->G.X, gx, gxlen );
- ecp_mpi_load( &grp->G.Y, gy, gylen );
- ecp_mpi_set1( &grp->G.Z );
- grp->pbits = mbedtls_mpi_bitlen( &grp->P );
- grp->nbits = mbedtls_mpi_bitlen( &grp->N );
- grp->h = 1;
- return( 0 );
- }
- #if defined(MBEDTLS_ECP_NIST_OPTIM)
- /* Forward declarations */
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- static int ecp_mod_p192( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
- static int ecp_mod_p224( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- static int ecp_mod_p256( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- static int ecp_mod_p384( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- static int ecp_mod_p521( mbedtls_mpi * );
- #endif
- #define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
- #else
- #define NIST_MODP( P )
- #endif /* MBEDTLS_ECP_NIST_OPTIM */
- /* Additional forward declarations */
- #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- static int ecp_mod_p255( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
- static int ecp_mod_p192k1( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
- static int ecp_mod_p224k1( mbedtls_mpi * );
- #endif
- #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- static int ecp_mod_p256k1( mbedtls_mpi * );
- #endif
- #define LOAD_GROUP_A( G ) ecp_group_load( grp, \
- G ## _p, sizeof( G ## _p ), \
- G ## _a, sizeof( G ## _a ), \
- G ## _b, sizeof( G ## _b ), \
- G ## _gx, sizeof( G ## _gx ), \
- G ## _gy, sizeof( G ## _gy ), \
- G ## _n, sizeof( G ## _n ) )
- #define LOAD_GROUP( G ) ecp_group_load( grp, \
- G ## _p, sizeof( G ## _p ), \
- NULL, 0, \
- G ## _b, sizeof( G ## _b ), \
- G ## _gx, sizeof( G ## _gx ), \
- G ## _gy, sizeof( G ## _gy ), \
- G ## _n, sizeof( G ## _n ) )
- #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- /*
- * Specialized function for creating the Curve25519 group
- */
- static int ecp_use_curve25519( mbedtls_ecp_group *grp )
- {
- int ret;
- /* Actually ( A + 2 ) / 4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) );
- /* P = 2^255 - 19 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
- grp->pbits = mbedtls_mpi_bitlen( &grp->P );
- /* Y intentionaly not set, since we use x/z coordinates.
- * This is used as a marker to identify Montgomery curves! */
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
- mbedtls_mpi_free( &grp->G.Y );
- /* Actually, the required msb for private keys */
- grp->nbits = 254;
- cleanup:
- if( ret != 0 )
- mbedtls_ecp_group_free( grp );
- return( ret );
- }
- #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
- /*
- * Set a group using well-known domain parameters
- */
- int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
- {
- mbedtls_ecp_group_free( grp );
- grp->id = id;
- switch( id )
- {
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- case MBEDTLS_ECP_DP_SECP192R1:
- NIST_MODP( p192 );
- return( LOAD_GROUP( secp192r1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
- case MBEDTLS_ECP_DP_SECP224R1:
- NIST_MODP( p224 );
- return( LOAD_GROUP( secp224r1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- case MBEDTLS_ECP_DP_SECP256R1:
- NIST_MODP( p256 );
- return( LOAD_GROUP( secp256r1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- case MBEDTLS_ECP_DP_SECP384R1:
- NIST_MODP( p384 );
- return( LOAD_GROUP( secp384r1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- case MBEDTLS_ECP_DP_SECP521R1:
- NIST_MODP( p521 );
- return( LOAD_GROUP( secp521r1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
- case MBEDTLS_ECP_DP_SECP192K1:
- grp->modp = ecp_mod_p192k1;
- return( LOAD_GROUP_A( secp192k1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
- case MBEDTLS_ECP_DP_SECP224K1:
- grp->modp = ecp_mod_p224k1;
- return( LOAD_GROUP_A( secp224k1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- case MBEDTLS_ECP_DP_SECP256K1:
- grp->modp = ecp_mod_p256k1;
- return( LOAD_GROUP_A( secp256k1 ) );
- #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
- case MBEDTLS_ECP_DP_BP256R1:
- return( LOAD_GROUP_A( brainpoolP256r1 ) );
- #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
- case MBEDTLS_ECP_DP_BP384R1:
- return( LOAD_GROUP_A( brainpoolP384r1 ) );
- #endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
- case MBEDTLS_ECP_DP_BP512R1:
- return( LOAD_GROUP_A( brainpoolP512r1 ) );
- #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- case MBEDTLS_ECP_DP_CURVE25519:
- grp->modp = ecp_mod_p255;
- return( ecp_use_curve25519( grp ) );
- #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
- default:
- mbedtls_ecp_group_free( grp );
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
- }
- }
- #if defined(MBEDTLS_ECP_NIST_OPTIM)
- /*
- * Fast reduction modulo the primes used by the NIST curves.
- *
- * These functions are critical for speed, but not needed for correct
- * operations. So, we make the choice to heavily rely on the internals of our
- * bignum library, which creates a tight coupling between these functions and
- * our MPI implementation. However, the coupling between the ECP module and
- * MPI remains loose, since these functions can be deactivated at will.
- */
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- /*
- * Compared to the way things are presented in FIPS 186-3 D.2,
- * we proceed in columns, from right (least significant chunk) to left,
- * adding chunks to N in place, and keeping a carry for the next chunk.
- * This avoids moving things around in memory, and uselessly adding zeros,
- * compared to the more straightforward, line-oriented approach.
- *
- * For this prime we need to handle data in chunks of 64 bits.
- * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
- * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it.
- */
- /* Add 64-bit chunks (dst += src) and update carry */
- static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
- {
- unsigned char i;
- mbedtls_mpi_uint c = 0;
- for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
- {
- *dst += c; c = ( *dst < c );
- *dst += *src; c += ( *dst < *src );
- }
- *carry += c;
- }
- /* Add carry to a 64-bit chunk and update carry */
- static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
- {
- unsigned char i;
- for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
- {
- *dst += *carry;
- *carry = ( *dst < *carry );
- }
- }
- #define WIDTH 8 / sizeof( mbedtls_mpi_uint )
- #define A( i ) N->p + i * WIDTH
- #define ADD( i ) add64( p, A( i ), &c )
- #define NEXT p += WIDTH; carry64( p, &c )
- #define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
- /*
- * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
- */
- static int ecp_mod_p192( mbedtls_mpi *N )
- {
- int ret;
- mbedtls_mpi_uint c = 0;
- mbedtls_mpi_uint *p, *end;
- /* Make sure we have enough blocks so that A(5) is legal */
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
- p = N->p;
- end = p + N->n;
- ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
- ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
- ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
- cleanup:
- return( ret );
- }
- #undef WIDTH
- #undef A
- #undef ADD
- #undef NEXT
- #undef LAST
- #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- /*
- * The reader is advised to first understand ecp_mod_p192() since the same
- * general structure is used here, but with additional complications:
- * (1) chunks of 32 bits, and (2) subtractions.
- */
- /*
- * For these primes, we need to handle data in chunks of 32 bits.
- * This makes it more complicated if we use 64 bits limbs in MPI,
- * which prevents us from using a uniform access method as for p192.
- *
- * So, we define a mini abstraction layer to access 32 bit chunks,
- * load them in 'cur' for work, and store them back from 'cur' when done.
- *
- * While at it, also define the size of N in terms of 32-bit chunks.
- */
- #define LOAD32 cur = A( i );
- #if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
- #define MAX32 N->n
- #define A( j ) N->p[j]
- #define STORE32 N->p[i] = cur;
- #else /* 64-bit */
- #define MAX32 N->n * 2
- #define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] )
- #define STORE32 \
- if( i % 2 ) { \
- N->p[i/2] &= 0x00000000FFFFFFFF; \
- N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
- } else { \
- N->p[i/2] &= 0xFFFFFFFF00000000; \
- N->p[i/2] |= (mbedtls_mpi_uint) cur; \
- }
- #endif /* sizeof( mbedtls_mpi_uint ) */
- /*
- * Helpers for addition and subtraction of chunks, with signed carry.
- */
- static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
- {
- *dst += src;
- *carry += ( *dst < src );
- }
- static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
- {
- *carry -= ( *dst < src );
- *dst -= src;
- }
- #define ADD( j ) add32( &cur, A( j ), &c );
- #define SUB( j ) sub32( &cur, A( j ), &c );
- /*
- * Helpers for the main 'loop'
- * (see fix_negative for the motivation of C)
- */
- #define INIT( b ) \
- int ret; \
- signed char c = 0, cc; \
- uint32_t cur; \
- size_t i = 0, bits = b; \
- mbedtls_mpi C; \
- mbedtls_mpi_uint Cp[ b / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
- \
- C.s = 1; \
- C.n = b / 8 / sizeof( mbedtls_mpi_uint) + 1; \
- C.p = Cp; \
- memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
- \
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, b * 2 / 8 / sizeof( mbedtls_mpi_uint ) ) ); \
- LOAD32;
- #define NEXT \
- STORE32; i++; LOAD32; \
- cc = c; c = 0; \
- if( cc < 0 ) \
- sub32( &cur, -cc, &c ); \
- else \
- add32( &cur, cc, &c ); \
- #define LAST \
- STORE32; i++; \
- cur = c > 0 ? c : 0; STORE32; \
- cur = 0; while( ++i < MAX32 ) { STORE32; } \
- if( c < 0 ) fix_negative( N, c, &C, bits );
- /*
- * If the result is negative, we get it in the form
- * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits'
- */
- static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
- {
- int ret;
- /* C = - c * 2^(bits + 32) */
- #if !defined(MBEDTLS_HAVE_INT64)
- ((void) bits);
- #else
- if( bits == 224 )
- C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
- else
- #endif
- C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
- /* N = - ( C - N ) */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
- N->s = -1;
- cleanup:
- return( ret );
- }
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
- /*
- * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
- */
- static int ecp_mod_p224( mbedtls_mpi *N )
- {
- INIT( 224 );
- SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
- SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
- SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
- SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
- SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
- SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
- SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- /*
- * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
- */
- static int ecp_mod_p256( mbedtls_mpi *N )
- {
- INIT( 256 );
- ADD( 8 ); ADD( 9 );
- SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
- ADD( 9 ); ADD( 10 );
- SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
- ADD( 10 ); ADD( 11 );
- SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
- ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
- SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
- ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
- SUB( 9 ); SUB( 10 ); NEXT; // A4
- ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
- SUB( 10 ); SUB( 11 ); NEXT; // A5
- ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
- SUB( 8 ); SUB( 9 ); NEXT; // A6
- ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
- SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- /*
- * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
- */
- static int ecp_mod_p384( mbedtls_mpi *N )
- {
- INIT( 384 );
- ADD( 12 ); ADD( 21 ); ADD( 20 );
- SUB( 23 ); NEXT; // A0
- ADD( 13 ); ADD( 22 ); ADD( 23 );
- SUB( 12 ); SUB( 20 ); NEXT; // A2
- ADD( 14 ); ADD( 23 );
- SUB( 13 ); SUB( 21 ); NEXT; // A2
- ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
- SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
- ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
- SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
- ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
- SUB( 16 ); NEXT; // A5
- ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
- SUB( 17 ); NEXT; // A6
- ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
- SUB( 18 ); NEXT; // A7
- ADD( 20 ); ADD( 17 ); ADD( 16 );
- SUB( 19 ); NEXT; // A8
- ADD( 21 ); ADD( 18 ); ADD( 17 );
- SUB( 20 ); NEXT; // A9
- ADD( 22 ); ADD( 19 ); ADD( 18 );
- SUB( 21 ); NEXT; // A10
- ADD( 23 ); ADD( 20 ); ADD( 19 );
- SUB( 22 ); LAST; // A11
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
- #undef A
- #undef LOAD32
- #undef STORE32
- #undef MAX32
- #undef INIT
- #undef NEXT
- #undef LAST
- #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
- MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
- MBEDTLS_ECP_DP_SECP384R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- /*
- * Here we have an actual Mersenne prime, so things are more straightforward.
- * However, chunks are aligned on a 'weird' boundary (521 bits).
- */
- /* Size of p521 in terms of mbedtls_mpi_uint */
- #define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
- /* Bits to keep in the most significant mbedtls_mpi_uint */
- #define P521_MASK 0x01FF
- /*
- * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
- * Write N as A1 + 2^521 A0, return A0 + A1
- */
- static int ecp_mod_p521( mbedtls_mpi *N )
- {
- int ret;
- size_t i;
- mbedtls_mpi M;
- mbedtls_mpi_uint Mp[P521_WIDTH + 1];
- /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
- * we need to hold bits 513 to 1056, which is 34 limbs, that is
- * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
- if( N->n < P521_WIDTH )
- return( 0 );
- /* M = A1 */
- M.s = 1;
- M.n = N->n - ( P521_WIDTH - 1 );
- if( M.n > P521_WIDTH + 1 )
- M.n = P521_WIDTH + 1;
- M.p = Mp;
- memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
- /* N = A0 */
- N->p[P521_WIDTH - 1] &= P521_MASK;
- for( i = P521_WIDTH; i < N->n; i++ )
- N->p[i] = 0;
- /* N = A0 + A1 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
- cleanup:
- return( ret );
- }
- #undef P521_WIDTH
- #undef P521_MASK
- #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
- #endif /* MBEDTLS_ECP_NIST_OPTIM */
- #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- /* Size of p255 in terms of mbedtls_mpi_uint */
- #define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
- /*
- * Fast quasi-reduction modulo p255 = 2^255 - 19
- * Write N as A0 + 2^255 A1, return A0 + 19 * A1
- */
- static int ecp_mod_p255( mbedtls_mpi *N )
- {
- int ret;
- size_t i;
- mbedtls_mpi M;
- mbedtls_mpi_uint Mp[P255_WIDTH + 2];
- if( N->n < P255_WIDTH )
- return( 0 );
- /* M = A1 */
- M.s = 1;
- M.n = N->n - ( P255_WIDTH - 1 );
- if( M.n > P255_WIDTH + 1 )
- M.n = P255_WIDTH + 1;
- M.p = Mp;
- memset( Mp, 0, sizeof Mp );
- memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
- M.n++; /* Make room for multiplication by 19 */
- /* N = A0 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
- for( i = P255_WIDTH; i < N->n; i++ )
- N->p[i] = 0;
- /* N = A0 + 19 * A1 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- /*
- * Fast quasi-reduction modulo P = 2^s - R,
- * with R about 33 bits, used by the Koblitz curves.
- *
- * Write N as A0 + 2^224 A1, return A0 + R * A1.
- * Actually do two passes, since R is big.
- */
- #define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
- #define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
- static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
- size_t adjust, size_t shift, mbedtls_mpi_uint mask )
- {
- int ret;
- size_t i;
- mbedtls_mpi M, R;
- mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R];
- if( N->n < p_limbs )
- return( 0 );
- /* Init R */
- R.s = 1;
- R.p = Rp;
- R.n = P_KOBLITZ_R;
- /* Common setup for M */
- M.s = 1;
- M.p = Mp;
- /* M = A1 */
- M.n = N->n - ( p_limbs - adjust );
- if( M.n > p_limbs + adjust )
- M.n = p_limbs + adjust;
- memset( Mp, 0, sizeof Mp );
- memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
- if( shift != 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
- M.n += R.n - adjust; /* Make room for multiplication by R */
- /* N = A0 */
- if( mask != 0 )
- N->p[p_limbs - 1] &= mask;
- for( i = p_limbs; i < N->n; i++ )
- N->p[i] = 0;
- /* N = A0 + R * A1 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
- /* Second pass */
- /* M = A1 */
- M.n = N->n - ( p_limbs - adjust );
- if( M.n > p_limbs + adjust )
- M.n = p_limbs + adjust;
- memset( Mp, 0, sizeof Mp );
- memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
- if( shift != 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
- M.n += R.n - adjust; /* Make room for multiplication by R */
- /* N = A0 */
- if( mask != 0 )
- N->p[p_limbs - 1] &= mask;
- for( i = p_limbs; i < N->n; i++ )
- N->p[i] = 0;
- /* N = A0 + R * A1 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
- cleanup:
- return( ret );
- }
- #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
- MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
- MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
- /*
- * Fast quasi-reduction modulo p192k1 = 2^192 - R,
- * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
- */
- static int ecp_mod_p192k1( mbedtls_mpi *N )
- {
- static mbedtls_mpi_uint Rp[] = {
- BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
- return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
- }
- #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
- /*
- * Fast quasi-reduction modulo p224k1 = 2^224 - R,
- * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
- */
- static int ecp_mod_p224k1( mbedtls_mpi *N )
- {
- static mbedtls_mpi_uint Rp[] = {
- BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
- #if defined(MBEDTLS_HAVE_INT64)
- return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
- #else
- return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
- #endif
- }
- #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- /*
- * Fast quasi-reduction modulo p256k1 = 2^256 - R,
- * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
- */
- static int ecp_mod_p256k1( mbedtls_mpi *N )
- {
- static mbedtls_mpi_uint Rp[] = {
- BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
- return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
- }
- #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
- /* Amalgamated Release Mappings */
- #undef ADD
- #endif /* MBEDTLS_ECP_C */
- /********* Start of file library/entropy.c ************/
- /*
- * Entropy accumulator implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ENTROPY_C)
- #include <string.h>
- #if defined(MBEDTLS_FS_IO)
- #include <stdio.h>
- #endif
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if defined(MBEDTLS_HAVEGE_C)
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void entropy_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
- void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
- {
- memset( ctx, 0, sizeof(mbedtls_entropy_context) );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
- mbedtls_sha512_starts( &ctx->accumulator, 0 );
- #else
- mbedtls_sha256_starts( &ctx->accumulator, 0 );
- #endif
- #if defined(MBEDTLS_HAVEGE_C)
- mbedtls_havege_init( &ctx->havege_data );
- #endif
- #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
- #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
- mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
- MBEDTLS_ENTROPY_MIN_PLATFORM,
- MBEDTLS_ENTROPY_SOURCE_STRONG );
- #endif
- #if defined(MBEDTLS_TIMING_C)
- mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
- MBEDTLS_ENTROPY_MIN_HARDCLOCK,
- MBEDTLS_ENTROPY_SOURCE_WEAK );
- #endif
- #if defined(MBEDTLS_HAVEGE_C)
- mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
- MBEDTLS_ENTROPY_MIN_HAVEGE,
- MBEDTLS_ENTROPY_SOURCE_STRONG );
- #endif
- #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
- mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
- MBEDTLS_ENTROPY_MIN_HARDWARE,
- MBEDTLS_ENTROPY_SOURCE_STRONG );
- #endif
- #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
- }
- void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
- {
- #if defined(MBEDTLS_HAVEGE_C)
- mbedtls_havege_free( &ctx->havege_data );
- #endif
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &ctx->mutex );
- #endif
- entropy_zeroize( ctx, sizeof( mbedtls_entropy_context ) );
- }
- int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
- mbedtls_entropy_f_source_ptr f_source, void *p_source,
- size_t threshold, int strong )
- {
- int index, ret = 0;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- index = ctx->source_count;
- if( index >= MBEDTLS_ENTROPY_MAX_SOURCES )
- {
- ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
- goto exit;
- }
- ctx->source[index].f_source = f_source;
- ctx->source[index].p_source = p_source;
- ctx->source[index].threshold = threshold;
- ctx->source[index].strong = strong;
- ctx->source_count++;
- exit:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- /*
- * Entropy accumulator update
- */
- static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id,
- const unsigned char *data, size_t len )
- {
- unsigned char header[2];
- unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
- size_t use_len = len;
- const unsigned char *p = data;
- if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
- {
- #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
- mbedtls_sha512( data, len, tmp, 0 );
- #else
- mbedtls_sha256( data, len, tmp, 0 );
- #endif
- p = tmp;
- use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
- }
- header[0] = source_id;
- header[1] = use_len & 0xFF;
- #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
- mbedtls_sha512_update( &ctx->accumulator, header, 2 );
- mbedtls_sha512_update( &ctx->accumulator, p, use_len );
- #else
- mbedtls_sha256_update( &ctx->accumulator, header, 2 );
- mbedtls_sha256_update( &ctx->accumulator, p, use_len );
- #endif
- return( 0 );
- }
- int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
- const unsigned char *data, size_t len )
- {
- int ret;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len );
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- /*
- * Run through the different sources to add entropy to our accumulator
- */
- static int entropy_gather_internal( mbedtls_entropy_context *ctx )
- {
- int ret, i, have_one_strong = 0;
- unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
- size_t olen;
- if( ctx->source_count == 0 )
- return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
- /*
- * Run through our entropy sources
- */
- for( i = 0; i < ctx->source_count; i++ )
- {
- if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
- have_one_strong = 1;
- olen = 0;
- if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
- buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
- {
- return( ret );
- }
- /*
- * Add if we actually gathered something
- */
- if( olen > 0 )
- {
- entropy_update( ctx, (unsigned char) i, buf, olen );
- ctx->source[i].size += olen;
- }
- }
- if( have_one_strong == 0 )
- return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE );
- return( 0 );
- }
- /*
- * Thread-safe wrapper for entropy_gather_internal()
- */
- int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
- {
- int ret;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- ret = entropy_gather_internal( ctx );
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
- {
- int ret, count = 0, i, done;
- mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
- unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
- if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- /*
- * Always gather extra entropy before a call
- */
- do
- {
- if( count++ > ENTROPY_MAX_LOOP )
- {
- ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
- goto exit;
- }
- if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
- goto exit;
- done = 1;
- for( i = 0; i < ctx->source_count; i++ )
- if( ctx->source[i].size < ctx->source[i].threshold )
- done = 0;
- }
- while( ! done );
- memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
- #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
- mbedtls_sha512_finish( &ctx->accumulator, buf );
- /*
- * Reset accumulator and counters and recycle existing entropy
- */
- memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) );
- mbedtls_sha512_starts( &ctx->accumulator, 0 );
- mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
- /*
- * Perform second SHA-512 on entropy
- */
- mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
- #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
- mbedtls_sha256_finish( &ctx->accumulator, buf );
- /*
- * Reset accumulator and counters and recycle existing entropy
- */
- memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) );
- mbedtls_sha256_starts( &ctx->accumulator, 0 );
- mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
- /*
- * Perform second SHA-256 on entropy
- */
- mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
- #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
- for( i = 0; i < ctx->source_count; i++ )
- ctx->source[i].size = 0;
- memcpy( output, buf, len );
- ret = 0;
- exit:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- #if defined(MBEDTLS_FS_IO)
- int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
- {
- int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
- FILE *f;
- unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
- if( ( f = fopen( path, "wb" ) ) == NULL )
- return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
- if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
- goto exit;
- if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
- {
- ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
- goto exit;
- }
- ret = 0;
- exit:
- fclose( f );
- return( ret );
- }
- int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
- {
- FILE *f;
- size_t n;
- unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
- fseek( f, 0, SEEK_END );
- n = (size_t) ftell( f );
- fseek( f, 0, SEEK_SET );
- if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE )
- n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
- if( fread( buf, 1, n, f ) != n )
- {
- fclose( f );
- return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
- }
- fclose( f );
- mbedtls_entropy_update_manual( ctx, buf, n );
- return( mbedtls_entropy_write_seed_file( ctx, path ) );
- }
- #endif /* MBEDTLS_FS_IO */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Dummy source function
- */
- static int entropy_dummy_source( void *data, unsigned char *output,
- size_t len, size_t *olen )
- {
- ((void) data);
- memset( output, 0x2a, len );
- *olen = len;
- return( 0 );
- }
- /*
- * The actual entropy quality is hard to test, but we can at least
- * test that the functions don't cause errors and write the correct
- * amount of data to buffers.
- */
- int mbedtls_entropy_self_test( int verbose )
- {
- int ret = 0;
- mbedtls_entropy_context ctx;
- unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
- unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
- size_t i, j;
- if( verbose != 0 )
- mbedtls_printf( " ENTROPY test: " );
- mbedtls_entropy_init( &ctx );
- /* First do a gather to make sure we have default sources */
- if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 )
- goto cleanup;
- ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16,
- MBEDTLS_ENTROPY_SOURCE_WEAK );
- if( ret != 0 )
- goto cleanup;
- if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
- goto cleanup;
- /*
- * To test that mbedtls_entropy_func writes correct number of bytes:
- * - use the whole buffer and rely on ASan to detect overruns
- * - collect entropy 8 times and OR the result in an accumulator:
- * any byte should then be 0 with probably 2^(-64), so requiring
- * each of the 32 or 64 bytes to be non-zero has a false failure rate
- * of at most 2^(-58) which is acceptable.
- */
- for( i = 0; i < 8; i++ )
- {
- if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
- goto cleanup;
- for( j = 0; j < sizeof( buf ); j++ )
- acc[j] |= buf[j];
- }
- for( j = 0; j < sizeof( buf ); j++ )
- {
- if( acc[j] == 0 )
- {
- ret = 1;
- goto cleanup;
- }
- }
- cleanup:
- mbedtls_entropy_free( &ctx );
- if( verbose != 0 )
- {
- if( ret != 0 )
- mbedtls_printf( "failed\n" );
- else
- mbedtls_printf( "passed\n" );
- mbedtls_printf( "\n" );
- }
- return( ret != 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_ENTROPY_C */
- /********* Start of file library/entropy_poll.c ************/
- /*
- * Platform-specific and custom entropy polling functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ENTROPY_C)
- #if defined(MBEDTLS_TIMING_C)
- #include <string.h>
- #endif
- #if defined(MBEDTLS_HAVEGE_C)
- #endif
- #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- #if !defined(_WIN32_WINNT)
- #define _WIN32_WINNT 0x0400
- #endif
- #include <windows.h>
- #include <wincrypt.h>
- int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
- size_t *olen )
- {
- HCRYPTPROV provider;
- ((void) data);
- *olen = 0;
- if( CryptAcquireContext( &provider, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
- {
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- }
- if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- CryptReleaseContext( provider, 0 );
- *olen = len;
- return( 0 );
- }
- #else /* _WIN32 && !EFIX64 && !EFI32 */
- /*
- * Test for Linux getrandom() support.
- * Since there is no wrapper in the libc yet, use the generic syscall wrapper
- * available in GNU libc and compatible libc's (eg uClibc).
- */
- #if defined(__linux__) && defined(__GLIBC__)
- #include <unistd.h>
- #include <sys/syscall.h>
- #if defined(SYS_getrandom)
- #define HAVE_GETRANDOM
- static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
- {
- /* MemSan cannot understand that the syscall writes to the buffer */
- #if defined(__has_feature)
- #if __has_feature(memory_sanitizer)
- memset( buf, 0, buflen );
- #endif
- #endif
- return( syscall( SYS_getrandom, buf, buflen, flags ) );
- }
- #include <sys/utsname.h>
- /* Check if version is at least 3.17.0 */
- static int check_version_3_17_plus( void )
- {
- int minor;
- struct utsname un;
- const char *ver;
- /* Get version information */
- uname(&un);
- ver = un.release;
- /* Check major version; assume a single digit */
- if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
- return( -1 );
- if( ver[0] - '0' > 3 )
- return( 0 );
- /* Ok, so now we know major == 3, check minor.
- * Assume 1 or 2 digits. */
- if( ver[2] < '0' || ver[2] > '9' )
- return( -1 );
- minor = ver[2] - '0';
- if( ver[3] >= '0' && ver[3] <= '9' )
- minor = 10 * minor + ver[3] - '0';
- else if( ver [3] != '.' )
- return( -1 );
- if( minor < 17 )
- return( -1 );
- return( 0 );
- }
- static int has_getrandom = -1;
- #endif /* SYS_getrandom */
- #endif /* __linux__ */
- #include <stdio.h>
- int mbedtls_platform_entropy_poll( void *data,
- unsigned char *output, size_t len, size_t *olen )
- {
- FILE *file;
- size_t read_len;
- ((void) data);
- #if defined(HAVE_GETRANDOM)
- if( has_getrandom == -1 )
- has_getrandom = ( check_version_3_17_plus() == 0 );
- if( has_getrandom )
- {
- int ret;
- if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- *olen = ret;
- return( 0 );
- }
- #endif /* HAVE_GETRANDOM */
- *olen = 0;
- file = fopen( "/dev/urandom", "rb" );
- if( file == NULL )
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- read_len = fread( output, 1, len, file );
- if( read_len != len )
- {
- fclose( file );
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- }
- fclose( file );
- *olen = len;
- return( 0 );
- }
- #endif /* _WIN32 && !EFIX64 && !EFI32 */
- #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
- #if defined(MBEDTLS_TIMING_C)
- int mbedtls_hardclock_poll( void *data,
- unsigned char *output, size_t len, size_t *olen )
- {
- unsigned long timer = mbedtls_timing_hardclock();
- ((void) data);
- *olen = 0;
- if( len < sizeof(unsigned long) )
- return( 0 );
- memcpy( output, &timer, sizeof(unsigned long) );
- *olen = sizeof(unsigned long);
- return( 0 );
- }
- #endif /* MBEDTLS_TIMING_C */
- #if defined(MBEDTLS_HAVEGE_C)
- int mbedtls_havege_poll( void *data,
- unsigned char *output, size_t len, size_t *olen )
- {
- mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
- *olen = 0;
- if( mbedtls_havege_random( hs, output, len ) != 0 )
- return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
- *olen = len;
- return( 0 );
- }
- #endif /* MBEDTLS_HAVEGE_C */
- #endif /* MBEDTLS_ENTROPY_C */
- /********* Start of file library/error.c ************/
- /*
- * Error message information
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
- #include <string.h>
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #define mbedtls_snprintf snprintf
- #endif
- #if defined(MBEDTLS_ERROR_C)
- #include <stdio.h>
- #if defined(MBEDTLS_AES_C)
- #endif
- #if defined(MBEDTLS_BASE64_C)
- #endif
- #if defined(MBEDTLS_BIGNUM_C)
- #endif
- #if defined(MBEDTLS_BLOWFISH_C)
- #endif
- #if defined(MBEDTLS_CAMELLIA_C)
- #endif
- #if defined(MBEDTLS_CCM_C)
- #endif
- #if defined(MBEDTLS_CIPHER_C)
- #endif
- #if defined(MBEDTLS_CTR_DRBG_C)
- #endif
- #if defined(MBEDTLS_DES_C)
- #endif
- #if defined(MBEDTLS_DHM_C)
- #endif
- #if defined(MBEDTLS_ECP_C)
- #endif
- #if defined(MBEDTLS_ENTROPY_C)
- #endif
- #if defined(MBEDTLS_GCM_C)
- #endif
- #if defined(MBEDTLS_HMAC_DRBG_C)
- #endif
- #if defined(MBEDTLS_MD_C)
- #endif
- #if defined(MBEDTLS_NET_C)
- #endif
- #if defined(MBEDTLS_OID_C)
- #endif
- #if defined(MBEDTLS_PADLOCK_C)
- #endif
- #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
- #endif
- #if defined(MBEDTLS_PK_C)
- #endif
- #if defined(MBEDTLS_PKCS12_C)
- #endif
- #if defined(MBEDTLS_PKCS5_C)
- #endif
- #if defined(MBEDTLS_RSA_C)
- #endif
- #if defined(MBEDTLS_SSL_TLS_C)
- #endif
- #if defined(MBEDTLS_THREADING_C)
- #endif
- #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
- #endif
- #if defined(MBEDTLS_XTEA_C)
- #endif
- void mbedtls_strerror( int ret, char *buf, size_t buflen )
- {
- size_t len;
- int use_ret;
- if( buflen == 0 )
- return;
- memset( buf, 0x00, buflen );
- if( ret < 0 )
- ret = -ret;
- if( ret & 0xFF80 )
- {
- use_ret = ret & 0xFF80;
- // High level error codes
- //
- // BEGIN generated code
- #if defined(MBEDTLS_CIPHER_C)
- if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
- #endif /* MBEDTLS_CIPHER_C */
- #if defined(MBEDTLS_DHM_C)
- if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
- if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "DHM - Read/write of file failed" );
- #endif /* MBEDTLS_DHM_C */
- #if defined(MBEDTLS_ECP_C)
- if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
- if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" );
- if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
- if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
- mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
- if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" );
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_MD_C)
- if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
- #endif /* MBEDTLS_MD_C */
- #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
- if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
- mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
- if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
- if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
- mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
- if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
- mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
- if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
- if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
- if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
- if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
- #endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
- #if defined(MBEDTLS_PK_C)
- if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
- if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
- mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
- if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
- if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
- mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
- if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
- if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
- mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
- mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
- mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
- if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" );
- #endif /* MBEDTLS_PK_C */
- #if defined(MBEDTLS_PKCS12_C)
- if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
- #endif /* MBEDTLS_PKCS12_C */
- #if defined(MBEDTLS_PKCS5_C)
- if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
- #endif /* MBEDTLS_PKCS5_C */
- #if defined(MBEDTLS_RSA_C)
- if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
- mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
- if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
- if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the library's validity check" );
- if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
- mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
- if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_SSL_TLS_C)
- if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
- mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
- mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
- mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
- mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
- mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
- mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
- mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
- mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
- if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
- {
- mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
- return;
- }
- if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
- mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
- mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
- if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
- mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
- mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
- mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
- mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
- mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
- mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
- mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
- if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
- mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
- mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) )
- mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" );
- #endif /* MBEDTLS_SSL_TLS_C */
- #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
- if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
- mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
- mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
- mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
- mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
- mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
- mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
- mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
- mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
- mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
- mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
- if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
- if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
- mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
- if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
- #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
- // END generated code
- if( strlen( buf ) == 0 )
- mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
- }
- use_ret = ret & ~0xFF80;
- if( use_ret == 0 )
- return;
- // If high level code is present, make a concatenation between both
- // error strings.
- //
- len = strlen( buf );
- if( len > 0 )
- {
- if( buflen - len < 5 )
- return;
- mbedtls_snprintf( buf + len, buflen - len, " : " );
- buf += len + 3;
- buflen -= len + 3;
- }
- // Low level error codes
- //
- // BEGIN generated code
- #if defined(MBEDTLS_AES_C)
- if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
- if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_ASN1_PARSE_C)
- if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
- mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
- #endif /* MBEDTLS_ASN1_PARSE_C */
- #if defined(MBEDTLS_BASE64_C)
- if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
- if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
- mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
- #endif /* MBEDTLS_BASE64_C */
- #if defined(MBEDTLS_BIGNUM_C)
- if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
- if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
- if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
- if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
- if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
- if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
- if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
- #endif /* MBEDTLS_BIGNUM_C */
- #if defined(MBEDTLS_BLOWFISH_C)
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
- #endif /* MBEDTLS_BLOWFISH_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_CCM_C)
- if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
- mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
- #endif /* MBEDTLS_CCM_C */
- #if defined(MBEDTLS_CTR_DRBG_C)
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" );
- #endif /* MBEDTLS_CTR_DRBG_C */
- #if defined(MBEDTLS_DES_C)
- if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ENTROPY_C)
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
- #endif /* MBEDTLS_ENTROPY_C */
- #if defined(MBEDTLS_GCM_C)
- if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
- if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
- mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_HMAC_DRBG_C)
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
- #endif /* MBEDTLS_HMAC_DRBG_C */
- #if defined(MBEDTLS_NET_C)
- if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
- if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
- if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
- if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
- mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
- if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
- mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
- if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
- if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
- mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
- #endif /* MBEDTLS_NET_C */
- #if defined(MBEDTLS_OID_C)
- if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
- mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
- if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
- #endif /* MBEDTLS_OID_C */
- #if defined(MBEDTLS_PADLOCK_C)
- if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
- mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
- #endif /* MBEDTLS_PADLOCK_C */
- #if defined(MBEDTLS_THREADING_C)
- if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
- mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
- #endif /* MBEDTLS_THREADING_C */
- #if defined(MBEDTLS_XTEA_C)
- if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
- #endif /* MBEDTLS_XTEA_C */
- // END generated code
- if( strlen( buf ) != 0 )
- return;
- mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
- }
- #else /* MBEDTLS_ERROR_C */
- #if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
- /*
- * Provide an non-function in case MBEDTLS_ERROR_C is not defined
- */
- void mbedtls_strerror( int ret, char *buf, size_t buflen )
- {
- ((void) ret);
- if( buflen > 0 )
- buf[0] = '\0';
- }
- #endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
- #endif /* MBEDTLS_ERROR_C */
- /********* Start of file library/gcm.c ************/
- /*
- * NIST SP800-38D compliant GCM implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
- *
- * See also:
- * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
- *
- * We use the algorithm described as Shoup's method with 4-bit tables in
- * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_GCM_C)
- #include <string.h>
- #if defined(MBEDTLS_AESNI_C)
- #endif
- #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- }
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- }
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void gcm_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Initialize a context
- */
- void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
- }
- /*
- * Precompute small multiples of H, that is set
- * HH[i] || HL[i] = H times i,
- * where i is seen as a field element as in [MGV], ie high-order bits
- * correspond to low powers of P. The result is stored in the same way, that
- * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
- * corresponds to P^127.
- */
- static int gcm_gen_table( mbedtls_gcm_context *ctx )
- {
- int ret, i, j;
- uint64_t hi, lo;
- uint64_t vl, vh;
- unsigned char h[16];
- size_t olen = 0;
- memset( h, 0, 16 );
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
- return( ret );
- /* pack h as two 64-bits ints, big-endian */
- GET_UINT32_BE( hi, h, 0 );
- GET_UINT32_BE( lo, h, 4 );
- vh = (uint64_t) hi << 32 | lo;
- GET_UINT32_BE( hi, h, 8 );
- GET_UINT32_BE( lo, h, 12 );
- vl = (uint64_t) hi << 32 | lo;
- /* 8 = 1000 corresponds to 1 in GF(2^128) */
- ctx->HL[8] = vl;
- ctx->HH[8] = vh;
- #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- /* With CLMUL support, we need only h, not the rest of the table */
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
- return( 0 );
- #endif
- /* 0 corresponds to 0 in GF(2^128) */
- ctx->HH[0] = 0;
- ctx->HL[0] = 0;
- for( i = 4; i > 0; i >>= 1 )
- {
- uint32_t T = ( vl & 1 ) * 0xe1000000U;
- vl = ( vh << 63 ) | ( vl >> 1 );
- vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
- ctx->HL[i] = vl;
- ctx->HH[i] = vh;
- }
- for( i = 2; i <= 8; i *= 2 )
- {
- uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
- vh = *HiH;
- vl = *HiL;
- for( j = 1; j < i; j++ )
- {
- HiH[j] = vh ^ ctx->HH[j];
- HiL[j] = vl ^ ctx->HL[j];
- }
- }
- return( 0 );
- }
- int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
- mbedtls_cipher_id_t cipher,
- const unsigned char *key,
- unsigned int keybits )
- {
- int ret;
- const mbedtls_cipher_info_t *cipher_info;
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- if( cipher_info->block_size != 16 )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- mbedtls_cipher_free( &ctx->cipher_ctx );
- if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
- MBEDTLS_ENCRYPT ) ) != 0 )
- {
- return( ret );
- }
- if( ( ret = gcm_gen_table( ctx ) ) != 0 )
- return( ret );
- return( 0 );
- }
- /*
- * Shoup's method for multiplication use this table with
- * last4[x] = x times P^128
- * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
- */
- static const uint64_t last4[16] =
- {
- 0x0000, 0x1c20, 0x3840, 0x2460,
- 0x7080, 0x6ca0, 0x48c0, 0x54e0,
- 0xe100, 0xfd20, 0xd940, 0xc560,
- 0x9180, 0x8da0, 0xa9c0, 0xb5e0
- };
- /*
- * Sets output to x times H using the precomputed tables.
- * x and output are seen as elements of GF(2^128) as in [MGV].
- */
- static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
- unsigned char output[16] )
- {
- int i = 0;
- unsigned char lo, hi, rem;
- uint64_t zh, zl;
- #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
- unsigned char h[16];
- PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
- PUT_UINT32_BE( ctx->HH[8], h, 4 );
- PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
- PUT_UINT32_BE( ctx->HL[8], h, 12 );
- mbedtls_aesni_gcm_mult( output, x, h );
- return;
- }
- #endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
- lo = x[15] & 0xf;
- zh = ctx->HH[lo];
- zl = ctx->HL[lo];
- for( i = 15; i >= 0; i-- )
- {
- lo = x[i] & 0xf;
- hi = x[i] >> 4;
- if( i != 15 )
- {
- rem = (unsigned char) zl & 0xf;
- zl = ( zh << 60 ) | ( zl >> 4 );
- zh = ( zh >> 4 );
- zh ^= (uint64_t) last4[rem] << 48;
- zh ^= ctx->HH[lo];
- zl ^= ctx->HL[lo];
- }
- rem = (unsigned char) zl & 0xf;
- zl = ( zh << 60 ) | ( zl >> 4 );
- zh = ( zh >> 4 );
- zh ^= (uint64_t) last4[rem] << 48;
- zh ^= ctx->HH[hi];
- zl ^= ctx->HL[hi];
- }
- PUT_UINT32_BE( zh >> 32, output, 0 );
- PUT_UINT32_BE( zh, output, 4 );
- PUT_UINT32_BE( zl >> 32, output, 8 );
- PUT_UINT32_BE( zl, output, 12 );
- }
- int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
- int mode,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len )
- {
- int ret;
- unsigned char work_buf[16];
- size_t i;
- const unsigned char *p;
- size_t use_len, olen = 0;
- /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
- if( ( (uint64_t) iv_len ) >> 61 != 0 ||
- ( (uint64_t) add_len ) >> 61 != 0 )
- {
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- }
- memset( ctx->y, 0x00, sizeof(ctx->y) );
- memset( ctx->buf, 0x00, sizeof(ctx->buf) );
- ctx->mode = mode;
- ctx->len = 0;
- ctx->add_len = 0;
- if( iv_len == 12 )
- {
- memcpy( ctx->y, iv, iv_len );
- ctx->y[15] = 1;
- }
- else
- {
- memset( work_buf, 0x00, 16 );
- PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
- p = iv;
- while( iv_len > 0 )
- {
- use_len = ( iv_len < 16 ) ? iv_len : 16;
- for( i = 0; i < use_len; i++ )
- ctx->y[i] ^= p[i];
- gcm_mult( ctx, ctx->y, ctx->y );
- iv_len -= use_len;
- p += use_len;
- }
- for( i = 0; i < 16; i++ )
- ctx->y[i] ^= work_buf[i];
- gcm_mult( ctx, ctx->y, ctx->y );
- }
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
- &olen ) ) != 0 )
- {
- return( ret );
- }
- ctx->add_len = add_len;
- p = add;
- while( add_len > 0 )
- {
- use_len = ( add_len < 16 ) ? add_len : 16;
- for( i = 0; i < use_len; i++ )
- ctx->buf[i] ^= p[i];
- gcm_mult( ctx, ctx->buf, ctx->buf );
- add_len -= use_len;
- p += use_len;
- }
- return( 0 );
- }
- int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
- size_t length,
- const unsigned char *input,
- unsigned char *output )
- {
- int ret;
- unsigned char ectr[16];
- size_t i;
- const unsigned char *p;
- unsigned char *out_p = output;
- size_t use_len, olen = 0;
- if( output > input && (size_t) ( output - input ) < length )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
- * Also check for possible overflow */
- if( ctx->len + length < ctx->len ||
- (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
- {
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- }
- ctx->len += length;
- p = input;
- while( length > 0 )
- {
- use_len = ( length < 16 ) ? length : 16;
- for( i = 16; i > 12; i-- )
- if( ++ctx->y[i - 1] != 0 )
- break;
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
- &olen ) ) != 0 )
- {
- return( ret );
- }
- for( i = 0; i < use_len; i++ )
- {
- if( ctx->mode == MBEDTLS_GCM_DECRYPT )
- ctx->buf[i] ^= p[i];
- out_p[i] = ectr[i] ^ p[i];
- if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
- ctx->buf[i] ^= out_p[i];
- }
- gcm_mult( ctx, ctx->buf, ctx->buf );
- length -= use_len;
- p += use_len;
- out_p += use_len;
- }
- return( 0 );
- }
- int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
- unsigned char *tag,
- size_t tag_len )
- {
- unsigned char work_buf[16];
- size_t i;
- uint64_t orig_len = ctx->len * 8;
- uint64_t orig_add_len = ctx->add_len * 8;
- if( tag_len > 16 || tag_len < 4 )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- if( tag_len != 0 )
- memcpy( tag, ctx->base_ectr, tag_len );
- if( orig_len || orig_add_len )
- {
- memset( work_buf, 0x00, 16 );
- PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
- PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
- PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
- PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
- for( i = 0; i < 16; i++ )
- ctx->buf[i] ^= work_buf[i];
- gcm_mult( ctx, ctx->buf, ctx->buf );
- for( i = 0; i < tag_len; i++ )
- tag[i] ^= ctx->buf[i];
- }
- return( 0 );
- }
- int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
- int mode,
- size_t length,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len,
- const unsigned char *input,
- unsigned char *output,
- size_t tag_len,
- unsigned char *tag )
- {
- int ret;
- if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
- return( ret );
- return( 0 );
- }
- int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
- size_t length,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len,
- const unsigned char *tag,
- size_t tag_len,
- const unsigned char *input,
- unsigned char *output )
- {
- int ret;
- unsigned char check_tag[16];
- size_t i;
- int diff;
- if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
- iv, iv_len, add, add_len,
- input, output, tag_len, check_tag ) ) != 0 )
- {
- return( ret );
- }
- /* Check tag in "constant-time" */
- for( diff = 0, i = 0; i < tag_len; i++ )
- diff |= tag[i] ^ check_tag[i];
- if( diff != 0 )
- {
- gcm_zeroize( output, length );
- return( MBEDTLS_ERR_GCM_AUTH_FAILED );
- }
- return( 0 );
- }
- void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
- {
- mbedtls_cipher_free( &ctx->cipher_ctx );
- gcm_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
- }
- #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
- /*
- * AES-GCM test vectors from:
- *
- * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
- */
- #define MAX_TESTS 6
- static const int key_index[MAX_TESTS] =
- { 0, 0, 1, 1, 1, 1 };
- static const unsigned char key[MAX_TESTS][32] =
- {
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
- 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
- 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
- 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
- };
- static const size_t iv_len[MAX_TESTS] =
- { 12, 12, 12, 12, 8, 60 };
- static const int iv_index[MAX_TESTS] =
- { 0, 0, 1, 1, 1, 2 };
- static const unsigned char iv[MAX_TESTS][64] =
- {
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 },
- { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
- 0xde, 0xca, 0xf8, 0x88 },
- { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
- 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
- 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
- 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
- 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
- 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
- 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
- 0xa6, 0x37, 0xb3, 0x9b },
- };
- static const size_t add_len[MAX_TESTS] =
- { 0, 0, 0, 20, 20, 20 };
- static const int add_index[MAX_TESTS] =
- { 0, 0, 0, 1, 1, 1 };
- static const unsigned char additional[MAX_TESTS][64] =
- {
- { 0x00 },
- { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
- 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
- 0xab, 0xad, 0xda, 0xd2 },
- };
- static const size_t pt_len[MAX_TESTS] =
- { 0, 16, 64, 60, 60, 60 };
- static const int pt_index[MAX_TESTS] =
- { 0, 0, 1, 1, 1, 1 };
- static const unsigned char pt[MAX_TESTS][64] =
- {
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
- 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
- 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
- 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
- 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
- 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
- 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
- 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
- };
- static const unsigned char ct[MAX_TESTS * 3][64] =
- {
- { 0x00 },
- { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
- 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
- { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
- 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
- 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
- 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
- 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
- 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
- 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
- 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
- { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
- 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
- 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
- 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
- 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
- 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
- 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
- 0x3d, 0x58, 0xe0, 0x91 },
- { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
- 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
- 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
- 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
- 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
- 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
- 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
- 0xc2, 0x3f, 0x45, 0x98 },
- { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
- 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
- 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
- 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
- 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
- 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
- 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
- 0x4c, 0x34, 0xae, 0xe5 },
- { 0x00 },
- { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
- 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
- { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
- 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
- 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
- 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
- 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
- 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
- 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
- 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
- { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
- 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
- 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
- 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
- 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
- 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
- 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
- 0xcc, 0xda, 0x27, 0x10 },
- { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
- 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
- 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
- 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
- 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
- 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
- 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
- 0xa0, 0xf0, 0x62, 0xf7 },
- { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
- 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
- 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
- 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
- 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
- 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
- 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
- 0xe9, 0xb7, 0x37, 0x3b },
- { 0x00 },
- { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
- 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
- { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
- 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
- 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
- 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
- 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
- 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
- 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
- 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
- { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
- 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
- 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
- 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
- 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
- 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
- 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
- 0xbc, 0xc9, 0xf6, 0x62 },
- { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
- 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
- 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
- 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
- 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
- 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
- 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
- 0xf4, 0x7c, 0x9b, 0x1f },
- { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
- 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
- 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
- 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
- 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
- 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
- 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
- 0x44, 0xae, 0x7e, 0x3f },
- };
- static const unsigned char tag[MAX_TESTS * 3][16] =
- {
- { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
- 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
- { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
- 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
- { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
- 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
- { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
- 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
- { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
- 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
- { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
- 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
- { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
- 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
- { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
- 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
- { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
- 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
- { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
- 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
- { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
- 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
- { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
- 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
- { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
- 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
- { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
- 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
- { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
- 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
- { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
- 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
- { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
- 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
- { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
- 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
- };
- int mbedtls_gcm_self_test( int verbose )
- {
- mbedtls_gcm_context ctx;
- unsigned char buf[64];
- unsigned char tag_buf[16];
- int i, j, ret;
- mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
- mbedtls_gcm_init( &ctx );
- for( j = 0; j < 3; j++ )
- {
- int key_len = 128 + 64 * j;
- for( i = 0; i < MAX_TESTS; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
- key_len, i, "enc" );
- mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
- ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
- pt_len[i],
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i],
- pt[pt_index[i]], buf, 16, tag_buf );
- if( ret != 0 ||
- memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- mbedtls_gcm_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
- key_len, i, "dec" );
- mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
- ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
- pt_len[i],
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i],
- ct[j * 6 + i], buf, 16, tag_buf );
- if( ret != 0 ||
- memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- mbedtls_gcm_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
- key_len, i, "enc" );
- mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
- ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i] );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( pt_len[i] > 32 )
- {
- size_t rest_len = pt_len[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
- buf + 32 );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- else
- {
- ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
- if( ret != 0 ||
- memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- mbedtls_gcm_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
- key_len, i, "dec" );
- mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
- ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i] );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( pt_len[i] > 32 )
- {
- size_t rest_len = pt_len[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
- buf + 32 );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- else
- {
- ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
- if( ret != 0 ||
- memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- mbedtls_gcm_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
- #endif /* MBEDTLS_GCM_C */
- /********* Start of file library/havege.c ************/
- /**
- * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The HAVEGE RNG was designed by Andre Seznec in 2002.
- *
- * http://www.irisa.fr/caps/projects/hipsor/publi.php
- *
- * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_HAVEGE_C)
- #include <string.h>
- /* Implementation that should never be optimized out by the compiler */
- static void havege_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /* ------------------------------------------------------------------------
- * On average, one iteration accesses two 8-word blocks in the havege WALK
- * table, and generates 16 words in the RES array.
- *
- * The data read in the WALK table is updated and permuted after each use.
- * The result of the hardware clock counter read is used for this update.
- *
- * 25 conditional tests are present. The conditional tests are grouped in
- * two nested groups of 12 conditional tests and 1 test that controls the
- * permutation; on average, there should be 6 tests executed and 3 of them
- * should be mispredicted.
- * ------------------------------------------------------------------------
- */
- #define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
- #define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
- #define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
- #define TST1_LEAVE U1++; }
- #define TST2_LEAVE U2++; }
- #define ONE_ITERATION \
- \
- PTEST = PT1 >> 20; \
- \
- TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
- TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
- TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
- \
- TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
- TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
- TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
- \
- PTX = (PT1 >> 18) & 7; \
- PT1 &= 0x1FFF; \
- PT2 &= 0x1FFF; \
- CLK = (int) mbedtls_timing_hardclock(); \
- \
- i = 0; \
- A = &WALK[PT1 ]; RES[i++] ^= *A; \
- B = &WALK[PT2 ]; RES[i++] ^= *B; \
- C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
- D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
- \
- IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
- *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
- *B = IN ^ U1; \
- *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
- *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
- \
- A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
- B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
- C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
- D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
- \
- if( PTEST & 1 ) SWAP( A, C ); \
- \
- IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
- *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
- *B = IN; CLK = (int) mbedtls_timing_hardclock(); \
- *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
- *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
- \
- A = &WALK[PT1 ^ 4]; \
- B = &WALK[PT2 ^ 1]; \
- \
- PTEST = PT2 >> 1; \
- \
- PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
- PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
- PTY = (PT2 >> 10) & 7; \
- \
- TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
- TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
- TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
- \
- TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
- TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
- TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
- \
- C = &WALK[PT1 ^ 5]; \
- D = &WALK[PT2 ^ 5]; \
- \
- RES[i++] ^= *A; \
- RES[i++] ^= *B; \
- RES[i++] ^= *C; \
- RES[i++] ^= *D; \
- \
- IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
- *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
- *B = IN ^ U2; \
- *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
- *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
- \
- A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
- B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
- C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
- D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
- \
- IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
- *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
- *B = IN; \
- *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
- *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
- \
- PT1 = ( RES[( i - 8 ) ^ PTX] ^ \
- WALK[PT1 ^ PTX ^ 7] ) & (~1); \
- PT1 ^= (PT2 ^ 0x10) & 0x10; \
- \
- for( n++, i = 0; i < 16; i++ ) \
- hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
- /*
- * Entropy gathering function
- */
- static void havege_fill( mbedtls_havege_state *hs )
- {
- int i, n = 0;
- int U1, U2, *A, *B, *C, *D;
- int PT1, PT2, *WALK, RES[16];
- int PTX, PTY, CLK, PTEST, IN;
- WALK = hs->WALK;
- PT1 = hs->PT1;
- PT2 = hs->PT2;
- PTX = U1 = 0;
- PTY = U2 = 0;
- memset( RES, 0, sizeof( RES ) );
- while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )
- {
- ONE_ITERATION
- ONE_ITERATION
- ONE_ITERATION
- ONE_ITERATION
- }
- hs->PT1 = PT1;
- hs->PT2 = PT2;
- hs->offset[0] = 0;
- hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2;
- }
- /*
- * HAVEGE initialization
- */
- void mbedtls_havege_init( mbedtls_havege_state *hs )
- {
- memset( hs, 0, sizeof( mbedtls_havege_state ) );
- havege_fill( hs );
- }
- void mbedtls_havege_free( mbedtls_havege_state *hs )
- {
- if( hs == NULL )
- return;
- havege_zeroize( hs, sizeof( mbedtls_havege_state ) );
- }
- /*
- * HAVEGE rand function
- */
- int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
- {
- int val;
- size_t use_len;
- mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
- unsigned char *p = buf;
- while( len > 0 )
- {
- use_len = len;
- if( use_len > sizeof(int) )
- use_len = sizeof(int);
- if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
- havege_fill( hs );
- val = hs->pool[hs->offset[0]++];
- val ^= hs->pool[hs->offset[1]++];
- memcpy( p, &val, use_len );
- len -= use_len;
- p += use_len;
- }
- return( 0 );
- }
- #endif /* MBEDTLS_HAVEGE_C */
- /********* Start of file library/hmac_drbg.c ************/
- /*
- * HMAC_DRBG implementation (NIST SP 800-90)
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The NIST SP 800-90A DRBGs are described in the following publication.
- * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
- * References below are based on rev. 1 (January 2012).
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_HMAC_DRBG_C)
- #include <string.h>
- #if defined(MBEDTLS_FS_IO)
- #include <stdio.h>
- #endif
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_PLATFORM_C */
- /* Implementation that should never be optimized out by the compiler */
- static void hmac_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * HMAC_DRBG context initialization
- */
- void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- }
- /*
- * HMAC_DRBG update, using optional additional data (10.1.2.2)
- */
- void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
- const unsigned char *additional, size_t add_len )
- {
- size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
- unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
- unsigned char sep[1];
- unsigned char K[MBEDTLS_MD_MAX_SIZE];
- for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
- {
- /* Step 1 or 4 */
- mbedtls_md_hmac_reset( &ctx->md_ctx );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
- if( rounds == 2 )
- mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, K );
- /* Step 2 or 5 */
- mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
- }
- }
- /*
- * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
- */
- int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
- const mbedtls_md_info_t * md_info,
- const unsigned char *data, size_t data_len )
- {
- int ret;
- if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
- return( ret );
- /*
- * Set initial working state.
- * Use the V memory location, which is currently all 0, to initialize the
- * MD context with an all-zero key. Then set V to its initial value.
- */
- mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) );
- memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
- mbedtls_hmac_drbg_update( ctx, data, data_len );
- return( 0 );
- }
- /*
- * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
- */
- int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
- const unsigned char *additional, size_t len )
- {
- unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
- size_t seedlen;
- /* III. Check input length */
- if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
- ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
- {
- return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
- }
- memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
- /* IV. Gather entropy_len bytes of entropy for the seed */
- if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
- return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
- seedlen = ctx->entropy_len;
- /* 1. Concatenate entropy and additional data if any */
- if( additional != NULL && len != 0 )
- {
- memcpy( seed + seedlen, additional, len );
- seedlen += len;
- }
- /* 2. Update state */
- mbedtls_hmac_drbg_update( ctx, seed, seedlen );
- /* 3. Reset reseed_counter */
- ctx->reseed_counter = 1;
- /* 4. Done */
- return( 0 );
- }
- /*
- * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
- */
- int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
- const mbedtls_md_info_t * md_info,
- int (*f_entropy)(void *, unsigned char *, size_t),
- void *p_entropy,
- const unsigned char *custom,
- size_t len )
- {
- int ret;
- size_t entropy_len, md_size;
- if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
- return( ret );
- md_size = mbedtls_md_get_size( md_info );
- /*
- * Set initial working state.
- * Use the V memory location, which is currently all 0, to initialize the
- * MD context with an all-zero key. Then set V to its initial value.
- */
- mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size );
- memset( ctx->V, 0x01, md_size );
- ctx->f_entropy = f_entropy;
- ctx->p_entropy = p_entropy;
- ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
- /*
- * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
- * each hash function, then according to SP800-90A rev1 10.1 table 2,
- * min_entropy_len (in bits) is security_strength.
- *
- * (This also matches the sizes used in the NIST test vectors.)
- */
- entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
- md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
- 32; /* better (256+) -> 256 bits */
- /*
- * For initialisation, use more entropy to emulate a nonce
- * (Again, matches test vectors.)
- */
- ctx->entropy_len = entropy_len * 3 / 2;
- if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
- return( ret );
- ctx->entropy_len = entropy_len;
- return( 0 );
- }
- /*
- * Set prediction resistance
- */
- void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
- int resistance )
- {
- ctx->prediction_resistance = resistance;
- }
- /*
- * Set entropy length grabbed for reseeds
- */
- void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
- {
- ctx->entropy_len = len;
- }
- /*
- * Set reseed interval
- */
- void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
- {
- ctx->reseed_interval = interval;
- }
- /*
- * HMAC_DRBG random function with optional additional data:
- * 10.1.2.5 (arabic) + 9.3 (Roman)
- */
- int mbedtls_hmac_drbg_random_with_add( void *p_rng,
- unsigned char *output, size_t out_len,
- const unsigned char *additional, size_t add_len )
- {
- int ret;
- mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
- size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
- size_t left = out_len;
- unsigned char *out = output;
- /* II. Check request length */
- if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
- return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
- /* III. Check input length */
- if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
- return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
- /* 1. (aka VII and IX) Check reseed counter and PR */
- if( ctx->f_entropy != NULL && /* For no-reseeding instances */
- ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
- ctx->reseed_counter > ctx->reseed_interval ) )
- {
- if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
- return( ret );
- add_len = 0; /* VII.4 */
- }
- /* 2. Use additional data if any */
- if( additional != NULL && add_len != 0 )
- mbedtls_hmac_drbg_update( ctx, additional, add_len );
- /* 3, 4, 5. Generate bytes */
- while( left != 0 )
- {
- size_t use_len = left > md_len ? md_len : left;
- mbedtls_md_hmac_reset( &ctx->md_ctx );
- mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
- memcpy( out, ctx->V, use_len );
- out += use_len;
- left -= use_len;
- }
- /* 6. Update */
- mbedtls_hmac_drbg_update( ctx, additional, add_len );
- /* 7. Update reseed counter */
- ctx->reseed_counter++;
- /* 8. Done */
- return( 0 );
- }
- /*
- * HMAC_DRBG random function
- */
- int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
- {
- int ret;
- mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- /*
- * Free an HMAC_DRBG context
- */
- void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
- {
- if( ctx == NULL )
- return;
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &ctx->mutex );
- #endif
- mbedtls_md_free( &ctx->md_ctx );
- hmac_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
- }
- #if defined(MBEDTLS_FS_IO)
- int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
- {
- int ret;
- FILE *f;
- unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
- if( ( f = fopen( path, "wb" ) ) == NULL )
- return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
- if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
- goto exit;
- if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
- {
- ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
- goto exit;
- }
- ret = 0;
- exit:
- fclose( f );
- return( ret );
- }
- int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
- {
- FILE *f;
- size_t n;
- unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
- fseek( f, 0, SEEK_END );
- n = (size_t) ftell( f );
- fseek( f, 0, SEEK_SET );
- if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
- {
- fclose( f );
- return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
- }
- if( fread( buf, 1, n, f ) != n )
- {
- fclose( f );
- return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
- }
- fclose( f );
- mbedtls_hmac_drbg_update( ctx, buf, n );
- return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
- }
- #endif /* MBEDTLS_FS_IO */
- #if defined(MBEDTLS_SELF_TEST)
- #if !defined(MBEDTLS_SHA1_C)
- /* Dummy checkup routine */
- int mbedtls_hmac_drbg_self_test( int verbose )
- {
- (void) verbose;
- return( 0 );
- }
- #else
- #define OUTPUT_LEN 80
- /* From a NIST PR=true test vector */
- static const unsigned char entropy_pr[] = {
- 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
- 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
- 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
- 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
- 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
- static const unsigned char result_pr[OUTPUT_LEN] = {
- 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
- 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
- 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
- 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
- 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
- 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
- 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
- /* From a NIST PR=false test vector */
- static const unsigned char entropy_nopr[] = {
- 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
- 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
- 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
- 0xe9, 0x9d, 0xfe, 0xdf };
- static const unsigned char result_nopr[OUTPUT_LEN] = {
- 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
- 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
- 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
- 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
- 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
- 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
- 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
- /* "Entropy" from buffer */
- static size_t test_offset;
- static int hmac_drbg_self_test_entropy( void *data,
- unsigned char *buf, size_t len )
- {
- const unsigned char *p = data;
- memcpy( buf, p + test_offset, len );
- test_offset += len;
- return( 0 );
- }
- #define CHK( c ) if( (c) != 0 ) \
- { \
- if( verbose != 0 ) \
- mbedtls_printf( "failed\n" ); \
- return( 1 ); \
- }
- /*
- * Checkup routine for HMAC_DRBG with SHA-1
- */
- int mbedtls_hmac_drbg_self_test( int verbose )
- {
- mbedtls_hmac_drbg_context ctx;
- unsigned char buf[OUTPUT_LEN];
- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
- mbedtls_hmac_drbg_init( &ctx );
- /*
- * PR = True
- */
- if( verbose != 0 )
- mbedtls_printf( " HMAC_DRBG (PR = True) : " );
- test_offset = 0;
- CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
- hmac_drbg_self_test_entropy, (void *) entropy_pr,
- NULL, 0 ) );
- mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
- CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
- CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
- CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
- mbedtls_hmac_drbg_free( &ctx );
- mbedtls_hmac_drbg_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- /*
- * PR = False
- */
- if( verbose != 0 )
- mbedtls_printf( " HMAC_DRBG (PR = False) : " );
- mbedtls_hmac_drbg_init( &ctx );
- test_offset = 0;
- CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
- hmac_drbg_self_test_entropy, (void *) entropy_nopr,
- NULL, 0 ) );
- CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
- CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
- CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
- CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
- mbedtls_hmac_drbg_free( &ctx );
- mbedtls_hmac_drbg_free( &ctx );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_HMAC_DRBG_C */
- /********* Start of file library/md.c ************/
- /**
- * \file mbedtls_md.c
- *
- * \brief Generic message digest wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_MD_C)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #include <string.h>
- #if defined(MBEDTLS_FS_IO)
- #include <stdio.h>
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void md_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Reminder: update profiles in x509_crt.c when adding a new hash!
- */
- static const int supported_digests[] = {
- #if defined(MBEDTLS_SHA512_C)
- MBEDTLS_MD_SHA512,
- MBEDTLS_MD_SHA384,
- #endif
- #if defined(MBEDTLS_SHA256_C)
- MBEDTLS_MD_SHA256,
- MBEDTLS_MD_SHA224,
- #endif
- #if defined(MBEDTLS_SHA1_C)
- MBEDTLS_MD_SHA1,
- #endif
- #if defined(MBEDTLS_RIPEMD160_C)
- MBEDTLS_MD_RIPEMD160,
- #endif
- #if defined(MBEDTLS_MD5_C)
- MBEDTLS_MD_MD5,
- #endif
- #if defined(MBEDTLS_MD4_C)
- MBEDTLS_MD_MD4,
- #endif
- #if defined(MBEDTLS_MD2_C)
- MBEDTLS_MD_MD2,
- #endif
- MBEDTLS_MD_NONE
- };
- const int *mbedtls_md_list( void )
- {
- return( supported_digests );
- }
- const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
- {
- if( NULL == md_name )
- return( NULL );
- /* Get the appropriate digest information */
- #if defined(MBEDTLS_MD2_C)
- if( !strcmp( "MD2", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
- #endif
- #if defined(MBEDTLS_MD4_C)
- if( !strcmp( "MD4", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
- #endif
- #if defined(MBEDTLS_MD5_C)
- if( !strcmp( "MD5", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
- #endif
- #if defined(MBEDTLS_RIPEMD160_C)
- if( !strcmp( "RIPEMD160", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
- #endif
- #if defined(MBEDTLS_SHA1_C)
- if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
- #endif
- #if defined(MBEDTLS_SHA256_C)
- if( !strcmp( "SHA224", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
- if( !strcmp( "SHA256", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- if( !strcmp( "SHA384", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
- if( !strcmp( "SHA512", md_name ) )
- return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
- #endif
- return( NULL );
- }
- const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
- {
- switch( md_type )
- {
- #if defined(MBEDTLS_MD2_C)
- case MBEDTLS_MD_MD2:
- return( &mbedtls_md2_info );
- #endif
- #if defined(MBEDTLS_MD4_C)
- case MBEDTLS_MD_MD4:
- return( &mbedtls_md4_info );
- #endif
- #if defined(MBEDTLS_MD5_C)
- case MBEDTLS_MD_MD5:
- return( &mbedtls_md5_info );
- #endif
- #if defined(MBEDTLS_RIPEMD160_C)
- case MBEDTLS_MD_RIPEMD160:
- return( &mbedtls_ripemd160_info );
- #endif
- #if defined(MBEDTLS_SHA1_C)
- case MBEDTLS_MD_SHA1:
- return( &mbedtls_sha1_info );
- #endif
- #if defined(MBEDTLS_SHA256_C)
- case MBEDTLS_MD_SHA224:
- return( &mbedtls_sha224_info );
- case MBEDTLS_MD_SHA256:
- return( &mbedtls_sha256_info );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- case MBEDTLS_MD_SHA384:
- return( &mbedtls_sha384_info );
- case MBEDTLS_MD_SHA512:
- return( &mbedtls_sha512_info );
- #endif
- default:
- return( NULL );
- }
- }
- void mbedtls_md_init( mbedtls_md_context_t *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
- }
- void mbedtls_md_free( mbedtls_md_context_t *ctx )
- {
- if( ctx == NULL || ctx->md_info == NULL )
- return;
- if( ctx->md_ctx != NULL )
- ctx->md_info->ctx_free_func( ctx->md_ctx );
- if( ctx->hmac_ctx != NULL )
- {
- md_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
- mbedtls_free( ctx->hmac_ctx );
- }
- md_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
- }
- int mbedtls_md_clone( mbedtls_md_context_t *dst,
- const mbedtls_md_context_t *src )
- {
- if( dst == NULL || dst->md_info == NULL ||
- src == NULL || src->md_info == NULL ||
- dst->md_info != src->md_info )
- {
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- }
- dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
- return( 0 );
- }
- #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
- int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
- {
- return mbedtls_md_setup( ctx, md_info, 1 );
- }
- #endif
- int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
- {
- if( md_info == NULL || ctx == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_MD_ALLOC_FAILED );
- if( hmac != 0 )
- {
- ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
- if( ctx->hmac_ctx == NULL )
- {
- md_info->ctx_free_func( ctx->md_ctx );
- return( MBEDTLS_ERR_MD_ALLOC_FAILED );
- }
- }
- ctx->md_info = md_info;
- return( 0 );
- }
- int mbedtls_md_starts( mbedtls_md_context_t *ctx )
- {
- if( ctx == NULL || ctx->md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- ctx->md_info->starts_func( ctx->md_ctx );
- return( 0 );
- }
- int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
- {
- if( ctx == NULL || ctx->md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- ctx->md_info->update_func( ctx->md_ctx, input, ilen );
- return( 0 );
- }
- int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
- {
- if( ctx == NULL || ctx->md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- ctx->md_info->finish_func( ctx->md_ctx, output );
- return( 0 );
- }
- int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
- unsigned char *output )
- {
- if( md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- md_info->digest_func( input, ilen, output );
- return( 0 );
- }
- #if defined(MBEDTLS_FS_IO)
- int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
- {
- int ret;
- FILE *f;
- size_t n;
- mbedtls_md_context_t ctx;
- unsigned char buf[1024];
- if( md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
- mbedtls_md_init( &ctx );
- if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
- goto cleanup;
- md_info->starts_func( ctx.md_ctx );
- while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
- md_info->update_func( ctx.md_ctx, buf, n );
- if( ferror( f ) != 0 )
- {
- ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
- goto cleanup;
- }
- md_info->finish_func( ctx.md_ctx, output );
- cleanup:
- fclose( f );
- mbedtls_md_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
- {
- unsigned char sum[MBEDTLS_MD_MAX_SIZE];
- unsigned char *ipad, *opad;
- size_t i;
- if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( keylen > (size_t) ctx->md_info->block_size )
- {
- ctx->md_info->starts_func( ctx->md_ctx );
- ctx->md_info->update_func( ctx->md_ctx, key, keylen );
- ctx->md_info->finish_func( ctx->md_ctx, sum );
- keylen = ctx->md_info->size;
- key = sum;
- }
- ipad = (unsigned char *) ctx->hmac_ctx;
- opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
- memset( ipad, 0x36, ctx->md_info->block_size );
- memset( opad, 0x5C, ctx->md_info->block_size );
- for( i = 0; i < keylen; i++ )
- {
- ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
- opad[i] = (unsigned char)( opad[i] ^ key[i] );
- }
- md_zeroize( sum, sizeof( sum ) );
- ctx->md_info->starts_func( ctx->md_ctx );
- ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
- return( 0 );
- }
- int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
- {
- if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- ctx->md_info->update_func( ctx->md_ctx, input, ilen );
- return( 0 );
- }
- int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
- {
- unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
- unsigned char *opad;
- if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
- ctx->md_info->finish_func( ctx->md_ctx, tmp );
- ctx->md_info->starts_func( ctx->md_ctx );
- ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size );
- ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size );
- ctx->md_info->finish_func( ctx->md_ctx, output );
- return( 0 );
- }
- int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
- {
- unsigned char *ipad;
- if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- ipad = (unsigned char *) ctx->hmac_ctx;
- ctx->md_info->starts_func( ctx->md_ctx );
- ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
- return( 0 );
- }
- int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
- const unsigned char *input, size_t ilen,
- unsigned char *output )
- {
- mbedtls_md_context_t ctx;
- int ret;
- if( md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- mbedtls_md_init( &ctx );
- if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
- return( ret );
- mbedtls_md_hmac_starts( &ctx, key, keylen );
- mbedtls_md_hmac_update( &ctx, input, ilen );
- mbedtls_md_hmac_finish( &ctx, output );
- mbedtls_md_free( &ctx );
- return( 0 );
- }
- int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
- {
- if( ctx == NULL || ctx->md_info == NULL )
- return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- ctx->md_info->process_func( ctx->md_ctx, data );
- return( 0 );
- }
- unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
- {
- if( md_info == NULL )
- return( 0 );
- return md_info->size;
- }
- mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
- {
- if( md_info == NULL )
- return( MBEDTLS_MD_NONE );
- return md_info->type;
- }
- const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
- {
- if( md_info == NULL )
- return( NULL );
- return md_info->name;
- }
- #endif /* MBEDTLS_MD_C */
- /********* Start of file library/md2.c ************/
- /*
- * RFC 1115/1319 compliant MD2 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The MD2 algorithm was designed by Ron Rivest in 1989.
- *
- * http://www.ietf.org/rfc/rfc1115.txt
- * http://www.ietf.org/rfc/rfc1319.txt
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_MD2_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_MD2_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void md2_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- static const unsigned char PI_SUBST[256] =
- {
- 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
- 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
- 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
- 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
- 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
- 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
- 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
- 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
- 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
- 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
- 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
- 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
- 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
- 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
- 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
- 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
- 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
- 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
- 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
- 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
- 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
- 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
- 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
- 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
- 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
- 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
- };
- void mbedtls_md2_init( mbedtls_md2_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_md2_context ) );
- }
- void mbedtls_md2_free( mbedtls_md2_context *ctx )
- {
- if( ctx == NULL )
- return;
- md2_zeroize( ctx, sizeof( mbedtls_md2_context ) );
- }
- void mbedtls_md2_clone( mbedtls_md2_context *dst,
- const mbedtls_md2_context *src )
- {
- *dst = *src;
- }
- /*
- * MD2 context setup
- */
- void mbedtls_md2_starts( mbedtls_md2_context *ctx )
- {
- memset( ctx->cksum, 0, 16 );
- memset( ctx->state, 0, 46 );
- memset( ctx->buffer, 0, 16 );
- ctx->left = 0;
- }
- #if !defined(MBEDTLS_MD2_PROCESS_ALT)
- void mbedtls_md2_process( mbedtls_md2_context *ctx )
- {
- int i, j;
- unsigned char t = 0;
- for( i = 0; i < 16; i++ )
- {
- ctx->state[i + 16] = ctx->buffer[i];
- ctx->state[i + 32] =
- (unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
- }
- for( i = 0; i < 18; i++ )
- {
- for( j = 0; j < 48; j++ )
- {
- ctx->state[j] = (unsigned char)
- ( ctx->state[j] ^ PI_SUBST[t] );
- t = ctx->state[j];
- }
- t = (unsigned char)( t + i );
- }
- t = ctx->cksum[15];
- for( i = 0; i < 16; i++ )
- {
- ctx->cksum[i] = (unsigned char)
- ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
- t = ctx->cksum[i];
- }
- }
- #endif /* !MBEDTLS_MD2_PROCESS_ALT */
- /*
- * MD2 process buffer
- */
- void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen )
- {
- size_t fill;
- while( ilen > 0 )
- {
- if( ctx->left + ilen > 16 )
- fill = 16 - ctx->left;
- else
- fill = ilen;
- memcpy( ctx->buffer + ctx->left, input, fill );
- ctx->left += fill;
- input += fill;
- ilen -= fill;
- if( ctx->left == 16 )
- {
- ctx->left = 0;
- mbedtls_md2_process( ctx );
- }
- }
- }
- /*
- * MD2 final digest
- */
- void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] )
- {
- size_t i;
- unsigned char x;
- x = (unsigned char)( 16 - ctx->left );
- for( i = ctx->left; i < 16; i++ )
- ctx->buffer[i] = x;
- mbedtls_md2_process( ctx );
- memcpy( ctx->buffer, ctx->cksum, 16 );
- mbedtls_md2_process( ctx );
- memcpy( output, ctx->state, 16 );
- }
- #endif /* !MBEDTLS_MD2_ALT */
- /*
- * output = MD2( input buffer )
- */
- void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
- {
- mbedtls_md2_context ctx;
- mbedtls_md2_init( &ctx );
- mbedtls_md2_starts( &ctx );
- mbedtls_md2_update( &ctx, input, ilen );
- mbedtls_md2_finish( &ctx, output );
- mbedtls_md2_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * RFC 1319 test vectors
- */
- static const char md2_test_str[7][81] =
- {
- { "" },
- { "a" },
- { "abc" },
- { "message digest" },
- { "abcdefghijklmnopqrstuvwxyz" },
- { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
- { "12345678901234567890123456789012345678901234567890123456789012" \
- "345678901234567890" }
- };
- static const unsigned char md2_test_sum[7][16] =
- {
- { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
- 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
- { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
- 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
- { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
- 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
- { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
- 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
- { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
- 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
- { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
- 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
- { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
- 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
- };
- /*
- * Checkup routine
- */
- int mbedtls_md2_self_test( int verbose )
- {
- int i;
- unsigned char md2sum[16];
- for( i = 0; i < 7; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " MD2 test #%d: ", i + 1 );
- mbedtls_md2( (unsigned char *) md2_test_str[i],
- strlen( md2_test_str[i] ), md2sum );
- if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_MD2_C */
- /********* Start of file library/md4.c ************/
- /*
- * RFC 1186/1320 compliant MD4 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The MD4 algorithm was designed by Ron Rivest in 1990.
- *
- * http://www.ietf.org/rfc/rfc1186.txt
- * http://www.ietf.org/rfc/rfc1320.txt
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_MD4_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_MD4_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void md4_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (little endian)
- */
- #ifndef GET_UINT32_LE
- #define GET_UINT32_LE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
- }
- #endif
- #ifndef PUT_UINT32_LE
- #define PUT_UINT32_LE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
- }
- #endif
- void mbedtls_md4_init( mbedtls_md4_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_md4_context ) );
- }
- void mbedtls_md4_free( mbedtls_md4_context *ctx )
- {
- if( ctx == NULL )
- return;
- md4_zeroize( ctx, sizeof( mbedtls_md4_context ) );
- }
- void mbedtls_md4_clone( mbedtls_md4_context *dst,
- const mbedtls_md4_context *src )
- {
- *dst = *src;
- }
- /*
- * MD4 context setup
- */
- void mbedtls_md4_starts( mbedtls_md4_context *ctx )
- {
- ctx->total[0] = 0;
- ctx->total[1] = 0;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- }
- #if !defined(MBEDTLS_MD4_PROCESS_ALT)
- void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] )
- {
- uint32_t X[16], A, B, C, D;
- GET_UINT32_LE( X[ 0], data, 0 );
- GET_UINT32_LE( X[ 1], data, 4 );
- GET_UINT32_LE( X[ 2], data, 8 );
- GET_UINT32_LE( X[ 3], data, 12 );
- GET_UINT32_LE( X[ 4], data, 16 );
- GET_UINT32_LE( X[ 5], data, 20 );
- GET_UINT32_LE( X[ 6], data, 24 );
- GET_UINT32_LE( X[ 7], data, 28 );
- GET_UINT32_LE( X[ 8], data, 32 );
- GET_UINT32_LE( X[ 9], data, 36 );
- GET_UINT32_LE( X[10], data, 40 );
- GET_UINT32_LE( X[11], data, 44 );
- GET_UINT32_LE( X[12], data, 48 );
- GET_UINT32_LE( X[13], data, 52 );
- GET_UINT32_LE( X[14], data, 56 );
- GET_UINT32_LE( X[15], data, 60 );
- #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- #define F(x, y, z) ((x & y) | ((~x) & z))
- #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
- P( A, B, C, D, X[ 0], 3 );
- P( D, A, B, C, X[ 1], 7 );
- P( C, D, A, B, X[ 2], 11 );
- P( B, C, D, A, X[ 3], 19 );
- P( A, B, C, D, X[ 4], 3 );
- P( D, A, B, C, X[ 5], 7 );
- P( C, D, A, B, X[ 6], 11 );
- P( B, C, D, A, X[ 7], 19 );
- P( A, B, C, D, X[ 8], 3 );
- P( D, A, B, C, X[ 9], 7 );
- P( C, D, A, B, X[10], 11 );
- P( B, C, D, A, X[11], 19 );
- P( A, B, C, D, X[12], 3 );
- P( D, A, B, C, X[13], 7 );
- P( C, D, A, B, X[14], 11 );
- P( B, C, D, A, X[15], 19 );
- #undef P
- #undef F
- #define F(x,y,z) ((x & y) | (x & z) | (y & z))
- #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
- P( A, B, C, D, X[ 0], 3 );
- P( D, A, B, C, X[ 4], 5 );
- P( C, D, A, B, X[ 8], 9 );
- P( B, C, D, A, X[12], 13 );
- P( A, B, C, D, X[ 1], 3 );
- P( D, A, B, C, X[ 5], 5 );
- P( C, D, A, B, X[ 9], 9 );
- P( B, C, D, A, X[13], 13 );
- P( A, B, C, D, X[ 2], 3 );
- P( D, A, B, C, X[ 6], 5 );
- P( C, D, A, B, X[10], 9 );
- P( B, C, D, A, X[14], 13 );
- P( A, B, C, D, X[ 3], 3 );
- P( D, A, B, C, X[ 7], 5 );
- P( C, D, A, B, X[11], 9 );
- P( B, C, D, A, X[15], 13 );
- #undef P
- #undef F
- #define F(x,y,z) (x ^ y ^ z)
- #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
- P( A, B, C, D, X[ 0], 3 );
- P( D, A, B, C, X[ 8], 9 );
- P( C, D, A, B, X[ 4], 11 );
- P( B, C, D, A, X[12], 15 );
- P( A, B, C, D, X[ 2], 3 );
- P( D, A, B, C, X[10], 9 );
- P( C, D, A, B, X[ 6], 11 );
- P( B, C, D, A, X[14], 15 );
- P( A, B, C, D, X[ 1], 3 );
- P( D, A, B, C, X[ 9], 9 );
- P( C, D, A, B, X[ 5], 11 );
- P( B, C, D, A, X[13], 15 );
- P( A, B, C, D, X[ 3], 3 );
- P( D, A, B, C, X[11], 9 );
- P( C, D, A, B, X[ 7], 11 );
- P( B, C, D, A, X[15], 15 );
- #undef F
- #undef P
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- }
- #endif /* !MBEDTLS_MD4_PROCESS_ALT */
- /*
- * MD4 process buffer
- */
- void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen )
- {
- size_t fill;
- uint32_t left;
- if( ilen == 0 )
- return;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if( ctx->total[0] < (uint32_t) ilen )
- ctx->total[1]++;
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left),
- (void *) input, fill );
- mbedtls_md4_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
- while( ilen >= 64 )
- {
- mbedtls_md4_process( ctx, input );
- input += 64;
- ilen -= 64;
- }
- if( ilen > 0 )
- {
- memcpy( (void *) (ctx->buffer + left),
- (void *) input, ilen );
- }
- }
- static const unsigned char md4_padding[64] =
- {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /*
- * MD4 final digest
- */
- void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] )
- {
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx->total[0] >> 29 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
- last = ctx->total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- mbedtls_md4_update( ctx, (unsigned char *) md4_padding, padn );
- mbedtls_md4_update( ctx, msglen, 8 );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
- }
- #endif /* !MBEDTLS_MD4_ALT */
- /*
- * output = MD4( input buffer )
- */
- void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
- {
- mbedtls_md4_context ctx;
- mbedtls_md4_init( &ctx );
- mbedtls_md4_starts( &ctx );
- mbedtls_md4_update( &ctx, input, ilen );
- mbedtls_md4_finish( &ctx, output );
- mbedtls_md4_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * RFC 1320 test vectors
- */
- static const char md4_test_str[7][81] =
- {
- { "" },
- { "a" },
- { "abc" },
- { "message digest" },
- { "abcdefghijklmnopqrstuvwxyz" },
- { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
- { "12345678901234567890123456789012345678901234567890123456789012" \
- "345678901234567890" }
- };
- static const unsigned char md4_test_sum[7][16] =
- {
- { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
- 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
- { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
- 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
- { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
- 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
- { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
- 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
- { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
- 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
- { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
- 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
- { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
- 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
- };
- /*
- * Checkup routine
- */
- int mbedtls_md4_self_test( int verbose )
- {
- int i;
- unsigned char md4sum[16];
- for( i = 0; i < 7; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " MD4 test #%d: ", i + 1 );
- mbedtls_md4( (unsigned char *) md4_test_str[i],
- strlen( md4_test_str[i] ), md4sum );
- if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_MD4_C */
- /********* Start of file library/md5.c ************/
- /*
- * RFC 1321 compliant MD5 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The MD5 algorithm was designed by Ron Rivest in 1991.
- *
- * http://www.ietf.org/rfc/rfc1321.txt
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_MD5_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_MD5_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void md5_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (little endian)
- */
- #ifndef GET_UINT32_LE
- #define GET_UINT32_LE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
- }
- #endif
- #ifndef PUT_UINT32_LE
- #define PUT_UINT32_LE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
- }
- #endif
- void mbedtls_md5_init( mbedtls_md5_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_md5_context ) );
- }
- void mbedtls_md5_free( mbedtls_md5_context *ctx )
- {
- if( ctx == NULL )
- return;
- md5_zeroize( ctx, sizeof( mbedtls_md5_context ) );
- }
- void mbedtls_md5_clone( mbedtls_md5_context *dst,
- const mbedtls_md5_context *src )
- {
- *dst = *src;
- }
- /*
- * MD5 context setup
- */
- void mbedtls_md5_starts( mbedtls_md5_context *ctx )
- {
- ctx->total[0] = 0;
- ctx->total[1] = 0;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- }
- #if !defined(MBEDTLS_MD5_PROCESS_ALT)
- void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
- {
- uint32_t X[16], A, B, C, D;
- GET_UINT32_LE( X[ 0], data, 0 );
- GET_UINT32_LE( X[ 1], data, 4 );
- GET_UINT32_LE( X[ 2], data, 8 );
- GET_UINT32_LE( X[ 3], data, 12 );
- GET_UINT32_LE( X[ 4], data, 16 );
- GET_UINT32_LE( X[ 5], data, 20 );
- GET_UINT32_LE( X[ 6], data, 24 );
- GET_UINT32_LE( X[ 7], data, 28 );
- GET_UINT32_LE( X[ 8], data, 32 );
- GET_UINT32_LE( X[ 9], data, 36 );
- GET_UINT32_LE( X[10], data, 40 );
- GET_UINT32_LE( X[11], data, 44 );
- GET_UINT32_LE( X[12], data, 48 );
- GET_UINT32_LE( X[13], data, 52 );
- GET_UINT32_LE( X[14], data, 56 );
- GET_UINT32_LE( X[15], data, 60 );
- #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
- #define P(a,b,c,d,k,s,t) \
- { \
- a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
- }
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- #define F(x,y,z) (z ^ (x & (y ^ z)))
- P( A, B, C, D, 0, 7, 0xD76AA478 );
- P( D, A, B, C, 1, 12, 0xE8C7B756 );
- P( C, D, A, B, 2, 17, 0x242070DB );
- P( B, C, D, A, 3, 22, 0xC1BDCEEE );
- P( A, B, C, D, 4, 7, 0xF57C0FAF );
- P( D, A, B, C, 5, 12, 0x4787C62A );
- P( C, D, A, B, 6, 17, 0xA8304613 );
- P( B, C, D, A, 7, 22, 0xFD469501 );
- P( A, B, C, D, 8, 7, 0x698098D8 );
- P( D, A, B, C, 9, 12, 0x8B44F7AF );
- P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
- P( B, C, D, A, 11, 22, 0x895CD7BE );
- P( A, B, C, D, 12, 7, 0x6B901122 );
- P( D, A, B, C, 13, 12, 0xFD987193 );
- P( C, D, A, B, 14, 17, 0xA679438E );
- P( B, C, D, A, 15, 22, 0x49B40821 );
- #undef F
- #define F(x,y,z) (y ^ (z & (x ^ y)))
- P( A, B, C, D, 1, 5, 0xF61E2562 );
- P( D, A, B, C, 6, 9, 0xC040B340 );
- P( C, D, A, B, 11, 14, 0x265E5A51 );
- P( B, C, D, A, 0, 20, 0xE9B6C7AA );
- P( A, B, C, D, 5, 5, 0xD62F105D );
- P( D, A, B, C, 10, 9, 0x02441453 );
- P( C, D, A, B, 15, 14, 0xD8A1E681 );
- P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
- P( A, B, C, D, 9, 5, 0x21E1CDE6 );
- P( D, A, B, C, 14, 9, 0xC33707D6 );
- P( C, D, A, B, 3, 14, 0xF4D50D87 );
- P( B, C, D, A, 8, 20, 0x455A14ED );
- P( A, B, C, D, 13, 5, 0xA9E3E905 );
- P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
- P( C, D, A, B, 7, 14, 0x676F02D9 );
- P( B, C, D, A, 12, 20, 0x8D2A4C8A );
- #undef F
- #define F(x,y,z) (x ^ y ^ z)
- P( A, B, C, D, 5, 4, 0xFFFA3942 );
- P( D, A, B, C, 8, 11, 0x8771F681 );
- P( C, D, A, B, 11, 16, 0x6D9D6122 );
- P( B, C, D, A, 14, 23, 0xFDE5380C );
- P( A, B, C, D, 1, 4, 0xA4BEEA44 );
- P( D, A, B, C, 4, 11, 0x4BDECFA9 );
- P( C, D, A, B, 7, 16, 0xF6BB4B60 );
- P( B, C, D, A, 10, 23, 0xBEBFBC70 );
- P( A, B, C, D, 13, 4, 0x289B7EC6 );
- P( D, A, B, C, 0, 11, 0xEAA127FA );
- P( C, D, A, B, 3, 16, 0xD4EF3085 );
- P( B, C, D, A, 6, 23, 0x04881D05 );
- P( A, B, C, D, 9, 4, 0xD9D4D039 );
- P( D, A, B, C, 12, 11, 0xE6DB99E5 );
- P( C, D, A, B, 15, 16, 0x1FA27CF8 );
- P( B, C, D, A, 2, 23, 0xC4AC5665 );
- #undef F
- #define F(x,y,z) (y ^ (x | ~z))
- P( A, B, C, D, 0, 6, 0xF4292244 );
- P( D, A, B, C, 7, 10, 0x432AFF97 );
- P( C, D, A, B, 14, 15, 0xAB9423A7 );
- P( B, C, D, A, 5, 21, 0xFC93A039 );
- P( A, B, C, D, 12, 6, 0x655B59C3 );
- P( D, A, B, C, 3, 10, 0x8F0CCC92 );
- P( C, D, A, B, 10, 15, 0xFFEFF47D );
- P( B, C, D, A, 1, 21, 0x85845DD1 );
- P( A, B, C, D, 8, 6, 0x6FA87E4F );
- P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
- P( C, D, A, B, 6, 15, 0xA3014314 );
- P( B, C, D, A, 13, 21, 0x4E0811A1 );
- P( A, B, C, D, 4, 6, 0xF7537E82 );
- P( D, A, B, C, 11, 10, 0xBD3AF235 );
- P( C, D, A, B, 2, 15, 0x2AD7D2BB );
- P( B, C, D, A, 9, 21, 0xEB86D391 );
- #undef F
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- }
- #endif /* !MBEDTLS_MD5_PROCESS_ALT */
- /*
- * MD5 process buffer
- */
- void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
- {
- size_t fill;
- uint32_t left;
- if( ilen == 0 )
- return;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if( ctx->total[0] < (uint32_t) ilen )
- ctx->total[1]++;
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- mbedtls_md5_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
- while( ilen >= 64 )
- {
- mbedtls_md5_process( ctx, input );
- input += 64;
- ilen -= 64;
- }
- if( ilen > 0 )
- {
- memcpy( (void *) (ctx->buffer + left), input, ilen );
- }
- }
- static const unsigned char md5_padding[64] =
- {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /*
- * MD5 final digest
- */
- void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
- {
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx->total[0] >> 29 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
- last = ctx->total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- mbedtls_md5_update( ctx, md5_padding, padn );
- mbedtls_md5_update( ctx, msglen, 8 );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
- }
- #endif /* !MBEDTLS_MD5_ALT */
- /*
- * output = MD5( input buffer )
- */
- void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
- {
- mbedtls_md5_context ctx;
- mbedtls_md5_init( &ctx );
- mbedtls_md5_starts( &ctx );
- mbedtls_md5_update( &ctx, input, ilen );
- mbedtls_md5_finish( &ctx, output );
- mbedtls_md5_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * RFC 1321 test vectors
- */
- static const unsigned char md5_test_buf[7][81] =
- {
- { "" },
- { "a" },
- { "abc" },
- { "message digest" },
- { "abcdefghijklmnopqrstuvwxyz" },
- { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
- { "12345678901234567890123456789012345678901234567890123456789012" \
- "345678901234567890" }
- };
- static const int md5_test_buflen[7] =
- {
- 0, 1, 3, 14, 26, 62, 80
- };
- static const unsigned char md5_test_sum[7][16] =
- {
- { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
- 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
- { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
- 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
- { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
- 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
- { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
- 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
- { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
- 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
- { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
- 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
- { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
- 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
- };
- /*
- * Checkup routine
- */
- int mbedtls_md5_self_test( int verbose )
- {
- int i;
- unsigned char md5sum[16];
- for( i = 0; i < 7; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " MD5 test #%d: ", i + 1 );
- mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
- if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef F
- #undef P
- #undef S
- #endif /* MBEDTLS_MD5_C */
- /********* Start of file library/md_wrap.c ************/
- /**
- * \file md_wrap.c
- *
- * \brief Generic message digest wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_MD_C)
- #if defined(MBEDTLS_MD2_C)
- #endif
- #if defined(MBEDTLS_MD4_C)
- #endif
- #if defined(MBEDTLS_MD5_C)
- #endif
- #if defined(MBEDTLS_RIPEMD160_C)
- #endif
- #if defined(MBEDTLS_SHA1_C)
- #endif
- #if defined(MBEDTLS_SHA256_C)
- #endif
- #if defined(MBEDTLS_SHA512_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if defined(MBEDTLS_MD2_C)
- static void md2_starts_wrap( void *ctx )
- {
- mbedtls_md2_starts( (mbedtls_md2_context *) ctx );
- }
- static void md2_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_md2_update( (mbedtls_md2_context *) ctx, input, ilen );
- }
- static void md2_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_md2_finish( (mbedtls_md2_context *) ctx, output );
- }
- static void *md2_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
- if( ctx != NULL )
- mbedtls_md2_init( (mbedtls_md2_context *) ctx );
- return( ctx );
- }
- static void md2_ctx_free( void *ctx )
- {
- mbedtls_md2_free( (mbedtls_md2_context *) ctx );
- mbedtls_free( ctx );
- }
- static void md2_clone_wrap( void *dst, const void *src )
- {
- mbedtls_md2_clone( (mbedtls_md2_context *) dst,
- (const mbedtls_md2_context *) src );
- }
- static void md2_process_wrap( void *ctx, const unsigned char *data )
- {
- ((void) data);
- mbedtls_md2_process( (mbedtls_md2_context *) ctx );
- }
- const mbedtls_md_info_t mbedtls_md2_info = {
- MBEDTLS_MD_MD2,
- "MD2",
- 16,
- 16,
- md2_starts_wrap,
- md2_update_wrap,
- md2_finish_wrap,
- mbedtls_md2,
- md2_ctx_alloc,
- md2_ctx_free,
- md2_clone_wrap,
- md2_process_wrap,
- };
- #endif /* MBEDTLS_MD2_C */
- #if defined(MBEDTLS_MD4_C)
- static void md4_starts_wrap( void *ctx )
- {
- mbedtls_md4_starts( (mbedtls_md4_context *) ctx );
- }
- static void md4_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_md4_update( (mbedtls_md4_context *) ctx, input, ilen );
- }
- static void md4_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_md4_finish( (mbedtls_md4_context *) ctx, output );
- }
- static void *md4_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
- if( ctx != NULL )
- mbedtls_md4_init( (mbedtls_md4_context *) ctx );
- return( ctx );
- }
- static void md4_ctx_free( void *ctx )
- {
- mbedtls_md4_free( (mbedtls_md4_context *) ctx );
- mbedtls_free( ctx );
- }
- static void md4_clone_wrap( void *dst, const void *src )
- {
- mbedtls_md4_clone( (mbedtls_md4_context *) dst,
- (const mbedtls_md4_context *) src );
- }
- static void md4_process_wrap( void *ctx, const unsigned char *data )
- {
- mbedtls_md4_process( (mbedtls_md4_context *) ctx, data );
- }
- const mbedtls_md_info_t mbedtls_md4_info = {
- MBEDTLS_MD_MD4,
- "MD4",
- 16,
- 64,
- md4_starts_wrap,
- md4_update_wrap,
- md4_finish_wrap,
- mbedtls_md4,
- md4_ctx_alloc,
- md4_ctx_free,
- md4_clone_wrap,
- md4_process_wrap,
- };
- #endif /* MBEDTLS_MD4_C */
- #if defined(MBEDTLS_MD5_C)
- static void md5_starts_wrap( void *ctx )
- {
- mbedtls_md5_starts( (mbedtls_md5_context *) ctx );
- }
- static void md5_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_md5_update( (mbedtls_md5_context *) ctx, input, ilen );
- }
- static void md5_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_md5_finish( (mbedtls_md5_context *) ctx, output );
- }
- static void *md5_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
- if( ctx != NULL )
- mbedtls_md5_init( (mbedtls_md5_context *) ctx );
- return( ctx );
- }
- static void md5_ctx_free( void *ctx )
- {
- mbedtls_md5_free( (mbedtls_md5_context *) ctx );
- mbedtls_free( ctx );
- }
- static void md5_clone_wrap( void *dst, const void *src )
- {
- mbedtls_md5_clone( (mbedtls_md5_context *) dst,
- (const mbedtls_md5_context *) src );
- }
- static void md5_process_wrap( void *ctx, const unsigned char *data )
- {
- mbedtls_md5_process( (mbedtls_md5_context *) ctx, data );
- }
- const mbedtls_md_info_t mbedtls_md5_info = {
- MBEDTLS_MD_MD5,
- "MD5",
- 16,
- 64,
- md5_starts_wrap,
- md5_update_wrap,
- md5_finish_wrap,
- mbedtls_md5,
- md5_ctx_alloc,
- md5_ctx_free,
- md5_clone_wrap,
- md5_process_wrap,
- };
- #endif /* MBEDTLS_MD5_C */
- #if defined(MBEDTLS_RIPEMD160_C)
- static void ripemd160_starts_wrap( void *ctx )
- {
- mbedtls_ripemd160_starts( (mbedtls_ripemd160_context *) ctx );
- }
- static void ripemd160_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_ripemd160_update( (mbedtls_ripemd160_context *) ctx, input, ilen );
- }
- static void ripemd160_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_ripemd160_finish( (mbedtls_ripemd160_context *) ctx, output );
- }
- static void *ripemd160_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
- if( ctx != NULL )
- mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
- return( ctx );
- }
- static void ripemd160_ctx_free( void *ctx )
- {
- mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
- mbedtls_free( ctx );
- }
- static void ripemd160_clone_wrap( void *dst, const void *src )
- {
- mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
- (const mbedtls_ripemd160_context *) src );
- }
- static void ripemd160_process_wrap( void *ctx, const unsigned char *data )
- {
- mbedtls_ripemd160_process( (mbedtls_ripemd160_context *) ctx, data );
- }
- const mbedtls_md_info_t mbedtls_ripemd160_info = {
- MBEDTLS_MD_RIPEMD160,
- "RIPEMD160",
- 20,
- 64,
- ripemd160_starts_wrap,
- ripemd160_update_wrap,
- ripemd160_finish_wrap,
- mbedtls_ripemd160,
- ripemd160_ctx_alloc,
- ripemd160_ctx_free,
- ripemd160_clone_wrap,
- ripemd160_process_wrap,
- };
- #endif /* MBEDTLS_RIPEMD160_C */
- #if defined(MBEDTLS_SHA1_C)
- static void sha1_starts_wrap( void *ctx )
- {
- mbedtls_sha1_starts( (mbedtls_sha1_context *) ctx );
- }
- static void sha1_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_sha1_update( (mbedtls_sha1_context *) ctx, input, ilen );
- }
- static void sha1_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_sha1_finish( (mbedtls_sha1_context *) ctx, output );
- }
- static void *sha1_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
- if( ctx != NULL )
- mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
- return( ctx );
- }
- static void sha1_clone_wrap( void *dst, const void *src )
- {
- mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
- (const mbedtls_sha1_context *) src );
- }
- static void sha1_ctx_free( void *ctx )
- {
- mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
- mbedtls_free( ctx );
- }
- static void sha1_process_wrap( void *ctx, const unsigned char *data )
- {
- mbedtls_sha1_process( (mbedtls_sha1_context *) ctx, data );
- }
- const mbedtls_md_info_t mbedtls_sha1_info = {
- MBEDTLS_MD_SHA1,
- "SHA1",
- 20,
- 64,
- sha1_starts_wrap,
- sha1_update_wrap,
- sha1_finish_wrap,
- mbedtls_sha1,
- sha1_ctx_alloc,
- sha1_ctx_free,
- sha1_clone_wrap,
- sha1_process_wrap,
- };
- #endif /* MBEDTLS_SHA1_C */
- /*
- * Wrappers for generic message digests
- */
- #if defined(MBEDTLS_SHA256_C)
- static void sha224_starts_wrap( void *ctx )
- {
- mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 1 );
- }
- static void sha224_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_sha256_update( (mbedtls_sha256_context *) ctx, input, ilen );
- }
- static void sha224_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_sha256_finish( (mbedtls_sha256_context *) ctx, output );
- }
- static void sha224_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
- {
- mbedtls_sha256( input, ilen, output, 1 );
- }
- static void *sha224_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
- if( ctx != NULL )
- mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
- return( ctx );
- }
- static void sha224_ctx_free( void *ctx )
- {
- mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
- mbedtls_free( ctx );
- }
- static void sha224_clone_wrap( void *dst, const void *src )
- {
- mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
- (const mbedtls_sha256_context *) src );
- }
- static void sha224_process_wrap( void *ctx, const unsigned char *data )
- {
- mbedtls_sha256_process( (mbedtls_sha256_context *) ctx, data );
- }
- const mbedtls_md_info_t mbedtls_sha224_info = {
- MBEDTLS_MD_SHA224,
- "SHA224",
- 28,
- 64,
- sha224_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha224_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
- };
- static void sha256_starts_wrap( void *ctx )
- {
- mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 0 );
- }
- static void sha256_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
- {
- mbedtls_sha256( input, ilen, output, 0 );
- }
- const mbedtls_md_info_t mbedtls_sha256_info = {
- MBEDTLS_MD_SHA256,
- "SHA256",
- 32,
- 64,
- sha256_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha256_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
- };
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- static void sha384_starts_wrap( void *ctx )
- {
- mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 1 );
- }
- static void sha384_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
- {
- mbedtls_sha512_update( (mbedtls_sha512_context *) ctx, input, ilen );
- }
- static void sha384_finish_wrap( void *ctx, unsigned char *output )
- {
- mbedtls_sha512_finish( (mbedtls_sha512_context *) ctx, output );
- }
- static void sha384_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
- {
- mbedtls_sha512( input, ilen, output, 1 );
- }
- static void *sha384_ctx_alloc( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
- if( ctx != NULL )
- mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
- return( ctx );
- }
- static void sha384_ctx_free( void *ctx )
- {
- mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
- mbedtls_free( ctx );
- }
- static void sha384_clone_wrap( void *dst, const void *src )
- {
- mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
- (const mbedtls_sha512_context *) src );
- }
- static void sha384_process_wrap( void *ctx, const unsigned char *data )
- {
- mbedtls_sha512_process( (mbedtls_sha512_context *) ctx, data );
- }
- const mbedtls_md_info_t mbedtls_sha384_info = {
- MBEDTLS_MD_SHA384,
- "SHA384",
- 48,
- 128,
- sha384_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha384_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
- };
- static void sha512_starts_wrap( void *ctx )
- {
- mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 0 );
- }
- static void sha512_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
- {
- mbedtls_sha512( input, ilen, output, 0 );
- }
- const mbedtls_md_info_t mbedtls_sha512_info = {
- MBEDTLS_MD_SHA512,
- "SHA512",
- 64,
- 128,
- sha512_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha512_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
- };
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_MD_C */
- /********* Start of file library/memory_buffer_alloc.c ************/
- /*
- * Buffer-based memory allocator
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
- /* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
- is dependent upon MBEDTLS_PLATFORM_C */
- #include <string.h>
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- #include <execinfo.h>
- #endif
- #if defined(MBEDTLS_THREADING_C)
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void memory_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #define MAGIC1 0xFF00AA55
- #define MAGIC2 0xEE119966
- #define MAX_BT 20
- typedef struct _memory_header memory_header;
- struct _memory_header
- {
- size_t magic1;
- size_t size;
- size_t alloc;
- memory_header *prev;
- memory_header *next;
- memory_header *prev_free;
- memory_header *next_free;
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- char **trace;
- size_t trace_count;
- #endif
- size_t magic2;
- };
- typedef struct
- {
- unsigned char *buf;
- size_t len;
- memory_header *first;
- memory_header *first_free;
- int verify;
- #if defined(MBEDTLS_MEMORY_DEBUG)
- size_t alloc_count;
- size_t free_count;
- size_t total_used;
- size_t maximum_used;
- size_t header_count;
- size_t maximum_header_count;
- #endif
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_threading_mutex_t mutex;
- #endif
- }
- buffer_alloc_ctx;
- static buffer_alloc_ctx heap;
- #if defined(MBEDTLS_MEMORY_DEBUG)
- static void debug_header( memory_header *hdr )
- {
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- size_t i;
- #endif
- mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
- "ALLOC(%zu), SIZE(%10zu)\n",
- (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
- hdr->alloc, hdr->size );
- mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n",
- (size_t) hdr->prev_free, (size_t) hdr->next_free );
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- mbedtls_fprintf( stderr, "TRACE: \n" );
- for( i = 0; i < hdr->trace_count; i++ )
- mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] );
- mbedtls_fprintf( stderr, "\n" );
- #endif
- }
- static void debug_chain()
- {
- memory_header *cur = heap.first;
- mbedtls_fprintf( stderr, "\nBlock list\n" );
- while( cur != NULL )
- {
- debug_header( cur );
- cur = cur->next;
- }
- mbedtls_fprintf( stderr, "Free list\n" );
- cur = heap.first_free;
- while( cur != NULL )
- {
- debug_header( cur );
- cur = cur->next_free;
- }
- }
- #endif /* MBEDTLS_MEMORY_DEBUG */
- static int verify_header( memory_header *hdr )
- {
- if( hdr->magic1 != MAGIC1 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" );
- #endif
- return( 1 );
- }
- if( hdr->magic2 != MAGIC2 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" );
- #endif
- return( 1 );
- }
- if( hdr->alloc > 1 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" );
- #endif
- return( 1 );
- }
- if( hdr->prev != NULL && hdr->prev == hdr->next )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: prev == next\n" );
- #endif
- return( 1 );
- }
- if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" );
- #endif
- return( 1 );
- }
- return( 0 );
- }
- static int verify_chain()
- {
- memory_header *prv = heap.first, *cur = heap.first->next;
- if( verify_header( heap.first ) != 0 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: verification of first header "
- "failed\n" );
- #endif
- return( 1 );
- }
- if( heap.first->prev != NULL )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: verification failed: "
- "first->prev != NULL\n" );
- #endif
- return( 1 );
- }
- while( cur != NULL )
- {
- if( verify_header( cur ) != 0 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: verification of header "
- "failed\n" );
- #endif
- return( 1 );
- }
- if( cur->prev != prv )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: verification failed: "
- "cur->prev != prv\n" );
- #endif
- return( 1 );
- }
- prv = cur;
- cur = cur->next;
- }
- return( 0 );
- }
- static void *buffer_alloc_calloc( size_t n, size_t size )
- {
- memory_header *new, *cur = heap.first_free;
- unsigned char *p;
- void *ret;
- size_t original_len, len;
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- void *trace_buffer[MAX_BT];
- size_t trace_cnt;
- #endif
- if( heap.buf == NULL || heap.first == NULL )
- return( NULL );
- original_len = len = n * size;
- if( n != 0 && len / n != size )
- return( NULL );
- if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
- {
- len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
- len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
- }
- // Find block that fits
- //
- while( cur != NULL )
- {
- if( cur->size >= len )
- break;
- cur = cur->next_free;
- }
- if( cur == NULL )
- return( NULL );
- if( cur->alloc != 0 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated "
- "data\n" );
- #endif
- mbedtls_exit( 1 );
- }
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.alloc_count++;
- #endif
- // Found location, split block if > memory_header + 4 room left
- //
- if( cur->size - len < sizeof(memory_header) +
- MBEDTLS_MEMORY_ALIGN_MULTIPLE )
- {
- cur->alloc = 1;
- // Remove from free_list
- //
- if( cur->prev_free != NULL )
- cur->prev_free->next_free = cur->next_free;
- else
- heap.first_free = cur->next_free;
- if( cur->next_free != NULL )
- cur->next_free->prev_free = cur->prev_free;
- cur->prev_free = NULL;
- cur->next_free = NULL;
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.total_used += cur->size;
- if( heap.total_used > heap.maximum_used )
- heap.maximum_used = heap.total_used;
- #endif
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- trace_cnt = backtrace( trace_buffer, MAX_BT );
- cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
- cur->trace_count = trace_cnt;
- #endif
- if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
- mbedtls_exit( 1 );
- ret = (unsigned char *) cur + sizeof( memory_header );
- memset( ret, 0, original_len );
- return( ret );
- }
- p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
- new = (memory_header *) p;
- new->size = cur->size - len - sizeof(memory_header);
- new->alloc = 0;
- new->prev = cur;
- new->next = cur->next;
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- new->trace = NULL;
- new->trace_count = 0;
- #endif
- new->magic1 = MAGIC1;
- new->magic2 = MAGIC2;
- if( new->next != NULL )
- new->next->prev = new;
- // Replace cur with new in free_list
- //
- new->prev_free = cur->prev_free;
- new->next_free = cur->next_free;
- if( new->prev_free != NULL )
- new->prev_free->next_free = new;
- else
- heap.first_free = new;
- if( new->next_free != NULL )
- new->next_free->prev_free = new;
- cur->alloc = 1;
- cur->size = len;
- cur->next = new;
- cur->prev_free = NULL;
- cur->next_free = NULL;
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.header_count++;
- if( heap.header_count > heap.maximum_header_count )
- heap.maximum_header_count = heap.header_count;
- heap.total_used += cur->size;
- if( heap.total_used > heap.maximum_used )
- heap.maximum_used = heap.total_used;
- #endif
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- trace_cnt = backtrace( trace_buffer, MAX_BT );
- cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
- cur->trace_count = trace_cnt;
- #endif
- if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
- mbedtls_exit( 1 );
- ret = (unsigned char *) cur + sizeof( memory_header );
- memset( ret, 0, original_len );
- return( ret );
- }
- static void buffer_alloc_free( void *ptr )
- {
- memory_header *hdr, *old = NULL;
- unsigned char *p = (unsigned char *) ptr;
- if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
- return;
- if( p < heap.buf || p > heap.buf + heap.len )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
- "space\n" );
- #endif
- mbedtls_exit( 1 );
- }
- p -= sizeof(memory_header);
- hdr = (memory_header *) p;
- if( verify_header( hdr ) != 0 )
- mbedtls_exit( 1 );
- if( hdr->alloc != 1 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated "
- "data\n" );
- #endif
- mbedtls_exit( 1 );
- }
- hdr->alloc = 0;
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.free_count++;
- heap.total_used -= hdr->size;
- #endif
- // Regroup with block before
- //
- if( hdr->prev != NULL && hdr->prev->alloc == 0 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.header_count--;
- #endif
- hdr->prev->size += sizeof(memory_header) + hdr->size;
- hdr->prev->next = hdr->next;
- old = hdr;
- hdr = hdr->prev;
- if( hdr->next != NULL )
- hdr->next->prev = hdr;
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- free( old->trace );
- #endif
- memset( old, 0, sizeof(memory_header) );
- }
- // Regroup with block after
- //
- if( hdr->next != NULL && hdr->next->alloc == 0 )
- {
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.header_count--;
- #endif
- hdr->size += sizeof(memory_header) + hdr->next->size;
- old = hdr->next;
- hdr->next = hdr->next->next;
- if( hdr->prev_free != NULL || hdr->next_free != NULL )
- {
- if( hdr->prev_free != NULL )
- hdr->prev_free->next_free = hdr->next_free;
- else
- heap.first_free = hdr->next_free;
- if( hdr->next_free != NULL )
- hdr->next_free->prev_free = hdr->prev_free;
- }
- hdr->prev_free = old->prev_free;
- hdr->next_free = old->next_free;
- if( hdr->prev_free != NULL )
- hdr->prev_free->next_free = hdr;
- else
- heap.first_free = hdr;
- if( hdr->next_free != NULL )
- hdr->next_free->prev_free = hdr;
- if( hdr->next != NULL )
- hdr->next->prev = hdr;
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- free( old->trace );
- #endif
- memset( old, 0, sizeof(memory_header) );
- }
- // Prepend to free_list if we have not merged
- // (Does not have to stay in same order as prev / next list)
- //
- if( old == NULL )
- {
- hdr->next_free = heap.first_free;
- if( heap.first_free != NULL )
- heap.first_free->prev_free = hdr;
- heap.first_free = hdr;
- }
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- hdr->trace = NULL;
- hdr->trace_count = 0;
- #endif
- if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
- mbedtls_exit( 1 );
- }
- void mbedtls_memory_buffer_set_verify( int verify )
- {
- heap.verify = verify;
- }
- int mbedtls_memory_buffer_alloc_verify()
- {
- return verify_chain();
- }
- #if defined(MBEDTLS_MEMORY_DEBUG)
- void mbedtls_memory_buffer_alloc_status()
- {
- mbedtls_fprintf( stderr,
- "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
- "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
- heap.header_count, heap.total_used,
- heap.maximum_header_count, heap.maximum_used,
- heap.maximum_header_count * sizeof( memory_header )
- + heap.maximum_used,
- heap.alloc_count, heap.free_count );
- if( heap.first->next == NULL )
- mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
- else
- {
- mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
- debug_chain();
- }
- }
- void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
- {
- *max_used = heap.maximum_used;
- *max_blocks = heap.maximum_header_count;
- }
- void mbedtls_memory_buffer_alloc_max_reset( void )
- {
- heap.maximum_used = 0;
- heap.maximum_header_count = 0;
- }
- void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks )
- {
- *cur_used = heap.total_used;
- *cur_blocks = heap.header_count;
- }
- #endif /* MBEDTLS_MEMORY_DEBUG */
- #if defined(MBEDTLS_THREADING_C)
- static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
- {
- void *buf;
- if( mbedtls_mutex_lock( &heap.mutex ) != 0 )
- return( NULL );
- buf = buffer_alloc_calloc( n, size );
- if( mbedtls_mutex_unlock( &heap.mutex ) )
- return( NULL );
- return( buf );
- }
- static void buffer_alloc_free_mutexed( void *ptr )
- {
- /* We have to good option here, but corrupting the heap seems
- * worse than loosing memory. */
- if( mbedtls_mutex_lock( &heap.mutex ) )
- return;
- buffer_alloc_free( ptr );
- (void) mbedtls_mutex_unlock( &heap.mutex );
- }
- #endif /* MBEDTLS_THREADING_C */
- void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
- {
- memset( &heap, 0, sizeof(buffer_alloc_ctx) );
- memset( buf, 0, len );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &heap.mutex );
- mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
- buffer_alloc_free_mutexed );
- #else
- mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
- #endif
- if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
- {
- /* Adjust len first since buf is used in the computation */
- len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
- - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
- buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
- - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
- }
- heap.buf = buf;
- heap.len = len;
- heap.first = (memory_header *) buf;
- heap.first->size = len - sizeof(memory_header);
- heap.first->magic1 = MAGIC1;
- heap.first->magic2 = MAGIC2;
- heap.first_free = heap.first;
- }
- void mbedtls_memory_buffer_alloc_free()
- {
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &heap.mutex );
- #endif
- memory_zeroize( &heap, sizeof(buffer_alloc_ctx) );
- }
- #if defined(MBEDTLS_SELF_TEST)
- static int check_pointer( void *p )
- {
- if( p == NULL )
- return( -1 );
- if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
- return( -1 );
- return( 0 );
- }
- static int check_all_free( )
- {
- if(
- #if defined(MBEDTLS_MEMORY_DEBUG)
- heap.total_used != 0 ||
- #endif
- heap.first != heap.first_free ||
- (void *) heap.first != (void *) heap.buf )
- {
- return( -1 );
- }
- return( 0 );
- }
- #define TEST_ASSERT( condition ) \
- if( ! (condition) ) \
- { \
- if( verbose != 0 ) \
- mbedtls_printf( "failed\n" ); \
- \
- ret = 1; \
- goto cleanup; \
- }
- int mbedtls_memory_buffer_alloc_self_test( int verbose )
- {
- unsigned char buf[1024];
- unsigned char *p, *q, *r, *end;
- int ret = 0;
- if( verbose != 0 )
- mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " );
- mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
- p = mbedtls_calloc( 1, 1 );
- q = mbedtls_calloc( 1, 128 );
- r = mbedtls_calloc( 1, 16 );
- TEST_ASSERT( check_pointer( p ) == 0 &&
- check_pointer( q ) == 0 &&
- check_pointer( r ) == 0 );
- mbedtls_free( r );
- mbedtls_free( q );
- mbedtls_free( p );
- TEST_ASSERT( check_all_free( ) == 0 );
- /* Memorize end to compare with the next test */
- end = heap.buf + heap.len;
- mbedtls_memory_buffer_alloc_free( );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " MBA test #2 (buf not aligned): " );
- mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
- TEST_ASSERT( heap.buf + heap.len == end );
- p = mbedtls_calloc( 1, 1 );
- q = mbedtls_calloc( 1, 128 );
- r = mbedtls_calloc( 1, 16 );
- TEST_ASSERT( check_pointer( p ) == 0 &&
- check_pointer( q ) == 0 &&
- check_pointer( r ) == 0 );
- mbedtls_free( r );
- mbedtls_free( q );
- mbedtls_free( p );
- TEST_ASSERT( check_all_free( ) == 0 );
- mbedtls_memory_buffer_alloc_free( );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " MBA test #3 (full): " );
- mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
- p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) );
- TEST_ASSERT( check_pointer( p ) == 0 );
- TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
- mbedtls_free( p );
- p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
- q = mbedtls_calloc( 1, 16 );
- TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
- TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
- mbedtls_free( q );
- TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL );
- mbedtls_free( p );
- TEST_ASSERT( check_all_free( ) == 0 );
- mbedtls_memory_buffer_alloc_free( );
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- cleanup:
- mbedtls_memory_buffer_alloc_free( );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
- /********* Start of file library/net.c ************/
- /*
- * TCP/IP or UDP/IP networking functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_NET_C)
- #include <string.h>
- #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
- !defined(EFI32)
- #ifdef _WIN32_WINNT
- #undef _WIN32_WINNT
- #endif
- /* Enables getaddrinfo() & Co */
- #define _WIN32_WINNT 0x0501
- #include <ws2tcpip.h>
- #include <winsock2.h>
- #include <windows.h>
- #if defined(_MSC_VER)
- #if defined(_WIN32_WCE)
- #pragma comment( lib, "ws2.lib" )
- #else
- #pragma comment( lib, "ws2_32.lib" )
- #endif
- #endif /* _MSC_VER */
- /* Amalgamated Release Mappings */
- #undef read
- #undef write
- #undef close
- #define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0)
- #define write(fd,buf,len) send(fd,(char*)buf,(int) len,0)
- #define close(fd) closesocket(fd)
- static int wsa_init_done = 0;
- #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #if !VXWORKS
- #include <sys/time.h>
- #endif
- #include <unistd.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <netdb.h>
- #include <errno.h>
- #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
- /* Some MS functions want int and MSVC warns if we pass size_t,
- * but the standard fucntions use socklen_t, so cast only for MSVC */
- #if defined(_MSC_VER)
- #define MSVC_INT_CAST (int)
- #else
- #define MSVC_INT_CAST
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #if !VXWORKS
- #include <stdint.h>
- #endif
- /*
- * Prepare for using the sockets interface
- */
- static int net_prepare( void )
- {
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- WSADATA wsaData;
- if( wsa_init_done == 0 )
- {
- if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
- return( MBEDTLS_ERR_NET_SOCKET_FAILED );
- wsa_init_done = 1;
- }
- #else
- #if !defined(EFIX64) && !defined(EFI32)
- signal( SIGPIPE, SIG_IGN );
- #endif
- #endif
- return( 0 );
- }
- /*
- * Initialize a context
- */
- void mbedtls_net_init( mbedtls_net_context *ctx )
- {
- ctx->fd = -1;
- }
- /*
- * Initiate a TCP connection with host:port and the given protocol
- */
- int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
- {
- int ret;
- struct addrinfo hints, *addr_list, *cur;
- if( ( ret = net_prepare() ) != 0 )
- return( ret );
- /* Do name resolution with both IPv6 and IPv4 */
- memset( &hints, 0, sizeof( hints ) );
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
- hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
- if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
- return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
- /* Try the sockaddrs until a connection succeeds */
- ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
- for( cur = addr_list; cur != NULL; cur = cur->ai_next )
- {
- ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
- cur->ai_protocol );
- if( ctx->fd < 0 )
- {
- ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
- continue;
- }
- if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
- {
- ret = 0;
- break;
- }
- close( ctx->fd );
- ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
- }
- freeaddrinfo( addr_list );
- return( ret );
- }
- /*
- * Create a listening socket on bind_ip:port
- */
- int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
- {
- int n, ret;
- struct addrinfo hints, *addr_list, *cur;
- if( ( ret = net_prepare() ) != 0 )
- return( ret );
- /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
- memset( &hints, 0, sizeof( hints ) );
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
- hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
- if( bind_ip == NULL )
- hints.ai_flags = AI_PASSIVE;
- if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
- return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
- /* Try the sockaddrs until a binding succeeds */
- ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
- for( cur = addr_list; cur != NULL; cur = cur->ai_next )
- {
- ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
- cur->ai_protocol );
- if( ctx->fd < 0 )
- {
- ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
- continue;
- }
- n = 1;
- if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
- #if VXWORKS
- (char *) &n, sizeof( n ) ) != 0 )
- #else
- (const char *) &n, sizeof( n ) ) != 0 )
- #endif
- {
- close( ctx->fd );
- ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
- continue;
- }
- if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
- {
- close( ctx->fd );
- ret = MBEDTLS_ERR_NET_BIND_FAILED;
- continue;
- }
- /* Listen only makes sense for TCP */
- if( proto == MBEDTLS_NET_PROTO_TCP )
- {
- if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
- {
- close( ctx->fd );
- ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
- continue;
- }
- }
- /* I we ever get there, it's a success */
- ret = 0;
- break;
- }
- freeaddrinfo( addr_list );
- return( ret );
- }
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- /*
- * Check if the requested operation would be blocking on a non-blocking socket
- * and thus 'failed' with a negative return value.
- */
- static int net_would_block( const mbedtls_net_context *ctx )
- {
- ((void) ctx);
- return( WSAGetLastError() == WSAEWOULDBLOCK );
- }
- #else
- /*
- * Check if the requested operation would be blocking on a non-blocking socket
- * and thus 'failed' with a negative return value.
- *
- * Note: on a blocking socket this function always returns 0!
- */
- static int net_would_block( const mbedtls_net_context *ctx )
- {
- /*
- * Never return 'WOULD BLOCK' on a non-blocking socket
- */
- if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
- return( 0 );
- switch( errno )
- {
- #if defined EAGAIN
- case EAGAIN:
- #endif
- #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
- case EWOULDBLOCK:
- #endif
- return( 1 );
- }
- return( 0 );
- }
- #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
- /*
- * Accept a connection from a remote client
- */
- int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
- mbedtls_net_context *client_ctx,
- void *client_ip, size_t buf_size, size_t *ip_len )
- {
- int ret;
- int type;
- struct sockaddr_storage client_addr;
- #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
- defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
- socklen_t n = (socklen_t) sizeof( client_addr );
- socklen_t type_len = (socklen_t) sizeof( type );
- #else
- int n = (int) sizeof( client_addr );
- int type_len = (int) sizeof( type );
- #endif
- /* Is this a TCP or UDP socket? */
- if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
- (void *) &type, &type_len ) != 0 ||
- ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
- {
- return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
- }
- if( type == SOCK_STREAM )
- {
- /* TCP: actual accept() */
- ret = client_ctx->fd = (int) accept( bind_ctx->fd,
- (struct sockaddr *) &client_addr, &n );
- }
- else
- {
- /* UDP: wait for a message, but keep it in the queue */
- char buf[1] = { 0 };
- ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
- (struct sockaddr *) &client_addr, &n );
- #if defined(_WIN32)
- if( ret == SOCKET_ERROR &&
- WSAGetLastError() == WSAEMSGSIZE )
- {
- /* We know buf is too small, thanks, just peeking here */
- ret = 0;
- }
- #endif
- }
- if( ret < 0 )
- {
- if( net_would_block( bind_ctx ) != 0 )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
- }
- /* UDP: hijack the listening socket to communicate with the client,
- * then bind a new socket to accept new connections */
- if( type != SOCK_STREAM )
- {
- struct sockaddr_storage local_addr;
- int one = 1;
- if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
- return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
- client_ctx->fd = bind_ctx->fd;
- bind_ctx->fd = -1; /* In case we exit early */
- n = sizeof( struct sockaddr_storage );
- if( getsockname( client_ctx->fd,
- (struct sockaddr *) &local_addr, &n ) != 0 ||
- ( bind_ctx->fd = (int) socket( local_addr.ss_family,
- SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
- #if VXWORKS
- setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
- (char *) &one, sizeof( one ) ) != 0 )
- #else
- setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
- (const char *) &one, sizeof( one ) ) != 0 )
- #endif
- {
- return( MBEDTLS_ERR_NET_SOCKET_FAILED );
- }
- if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
- {
- return( MBEDTLS_ERR_NET_BIND_FAILED );
- }
- }
- if( client_ip != NULL )
- {
- if( client_addr.ss_family == AF_INET )
- {
- struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
- *ip_len = sizeof( addr4->sin_addr.s_addr );
- if( buf_size < *ip_len )
- return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
- memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
- }
- else
- {
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
- *ip_len = sizeof( addr6->sin6_addr.s6_addr );
- if( buf_size < *ip_len )
- return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
- memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
- }
- }
- return( 0 );
- }
- /*
- * Set the socket blocking or non-blocking
- */
- int mbedtls_net_set_block( mbedtls_net_context *ctx )
- {
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- u_long n = 0;
- return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
- #else
- return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
- #endif
- }
- int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
- {
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- u_long n = 1;
- return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
- #else
- return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
- #endif
- }
- /*
- * Portable usleep helper
- */
- void mbedtls_net_usleep( unsigned long usec )
- {
- #if defined(_WIN32)
- Sleep( ( usec + 999 ) / 1000 );
- #else
- struct timeval tv;
- tv.tv_sec = usec / 1000000;
- #if defined(__unix__) || defined(__unix) || \
- ( defined(__APPLE__) && defined(__MACH__) )
- tv.tv_usec = (suseconds_t) usec % 1000000;
- #else
- tv.tv_usec = usec % 1000000;
- #endif
- select( 0, NULL, NULL, NULL, &tv );
- #endif
- }
- /*
- * Read at most 'len' characters
- */
- int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
- {
- int ret;
- int fd = ((mbedtls_net_context *) ctx)->fd;
- if( fd < 0 )
- return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
- ret = (int) read( fd, buf, len );
- if( ret < 0 )
- {
- if( net_would_block( ctx ) != 0 )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- if( WSAGetLastError() == WSAECONNRESET )
- return( MBEDTLS_ERR_NET_CONN_RESET );
- #else
- if( errno == EPIPE || errno == ECONNRESET )
- return( MBEDTLS_ERR_NET_CONN_RESET );
- if( errno == EINTR )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- #endif
- return( MBEDTLS_ERR_NET_RECV_FAILED );
- }
- return( ret );
- }
- /*
- * Read at most 'len' characters, blocking for at most 'timeout' ms
- */
- int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
- uint32_t timeout )
- {
- int ret;
- struct timeval tv;
- fd_set read_fds;
- int fd = ((mbedtls_net_context *) ctx)->fd;
- if( fd < 0 )
- return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
- FD_ZERO( &read_fds );
- FD_SET( fd, &read_fds );
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = ( timeout % 1000 ) * 1000;
- ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
- /* Zero fds ready means we timed out */
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_TIMEOUT );
- if( ret < 0 )
- {
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- if( WSAGetLastError() == WSAEINTR )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- #else
- if( errno == EINTR )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- #endif
- return( MBEDTLS_ERR_NET_RECV_FAILED );
- }
- /* This call will not block */
- return( mbedtls_net_recv( ctx, buf, len ) );
- }
- /*
- * Write at most 'len' characters
- */
- int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
- {
- int ret;
- int fd = ((mbedtls_net_context *) ctx)->fd;
- if( fd < 0 )
- return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
- #if VXWORKS
- ret = (int) write( fd, (char*) buf, len );
- #else
- ret = (int) write( fd, buf, len );
- #endif
- if( ret < 0 )
- {
- if( net_would_block( ctx ) != 0 )
- return( MBEDTLS_ERR_SSL_WANT_WRITE );
- #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
- !defined(EFI32)
- if( WSAGetLastError() == WSAECONNRESET )
- return( MBEDTLS_ERR_NET_CONN_RESET );
- #else
- if( errno == EPIPE || errno == ECONNRESET )
- return( MBEDTLS_ERR_NET_CONN_RESET );
- if( errno == EINTR )
- return( MBEDTLS_ERR_SSL_WANT_WRITE );
- #endif
- return( MBEDTLS_ERR_NET_SEND_FAILED );
- }
- return( ret );
- }
- /*
- * Gracefully close the connection
- */
- void mbedtls_net_free( mbedtls_net_context *ctx )
- {
- if( ctx->fd == -1 )
- return;
- shutdown( ctx->fd, 2 );
- close( ctx->fd );
- ctx->fd = -1;
- }
- #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && !defined(EFI32)
- /* Amalgamated Release Mappings */
- #undef read
- #undef write
- #undef close
- #define read _read
- #define write _write
- #define close _close
- #endif
- #endif /* MBEDTLS_NET_C */
- /********* Start of file library/oid.c ************/
- /**
- * \file oid.c
- *
- * \brief Object Identifier (OID) database
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_OID_C)
- #include <stdio.h>
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #define mbedtls_snprintf snprintf
- #endif
- #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
- #endif
- /*
- * Macro to automatically add the size of #define'd OIDs
- */
- #define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s)
- /*
- * Macro to generate an internal function for oid_XXX_from_asn1() (used by
- * the other functions)
- */
- #define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \
- static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid ) \
- { \
- const TYPE_T *p = LIST; \
- const mbedtls_oid_descriptor_t *cur = (const mbedtls_oid_descriptor_t *) p; \
- if( p == NULL || oid == NULL ) return( NULL ); \
- while( cur->asn1 != NULL ) { \
- if( cur->asn1_len == oid->len && \
- memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \
- return( p ); \
- } \
- p++; \
- cur = (const mbedtls_oid_descriptor_t *) p; \
- } \
- return( NULL ); \
- }
- /*
- * Macro to generate a function for retrieving a single attribute from the
- * descriptor of an mbedtls_oid_descriptor_t wrapper.
- */
- #define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
- int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
- { \
- const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
- if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
- *ATTR1 = data->descriptor.ATTR1; \
- return( 0 ); \
- }
- /*
- * Macro to generate a function for retrieving a single attribute from an
- * mbedtls_oid_descriptor_t wrapper.
- */
- #define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
- int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \
- { \
- const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
- if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
- *ATTR1 = data->ATTR1; \
- return( 0 ); \
- }
- /*
- * Macro to generate a function for retrieving two attributes from an
- * mbedtls_oid_descriptor_t wrapper.
- */
- #define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
- ATTR2_TYPE, ATTR2) \
- int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \
- { \
- const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \
- if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \
- *ATTR1 = data->ATTR1; \
- *ATTR2 = data->ATTR2; \
- return( 0 ); \
- }
- /*
- * Macro to generate a function for retrieving the OID based on a single
- * attribute from a mbedtls_oid_descriptor_t wrapper.
- */
- #define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \
- int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \
- { \
- const TYPE_T *cur = LIST; \
- while( cur->descriptor.asn1 != NULL ) { \
- if( cur->ATTR1 == ATTR1 ) { \
- *oid = cur->descriptor.asn1; \
- *olen = cur->descriptor.asn1_len; \
- return( 0 ); \
- } \
- cur++; \
- } \
- return( MBEDTLS_ERR_OID_NOT_FOUND ); \
- }
- /*
- * Macro to generate a function for retrieving the OID based on two
- * attributes from a mbedtls_oid_descriptor_t wrapper.
- */
- #define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \
- ATTR2_TYPE, ATTR2) \
- int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
- size_t *olen ) \
- { \
- const TYPE_T *cur = LIST; \
- while( cur->descriptor.asn1 != NULL ) { \
- if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \
- *oid = cur->descriptor.asn1; \
- *olen = cur->descriptor.asn1_len; \
- return( 0 ); \
- } \
- cur++; \
- } \
- return( MBEDTLS_ERR_OID_NOT_FOUND ); \
- }
- /*
- * For X520 attribute types
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- const char *short_name;
- } oid_x520_attr_t;
- static const oid_x520_attr_t oid_x520_attr_type[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" },
- "CN",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" },
- "C",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" },
- "L",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" },
- "ST",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" },
- "O",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" },
- "OU",
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" },
- "emailAddress",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" },
- "serialNumber",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" },
- "postalAddress",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" },
- "postalCode",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" },
- "SN",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" },
- "GN",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" },
- "initials",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" },
- "generationQualifier",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" },
- "title",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" },
- "dnQualifier",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" },
- "pseudonym",
- },
- {
- { ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" },
- "DC",
- },
- {
- { ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" },
- "uniqueIdentifier",
- },
- {
- { NULL, 0, NULL, NULL },
- NULL,
- }
- };
- FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type)
- FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name)
- #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
- /*
- * For X509 extensions
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- int ext_type;
- } oid_x509_ext_t;
- static const oid_x509_ext_t oid_x509_ext[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
- MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
- },
- {
- { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
- MBEDTLS_X509_EXT_KEY_USAGE,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
- MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
- },
- {
- { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
- MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
- },
- {
- { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
- MBEDTLS_X509_EXT_NS_CERT_TYPE,
- },
- {
- { NULL, 0, NULL, NULL },
- 0,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext)
- FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type)
- static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
- {
- { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
- { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
- { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
- { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
- { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
- { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
- { NULL, 0, NULL, NULL },
- };
- FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
- FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
- #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
- #if defined(MBEDTLS_MD_C)
- /*
- * For SignatureAlgorithmIdentifier
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- mbedtls_md_type_t md_alg;
- mbedtls_pk_type_t pk_alg;
- } oid_sig_alg_t;
- static const oid_sig_alg_t oid_sig_alg[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" },
- MBEDTLS_MD_MD2, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" },
- MBEDTLS_MD_MD4, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" },
- MBEDTLS_MD_MD5, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" },
- MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" },
- MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" },
- MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" },
- MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" },
- MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" },
- MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" },
- MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" },
- MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" },
- MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" },
- MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" },
- MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" },
- MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS,
- },
- {
- { NULL, 0, NULL, NULL },
- MBEDTLS_MD_NONE, MBEDTLS_PK_NONE,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg)
- FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description)
- FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg)
- FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg)
- #endif /* MBEDTLS_MD_C */
- /*
- * For PublicKeyInfo (PKCS1, RFC 5480)
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- mbedtls_pk_type_t pk_alg;
- } oid_pk_alg_t;
- static const oid_pk_alg_t oid_pk_alg[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" },
- MBEDTLS_PK_RSA,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" },
- MBEDTLS_PK_ECKEY,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" },
- MBEDTLS_PK_ECKEY_DH,
- },
- {
- { NULL, 0, NULL, NULL },
- MBEDTLS_PK_NONE,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg)
- FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg)
- FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg)
- #if defined(MBEDTLS_ECP_C)
- /*
- * For namedCurve (RFC 5480)
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- mbedtls_ecp_group_id grp_id;
- } oid_ecp_grp_t;
- static const oid_ecp_grp_t oid_ecp_grp[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" },
- MBEDTLS_ECP_DP_SECP192R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" },
- MBEDTLS_ECP_DP_SECP224R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" },
- MBEDTLS_ECP_DP_SECP256R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" },
- MBEDTLS_ECP_DP_SECP384R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" },
- MBEDTLS_ECP_DP_SECP521R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" },
- MBEDTLS_ECP_DP_SECP192K1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" },
- MBEDTLS_ECP_DP_SECP224K1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" },
- MBEDTLS_ECP_DP_SECP256K1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" },
- MBEDTLS_ECP_DP_BP256R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" },
- MBEDTLS_ECP_DP_BP384R1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" },
- MBEDTLS_ECP_DP_BP512R1,
- },
- {
- { NULL, 0, NULL, NULL },
- MBEDTLS_ECP_DP_NONE,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp)
- FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id)
- FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id)
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_CIPHER_C)
- /*
- * For PKCS#5 PBES2 encryption algorithm
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- mbedtls_cipher_type_t cipher_alg;
- } oid_cipher_alg_t;
- static const oid_cipher_alg_t oid_cipher_alg[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" },
- MBEDTLS_CIPHER_DES_CBC,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" },
- MBEDTLS_CIPHER_DES_EDE3_CBC,
- },
- {
- { NULL, 0, NULL, NULL },
- MBEDTLS_CIPHER_NONE,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg)
- FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, mbedtls_cipher_type_t, cipher_alg)
- #endif /* MBEDTLS_CIPHER_C */
- #if defined(MBEDTLS_MD_C)
- /*
- * For digestAlgorithm
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- mbedtls_md_type_t md_alg;
- } oid_md_alg_t;
- static const oid_md_alg_t oid_md_alg[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" },
- MBEDTLS_MD_MD2,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" },
- MBEDTLS_MD_MD4,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" },
- MBEDTLS_MD_MD5,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" },
- MBEDTLS_MD_SHA1,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" },
- MBEDTLS_MD_SHA224,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" },
- MBEDTLS_MD_SHA256,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" },
- MBEDTLS_MD_SHA384,
- },
- {
- { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" },
- MBEDTLS_MD_SHA512,
- },
- {
- { NULL, 0, NULL, NULL },
- MBEDTLS_MD_NONE,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
- FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
- FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
- #endif /* MBEDTLS_MD_C */
- #if defined(MBEDTLS_PKCS12_C)
- /*
- * For PKCS#12 PBEs
- */
- typedef struct {
- mbedtls_oid_descriptor_t descriptor;
- mbedtls_md_type_t md_alg;
- mbedtls_cipher_type_t cipher_alg;
- } oid_pkcs12_pbe_alg_t;
- static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
- {
- {
- { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" },
- MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC,
- },
- {
- { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" },
- MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC,
- },
- {
- { NULL, 0, NULL, NULL },
- MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE,
- },
- };
- FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg)
- FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, mbedtls_md_type_t, md_alg, mbedtls_cipher_type_t, cipher_alg)
- #endif /* MBEDTLS_PKCS12_C */
- #define OID_SAFE_SNPRINTF \
- do { \
- if( ret < 0 || (size_t) ret >= n ) \
- return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \
- \
- n -= (size_t) ret; \
- p += (size_t) ret; \
- } while( 0 )
- /* Return the x.y.z.... style numeric string for the given OID */
- int mbedtls_oid_get_numeric_string( char *buf, size_t size,
- const mbedtls_asn1_buf *oid )
- {
- int ret;
- size_t i, n;
- unsigned int value;
- char *p;
- p = buf;
- n = size;
- /* First byte contains first two dots */
- if( oid->len > 0 )
- {
- ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
- OID_SAFE_SNPRINTF;
- }
- value = 0;
- for( i = 1; i < oid->len; i++ )
- {
- /* Prevent overflow in value. */
- if( ( ( value << 7 ) >> 7 ) != value )
- return( MBEDTLS_ERR_OID_BUF_TOO_SMALL );
- value <<= 7;
- value += oid->p[i] & 0x7F;
- if( !( oid->p[i] & 0x80 ) )
- {
- /* Last byte */
- ret = mbedtls_snprintf( p, n, ".%d", value );
- OID_SAFE_SNPRINTF;
- value = 0;
- }
- }
- return( (int) ( size - n ) );
- }
- /* Amalgamated Release Mappings */
- #undef SAFE_SNPRINTF
- #endif /* MBEDTLS_OID_C */
- /********* Start of file library/padlock.c ************/
- /*
- * VIA PadLock support functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * This implementation is based on the VIA PadLock Programming Guide:
- *
- * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
- * programming_guide.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PADLOCK_C)
- #include <string.h>
- #ifndef asm
- #define asm __asm
- #endif
- #if defined(MBEDTLS_HAVE_X86)
- /*
- * PadLock detection routine
- */
- int mbedtls_padlock_has_support( int feature )
- {
- static int flags = -1;
- int ebx = 0, edx = 0;
- if( flags == -1 )
- {
- asm( "movl %%ebx, %0 \n\t"
- "movl $0xC0000000, %%eax \n\t"
- "cpuid \n\t"
- "cmpl $0xC0000001, %%eax \n\t"
- "movl $0, %%edx \n\t"
- "jb unsupported \n\t"
- "movl $0xC0000001, %%eax \n\t"
- "cpuid \n\t"
- "unsupported: \n\t"
- "movl %%edx, %1 \n\t"
- "movl %2, %%ebx \n\t"
- : "=m" (ebx), "=m" (edx)
- : "m" (ebx)
- : "eax", "ecx", "edx" );
- flags = edx;
- }
- return( flags & feature );
- }
- /*
- * PadLock AES-ECB block en(de)cryption
- */
- int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- int ebx = 0;
- uint32_t *rk;
- uint32_t *blk;
- uint32_t *ctrl;
- unsigned char buf[256];
- rk = ctx->rk;
- blk = MBEDTLS_PADLOCK_ALIGN16( buf );
- memcpy( blk, input, 16 );
- ctrl = blk + 4;
- *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );
- asm( "pushfl \n\t"
- "popfl \n\t"
- "movl %%ebx, %0 \n\t"
- "movl $1, %%ecx \n\t"
- "movl %2, %%edx \n\t"
- "movl %3, %%ebx \n\t"
- "movl %4, %%esi \n\t"
- "movl %4, %%edi \n\t"
- ".byte 0xf3,0x0f,0xa7,0xc8 \n\t"
- "movl %1, %%ebx \n\t"
- : "=m" (ebx)
- : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
- : "memory", "ecx", "edx", "esi", "edi" );
- memcpy( output, blk, 16 );
- return( 0 );
- }
- /*
- * PadLock AES-CBC buffer en(de)cryption
- */
- int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
- {
- int ebx = 0;
- size_t count;
- uint32_t *rk;
- uint32_t *iw;
- uint32_t *ctrl;
- unsigned char buf[256];
- if( ( (long) input & 15 ) != 0 ||
- ( (long) output & 15 ) != 0 )
- return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED );
- rk = ctx->rk;
- iw = MBEDTLS_PADLOCK_ALIGN16( buf );
- memcpy( iw, iv, 16 );
- ctrl = iw + 4;
- *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 );
- count = ( length + 15 ) >> 4;
- asm( "pushfl \n\t"
- "popfl \n\t"
- "movl %%ebx, %0 \n\t"
- "movl %2, %%ecx \n\t"
- "movl %3, %%edx \n\t"
- "movl %4, %%ebx \n\t"
- "movl %5, %%esi \n\t"
- "movl %6, %%edi \n\t"
- "movl %7, %%eax \n\t"
- ".byte 0xf3,0x0f,0xa7,0xd0 \n\t"
- "movl %1, %%ebx \n\t"
- : "=m" (ebx)
- : "m" (ebx), "m" (count), "m" (ctrl),
- "m" (rk), "m" (input), "m" (output), "m" (iw)
- : "memory", "eax", "ecx", "edx", "esi", "edi" );
- memcpy( iv, iw, 16 );
- return( 0 );
- }
- #endif /* MBEDTLS_HAVE_X86 */
- #endif /* MBEDTLS_PADLOCK_C */
- /********* Start of file library/pem.c ************/
- /*
- * Privacy Enhanced Mail (PEM) decoding
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void pem_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #if defined(MBEDTLS_PEM_PARSE_C)
- void mbedtls_pem_init( mbedtls_pem_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_pem_context ) );
- }
- #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
- /*
- * Read a 16-byte hex string and convert it to binary
- */
- static int pem_get_iv( const unsigned char *s, unsigned char *iv,
- size_t iv_len )
- {
- size_t i, j, k;
- memset( iv, 0, iv_len );
- for( i = 0; i < iv_len * 2; i++, s++ )
- {
- if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
- if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
- if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
- return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
- k = ( ( i & 1 ) != 0 ) ? j : j << 4;
- iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
- }
- return( 0 );
- }
- static void pem_pbkdf1( unsigned char *key, size_t keylen,
- unsigned char *iv,
- const unsigned char *pwd, size_t pwdlen )
- {
- mbedtls_md5_context md5_ctx;
- unsigned char md5sum[16];
- size_t use_len;
- mbedtls_md5_init( &md5_ctx );
- /*
- * key[ 0..15] = MD5(pwd || IV)
- */
- mbedtls_md5_starts( &md5_ctx );
- mbedtls_md5_update( &md5_ctx, pwd, pwdlen );
- mbedtls_md5_update( &md5_ctx, iv, 8 );
- mbedtls_md5_finish( &md5_ctx, md5sum );
- if( keylen <= 16 )
- {
- memcpy( key, md5sum, keylen );
- mbedtls_md5_free( &md5_ctx );
- pem_zeroize( md5sum, 16 );
- return;
- }
- memcpy( key, md5sum, 16 );
- /*
- * key[16..23] = MD5(key[ 0..15] || pwd || IV])
- */
- mbedtls_md5_starts( &md5_ctx );
- mbedtls_md5_update( &md5_ctx, md5sum, 16 );
- mbedtls_md5_update( &md5_ctx, pwd, pwdlen );
- mbedtls_md5_update( &md5_ctx, iv, 8 );
- mbedtls_md5_finish( &md5_ctx, md5sum );
- use_len = 16;
- if( keylen < 32 )
- use_len = keylen - 16;
- memcpy( key + 16, md5sum, use_len );
- mbedtls_md5_free( &md5_ctx );
- pem_zeroize( md5sum, 16 );
- }
- #if defined(MBEDTLS_DES_C)
- /*
- * Decrypt with DES-CBC, using PBKDF1 for key derivation
- */
- static void pem_des_decrypt( unsigned char des_iv[8],
- unsigned char *buf, size_t buflen,
- const unsigned char *pwd, size_t pwdlen )
- {
- mbedtls_des_context des_ctx;
- unsigned char des_key[8];
- mbedtls_des_init( &des_ctx );
- pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen );
- mbedtls_des_setkey_dec( &des_ctx, des_key );
- mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen,
- des_iv, buf, buf );
- mbedtls_des_free( &des_ctx );
- pem_zeroize( des_key, 8 );
- }
- /*
- * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
- */
- static void pem_des3_decrypt( unsigned char des3_iv[8],
- unsigned char *buf, size_t buflen,
- const unsigned char *pwd, size_t pwdlen )
- {
- mbedtls_des3_context des3_ctx;
- unsigned char des3_key[24];
- mbedtls_des3_init( &des3_ctx );
- pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen );
- mbedtls_des3_set3key_dec( &des3_ctx, des3_key );
- mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
- des3_iv, buf, buf );
- mbedtls_des3_free( &des3_ctx );
- pem_zeroize( des3_key, 24 );
- }
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_AES_C)
- /*
- * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
- */
- static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
- unsigned char *buf, size_t buflen,
- const unsigned char *pwd, size_t pwdlen )
- {
- mbedtls_aes_context aes_ctx;
- unsigned char aes_key[32];
- mbedtls_aes_init( &aes_ctx );
- pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen );
- mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 );
- mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
- aes_iv, buf, buf );
- mbedtls_aes_free( &aes_ctx );
- pem_zeroize( aes_key, keylen );
- }
- #endif /* MBEDTLS_AES_C */
- #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
- int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
- const unsigned char *data, const unsigned char *pwd,
- size_t pwdlen, size_t *use_len )
- {
- int ret, enc;
- size_t len;
- unsigned char *buf;
- const unsigned char *s1, *s2, *end;
- #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
- unsigned char pem_iv[16];
- mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE;
- #else
- ((void) pwd);
- ((void) pwdlen);
- #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
- if( ctx == NULL )
- return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA );
- s1 = (unsigned char *) strstr( (const char *) data, header );
- if( s1 == NULL )
- return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
- s2 = (unsigned char *) strstr( (const char *) data, footer );
- if( s2 == NULL || s2 <= s1 )
- return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
- s1 += strlen( header );
- if( *s1 == ' ' ) s1++;
- if( *s1 == '\r' ) s1++;
- if( *s1 == '\n' ) s1++;
- else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
- end = s2;
- end += strlen( footer );
- if( *end == ' ' ) end++;
- if( *end == '\r' ) end++;
- if( *end == '\n' ) end++;
- *use_len = end - data;
- enc = 0;
- if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
- {
- #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
- enc++;
- s1 += 22;
- if( *s1 == '\r' ) s1++;
- if( *s1 == '\n' ) s1++;
- else return( MBEDTLS_ERR_PEM_INVALID_DATA );
- #if defined(MBEDTLS_DES_C)
- if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
- {
- enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
- s1 += 23;
- if( pem_get_iv( s1, pem_iv, 8 ) != 0 )
- return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
- s1 += 16;
- }
- else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
- {
- enc_alg = MBEDTLS_CIPHER_DES_CBC;
- s1 += 18;
- if( pem_get_iv( s1, pem_iv, 8) != 0 )
- return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
- s1 += 16;
- }
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_AES_C)
- if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
- {
- if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
- enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
- else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
- enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
- else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
- enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
- else
- return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
- s1 += 22;
- if( pem_get_iv( s1, pem_iv, 16 ) != 0 )
- return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
- s1 += 32;
- }
- #endif /* MBEDTLS_AES_C */
- if( enc_alg == MBEDTLS_CIPHER_NONE )
- return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
- if( *s1 == '\r' ) s1++;
- if( *s1 == '\n' ) s1++;
- else return( MBEDTLS_ERR_PEM_INVALID_DATA );
- #else
- return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
- #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
- }
- if( s1 == s2 )
- return( MBEDTLS_ERR_PEM_INVALID_DATA );
- ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
- if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
- return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
- if( ( buf = mbedtls_calloc( 1, len ) ) == NULL )
- return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
- if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
- {
- mbedtls_free( buf );
- return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
- }
- if( enc != 0 )
- {
- #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
- if( pwd == NULL )
- {
- mbedtls_free( buf );
- return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
- }
- #if defined(MBEDTLS_DES_C)
- if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC )
- pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
- else if( enc_alg == MBEDTLS_CIPHER_DES_CBC )
- pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_AES_C)
- if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC )
- pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
- else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC )
- pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
- else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC )
- pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
- #endif /* MBEDTLS_AES_C */
- /*
- * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
- * length bytes (allow 4 to be sure) in all known use cases.
- *
- * Use that as heurisitic to try detecting password mismatchs.
- */
- if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
- {
- mbedtls_free( buf );
- return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
- }
- #else
- mbedtls_free( buf );
- return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
- #endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
- }
- ctx->buf = buf;
- ctx->buflen = len;
- return( 0 );
- }
- void mbedtls_pem_free( mbedtls_pem_context *ctx )
- {
- mbedtls_free( ctx->buf );
- mbedtls_free( ctx->info );
- pem_zeroize( ctx, sizeof( mbedtls_pem_context ) );
- }
- #endif /* MBEDTLS_PEM_PARSE_C */
- #if defined(MBEDTLS_PEM_WRITE_C)
- int mbedtls_pem_write_buffer( const char *header, const char *footer,
- const unsigned char *der_data, size_t der_len,
- unsigned char *buf, size_t buf_len, size_t *olen )
- {
- int ret;
- unsigned char *encode_buf, *c, *p = buf;
- size_t len = 0, use_len, add_len = 0;
- mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
- add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1;
- if( use_len + add_len > buf_len )
- {
- *olen = use_len + add_len;
- return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
- }
- if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL )
- return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
- if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
- der_len ) ) != 0 )
- {
- mbedtls_free( encode_buf );
- return( ret );
- }
- memcpy( p, header, strlen( header ) );
- p += strlen( header );
- c = encode_buf;
- while( use_len )
- {
- len = ( use_len > 64 ) ? 64 : use_len;
- memcpy( p, c, len );
- use_len -= len;
- p += len;
- c += len;
- *p++ = '\n';
- }
- memcpy( p, footer, strlen( footer ) );
- p += strlen( footer );
- *p++ = '\0';
- *olen = p - buf;
- mbedtls_free( encode_buf );
- return( 0 );
- }
- #endif /* MBEDTLS_PEM_WRITE_C */
- #endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
- /********* Start of file library/pk.c ************/
- /*
- * Public Key abstraction layer
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PK_C)
- #if defined(MBEDTLS_RSA_C)
- #endif
- #if defined(MBEDTLS_ECP_C)
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void pk_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Initialise a mbedtls_pk_context
- */
- void mbedtls_pk_init( mbedtls_pk_context *ctx )
- {
- if( ctx == NULL )
- return;
- ctx->pk_info = NULL;
- ctx->pk_ctx = NULL;
- }
- /*
- * Free (the components of) a mbedtls_pk_context
- */
- void mbedtls_pk_free( mbedtls_pk_context *ctx )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return;
- ctx->pk_info->ctx_free_func( ctx->pk_ctx );
- pk_zeroize( ctx, sizeof( mbedtls_pk_context ) );
- }
- /*
- * Get pk_info structure from type
- */
- const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
- {
- switch( pk_type ) {
- #if defined(MBEDTLS_RSA_C)
- case MBEDTLS_PK_RSA:
- return( &mbedtls_rsa_info );
- #endif
- #if defined(MBEDTLS_ECP_C)
- case MBEDTLS_PK_ECKEY:
- return( &mbedtls_eckey_info );
- case MBEDTLS_PK_ECKEY_DH:
- return( &mbedtls_eckeydh_info );
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- case MBEDTLS_PK_ECDSA:
- return( &mbedtls_ecdsa_info );
- #endif
- /* MBEDTLS_PK_RSA_ALT omitted on purpose */
- default:
- return( NULL );
- }
- }
- /*
- * Initialise context
- */
- int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
- {
- if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_PK_ALLOC_FAILED );
- ctx->pk_info = info;
- return( 0 );
- }
- #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
- /*
- * Initialize an RSA-alt context
- */
- int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
- mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
- mbedtls_pk_rsa_alt_sign_func sign_func,
- mbedtls_pk_rsa_alt_key_len_func key_len_func )
- {
- mbedtls_rsa_alt_context *rsa_alt;
- const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
- if( ctx == NULL || ctx->pk_info != NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_PK_ALLOC_FAILED );
- ctx->pk_info = info;
- rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
- rsa_alt->key = key;
- rsa_alt->decrypt_func = decrypt_func;
- rsa_alt->sign_func = sign_func;
- rsa_alt->key_len_func = key_len_func;
- return( 0 );
- }
- #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
- /*
- * Tell if a PK can do the operations of the given type
- */
- int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
- {
- /* null or NONE context can't do anything */
- if( ctx == NULL || ctx->pk_info == NULL )
- return( 0 );
- return( ctx->pk_info->can_do( type ) );
- }
- /*
- * Helper for mbedtls_pk_sign and mbedtls_pk_verify
- */
- static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
- {
- const mbedtls_md_info_t *md_info;
- if( *hash_len != 0 )
- return( 0 );
- if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
- return( -1 );
- *hash_len = mbedtls_md_get_size( md_info );
- return( 0 );
- }
- /*
- * Verify a signature
- */
- int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len )
- {
- if( ctx == NULL || ctx->pk_info == NULL ||
- pk_hashlen_helper( md_alg, &hash_len ) != 0 )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ctx->pk_info->verify_func == NULL )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
- sig, sig_len ) );
- }
- /*
- * Verify a signature with options
- */
- int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
- mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ! mbedtls_pk_can_do( ctx, type ) )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- if( type == MBEDTLS_PK_RSASSA_PSS )
- {
- #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
- int ret;
- const mbedtls_pk_rsassa_pss_options *pss_opts;
- if( options == NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
- if( sig_len < mbedtls_pk_get_len( ctx ) )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
- NULL, NULL, MBEDTLS_RSA_PUBLIC,
- md_alg, (unsigned int) hash_len, hash,
- pss_opts->mgf1_hash_id,
- pss_opts->expected_salt_len,
- sig );
- if( ret != 0 )
- return( ret );
- if( sig_len > mbedtls_pk_get_len( ctx ) )
- return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
- return( 0 );
- #else
- return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- #endif
- }
- /* General case: no options */
- if( options != NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
- }
- /*
- * Make a signature
- */
- int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- if( ctx == NULL || ctx->pk_info == NULL ||
- pk_hashlen_helper( md_alg, &hash_len ) != 0 )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ctx->pk_info->sign_func == NULL )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
- sig, sig_len, f_rng, p_rng ) );
- }
- /*
- * Decrypt message
- */
- int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen, size_t osize,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ctx->pk_info->decrypt_func == NULL )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
- output, olen, osize, f_rng, p_rng ) );
- }
- /*
- * Encrypt message
- */
- int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen, size_t osize,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ctx->pk_info->encrypt_func == NULL )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
- output, olen, osize, f_rng, p_rng ) );
- }
- /*
- * Check public-private key pair
- */
- int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
- {
- if( pub == NULL || pub->pk_info == NULL ||
- prv == NULL || prv->pk_info == NULL ||
- prv->pk_info->check_pair_func == NULL )
- {
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- }
- if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
- {
- if( pub->pk_info->type != MBEDTLS_PK_RSA )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- }
- else
- {
- if( pub->pk_info != prv->pk_info )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- }
- return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
- }
- /*
- * Get key size in bits
- */
- size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( 0 );
- return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
- }
- /*
- * Export debug information
- */
- int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- if( ctx->pk_info->debug_func == NULL )
- return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
- ctx->pk_info->debug_func( ctx->pk_ctx, items );
- return( 0 );
- }
- /*
- * Access the PK type name
- */
- const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( "invalid PK" );
- return( ctx->pk_info->name );
- }
- /*
- * Access the PK type
- */
- mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
- {
- if( ctx == NULL || ctx->pk_info == NULL )
- return( MBEDTLS_PK_NONE );
- return( ctx->pk_info->type );
- }
- #endif /* MBEDTLS_PK_C */
- /********* Start of file library/pk_wrap.c ************/
- /*
- * Public Key abstraction layer: wrapper functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PK_C)
- /* Even if RSA not activated, for the sake of RSA-alt */
- #include <string.h>
- #if defined(MBEDTLS_ECP_C)
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
- /* Implementation that should never be optimized out by the compiler */
- static void pk_wrap_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #endif
- #if defined(MBEDTLS_RSA_C)
- static int rsa_can_do( mbedtls_pk_type_t type )
- {
- return( type == MBEDTLS_PK_RSA ||
- type == MBEDTLS_PK_RSASSA_PSS );
- }
- static size_t rsa_get_bitlen( const void *ctx )
- {
- return( 8 * ((const mbedtls_rsa_context *) ctx)->len );
- }
- static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len )
- {
- int ret;
- if( sig_len < ((mbedtls_rsa_context *) ctx)->len )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL,
- MBEDTLS_RSA_PUBLIC, md_alg,
- (unsigned int) hash_len, hash, sig ) ) != 0 )
- return( ret );
- if( sig_len > ((mbedtls_rsa_context *) ctx)->len )
- return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
- return( 0 );
- }
- static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- *sig_len = ((mbedtls_rsa_context *) ctx)->len;
- return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
- md_alg, (unsigned int) hash_len, hash, sig ) );
- }
- static int rsa_decrypt_wrap( void *ctx,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen, size_t osize,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- if( ilen != ((mbedtls_rsa_context *) ctx)->len )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng,
- MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
- }
- static int rsa_encrypt_wrap( void *ctx,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen, size_t osize,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- *olen = ((mbedtls_rsa_context *) ctx)->len;
- if( *olen > osize )
- return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
- return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx,
- f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) );
- }
- static int rsa_check_pair_wrap( const void *pub, const void *prv )
- {
- return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
- (const mbedtls_rsa_context *) prv ) );
- }
- static void *rsa_alloc_wrap( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
- if( ctx != NULL )
- mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
- return( ctx );
- }
- static void rsa_free_wrap( void *ctx )
- {
- mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
- mbedtls_free( ctx );
- }
- static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
- {
- items->type = MBEDTLS_PK_DEBUG_MPI;
- items->name = "rsa.N";
- items->value = &( ((mbedtls_rsa_context *) ctx)->N );
- items++;
- items->type = MBEDTLS_PK_DEBUG_MPI;
- items->name = "rsa.E";
- items->value = &( ((mbedtls_rsa_context *) ctx)->E );
- }
- const mbedtls_pk_info_t mbedtls_rsa_info = {
- MBEDTLS_PK_RSA,
- "RSA",
- rsa_get_bitlen,
- rsa_can_do,
- rsa_verify_wrap,
- rsa_sign_wrap,
- rsa_decrypt_wrap,
- rsa_encrypt_wrap,
- rsa_check_pair_wrap,
- rsa_alloc_wrap,
- rsa_free_wrap,
- rsa_debug,
- };
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- /*
- * Generic EC key
- */
- static int eckey_can_do( mbedtls_pk_type_t type )
- {
- return( type == MBEDTLS_PK_ECKEY ||
- type == MBEDTLS_PK_ECKEY_DH ||
- type == MBEDTLS_PK_ECDSA );
- }
- static size_t eckey_get_bitlen( const void *ctx )
- {
- return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
- }
- #if defined(MBEDTLS_ECDSA_C)
- /* Forward declarations */
- static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len );
- static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
- static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len )
- {
- int ret;
- mbedtls_ecdsa_context ecdsa;
- mbedtls_ecdsa_init( &ecdsa );
- if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
- ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
- mbedtls_ecdsa_free( &ecdsa );
- return( ret );
- }
- static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret;
- mbedtls_ecdsa_context ecdsa;
- mbedtls_ecdsa_init( &ecdsa );
- if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
- ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
- f_rng, p_rng );
- mbedtls_ecdsa_free( &ecdsa );
- return( ret );
- }
- #endif /* MBEDTLS_ECDSA_C */
- static int eckey_check_pair( const void *pub, const void *prv )
- {
- return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
- (const mbedtls_ecp_keypair *) prv ) );
- }
- static void *eckey_alloc_wrap( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
- if( ctx != NULL )
- mbedtls_ecp_keypair_init( ctx );
- return( ctx );
- }
- static void eckey_free_wrap( void *ctx )
- {
- mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
- mbedtls_free( ctx );
- }
- static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
- {
- items->type = MBEDTLS_PK_DEBUG_ECP;
- items->name = "eckey.Q";
- items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
- }
- const mbedtls_pk_info_t mbedtls_eckey_info = {
- MBEDTLS_PK_ECKEY,
- "EC",
- eckey_get_bitlen,
- eckey_can_do,
- #if defined(MBEDTLS_ECDSA_C)
- eckey_verify_wrap,
- eckey_sign_wrap,
- #else
- NULL,
- NULL,
- #endif
- NULL,
- NULL,
- eckey_check_pair,
- eckey_alloc_wrap,
- eckey_free_wrap,
- eckey_debug,
- };
- /*
- * EC key restricted to ECDH
- */
- static int eckeydh_can_do( mbedtls_pk_type_t type )
- {
- return( type == MBEDTLS_PK_ECKEY ||
- type == MBEDTLS_PK_ECKEY_DH );
- }
- const mbedtls_pk_info_t mbedtls_eckeydh_info = {
- MBEDTLS_PK_ECKEY_DH,
- "EC_DH",
- eckey_get_bitlen, /* Same underlying key structure */
- eckeydh_can_do,
- NULL,
- NULL,
- NULL,
- NULL,
- eckey_check_pair,
- eckey_alloc_wrap, /* Same underlying key structure */
- eckey_free_wrap, /* Same underlying key structure */
- eckey_debug, /* Same underlying key structure */
- };
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_ECDSA_C)
- static int ecdsa_can_do( mbedtls_pk_type_t type )
- {
- return( type == MBEDTLS_PK_ECDSA );
- }
- static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- const unsigned char *sig, size_t sig_len )
- {
- int ret;
- ((void) md_alg);
- ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
- hash, hash_len, sig, sig_len );
- if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
- return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
- return( ret );
- }
- static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
- md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
- }
- static void *ecdsa_alloc_wrap( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
- if( ctx != NULL )
- mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
- return( ctx );
- }
- static void ecdsa_free_wrap( void *ctx )
- {
- mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
- mbedtls_free( ctx );
- }
- const mbedtls_pk_info_t mbedtls_ecdsa_info = {
- MBEDTLS_PK_ECDSA,
- "ECDSA",
- eckey_get_bitlen, /* Compatible key structures */
- ecdsa_can_do,
- ecdsa_verify_wrap,
- ecdsa_sign_wrap,
- NULL,
- NULL,
- eckey_check_pair, /* Compatible key structures */
- ecdsa_alloc_wrap,
- ecdsa_free_wrap,
- eckey_debug, /* Compatible key structures */
- };
- #endif /* MBEDTLS_ECDSA_C */
- #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
- /*
- * Support for alternative RSA-private implementations
- */
- static int rsa_alt_can_do( mbedtls_pk_type_t type )
- {
- return( type == MBEDTLS_PK_RSA );
- }
- static size_t rsa_alt_get_bitlen( const void *ctx )
- {
- const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
- return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
- }
- static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
- const unsigned char *hash, size_t hash_len,
- unsigned char *sig, size_t *sig_len,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
- *sig_len = rsa_alt->key_len_func( rsa_alt->key );
- return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
- md_alg, (unsigned int) hash_len, hash, sig ) );
- }
- static int rsa_alt_decrypt_wrap( void *ctx,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen, size_t osize,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
- ((void) f_rng);
- ((void) p_rng);
- if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- return( rsa_alt->decrypt_func( rsa_alt->key,
- MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
- }
- #if defined(MBEDTLS_RSA_C)
- static int rsa_alt_check_pair( const void *pub, const void *prv )
- {
- unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
- unsigned char hash[32];
- size_t sig_len = 0;
- int ret;
- if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- memset( hash, 0x2a, sizeof( hash ) );
- if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
- hash, sizeof( hash ),
- sig, &sig_len, NULL, NULL ) ) != 0 )
- {
- return( ret );
- }
- if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
- hash, sizeof( hash ), sig, sig_len ) != 0 )
- {
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_RSA_C */
- static void *rsa_alt_alloc_wrap( void )
- {
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
- if( ctx != NULL )
- memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
- return( ctx );
- }
- static void rsa_alt_free_wrap( void *ctx )
- {
- pk_wrap_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
- mbedtls_free( ctx );
- }
- const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
- MBEDTLS_PK_RSA_ALT,
- "RSA-alt",
- rsa_alt_get_bitlen,
- rsa_alt_can_do,
- NULL,
- rsa_alt_sign_wrap,
- rsa_alt_decrypt_wrap,
- NULL,
- #if defined(MBEDTLS_RSA_C)
- rsa_alt_check_pair,
- #else
- NULL,
- #endif
- rsa_alt_alloc_wrap,
- rsa_alt_free_wrap,
- NULL,
- };
- #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
- #endif /* MBEDTLS_PK_C */
- /********* Start of file library/pkcs11.c ************/
- /**
- * \file pkcs11.c
- *
- * \brief Wrapper for PKCS#11 library libpkcs11-helper
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if defined(MBEDTLS_PKCS11_C)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #include <string.h>
- void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) );
- }
- int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
- {
- int ret = 1;
- unsigned char *cert_blob = NULL;
- size_t cert_blob_size = 0;
- if( cert == NULL )
- {
- ret = 2;
- goto cleanup;
- }
- if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
- &cert_blob_size ) != CKR_OK )
- {
- ret = 3;
- goto cleanup;
- }
- cert_blob = mbedtls_calloc( 1, cert_blob_size );
- if( NULL == cert_blob )
- {
- ret = 4;
- goto cleanup;
- }
- if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
- &cert_blob_size ) != CKR_OK )
- {
- ret = 5;
- goto cleanup;
- }
- if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) )
- {
- ret = 6;
- goto cleanup;
- }
- ret = 0;
- cleanup:
- if( NULL != cert_blob )
- mbedtls_free( cert_blob );
- return( ret );
- }
- int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
- pkcs11h_certificate_t pkcs11_cert )
- {
- int ret = 1;
- mbedtls_x509_crt cert;
- mbedtls_x509_crt_init( &cert );
- if( priv_key == NULL )
- goto cleanup;
- if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) )
- goto cleanup;
- priv_key->len = mbedtls_pk_get_len( &cert.pk );
- priv_key->pkcs11h_cert = pkcs11_cert;
- ret = 0;
- cleanup:
- mbedtls_x509_crt_free( &cert );
- return( ret );
- }
- void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
- {
- if( NULL != priv_key )
- pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
- }
- int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
- int mode, size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len )
- {
- size_t input_len, output_len;
- if( NULL == ctx )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( MBEDTLS_RSA_PRIVATE != mode )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- output_len = input_len = ctx->len;
- if( input_len < 16 || input_len > output_max_len )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- /* Determine size of output buffer */
- if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
- input_len, NULL, &output_len ) != CKR_OK )
- {
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- }
- if( output_len > output_max_len )
- return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
- if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
- input_len, output, &output_len ) != CKR_OK )
- {
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- }
- *olen = output_len;
- return( 0 );
- }
- int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig )
- {
- size_t sig_len = 0, asn_len = 0, oid_size = 0;
- unsigned char *p = sig;
- const char *oid;
- if( NULL == ctx )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( MBEDTLS_RSA_PRIVATE != mode )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( md_alg != MBEDTLS_MD_NONE )
- {
- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hashlen = mbedtls_md_get_size( md_info );
- asn_len = 10 + oid_size;
- }
- sig_len = ctx->len;
- if( hashlen > sig_len || asn_len > sig_len ||
- hashlen + asn_len > sig_len )
- {
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- }
- if( md_alg != MBEDTLS_MD_NONE )
- {
- /*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm DigestAlgorithmIdentifier,
- * digest Digest }
- *
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Digest ::= OCTET STRING
- */
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
- *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
- *p++ = (unsigned char) ( 0x04 + oid_size );
- *p++ = MBEDTLS_ASN1_OID;
- *p++ = oid_size & 0xFF;
- memcpy( p, oid, oid_size );
- p += oid_size;
- *p++ = MBEDTLS_ASN1_NULL;
- *p++ = 0x00;
- *p++ = MBEDTLS_ASN1_OCTET_STRING;
- *p++ = hashlen;
- }
- memcpy( p, hash, hashlen );
- if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
- asn_len + hashlen, sig, &sig_len ) != CKR_OK )
- {
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- }
- return( 0 );
- }
- #endif /* defined(MBEDTLS_PKCS11_C) */
- /********* Start of file library/pkcs12.c ************/
- /*
- * PKCS#12 Personal Information Exchange Syntax
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The PKCS #12 Personal Information Exchange Syntax Standard v1.1
- *
- * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
- * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PKCS12_C)
- #include <string.h>
- #if defined(MBEDTLS_ARC4_C)
- #endif
- #if defined(MBEDTLS_DES_C)
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void pkcs_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
- mbedtls_asn1_buf *salt, int *iterations )
- {
- int ret;
- unsigned char **p = ¶ms->p;
- const unsigned char *end = params->p + params->len;
- /*
- * pkcs-12PbeParams ::= SEQUENCE {
- * salt OCTET STRING,
- * iterations INTEGER
- * }
- *
- */
- if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
- salt->p = *p;
- *p += salt->len;
- if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
- if( *p != end )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- #define PKCS12_MAX_PWDLEN 128
- static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
- const unsigned char *pwd, size_t pwdlen,
- unsigned char *key, size_t keylen,
- unsigned char *iv, size_t ivlen )
- {
- int ret, iterations;
- mbedtls_asn1_buf salt;
- size_t i;
- unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
- if( pwdlen > PKCS12_MAX_PWDLEN )
- return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
- memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
- memset( &unipwd, 0, sizeof(unipwd) );
- if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt,
- &iterations ) ) != 0 )
- return( ret );
- for( i = 0; i < pwdlen; i++ )
- unipwd[i * 2 + 1] = pwd[i];
- if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
- salt.p, salt.len, md_type,
- MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 )
- {
- return( ret );
- }
- if( iv == NULL || ivlen == 0 )
- return( 0 );
- if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
- salt.p, salt.len, md_type,
- MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- #undef PKCS12_MAX_PWDLEN
- int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
- const unsigned char *pwd, size_t pwdlen,
- const unsigned char *data, size_t len,
- unsigned char *output )
- {
- #if !defined(MBEDTLS_ARC4_C)
- ((void) pbe_params);
- ((void) mode);
- ((void) pwd);
- ((void) pwdlen);
- ((void) data);
- ((void) len);
- ((void) output);
- return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
- #else
- int ret;
- unsigned char key[16];
- mbedtls_arc4_context ctx;
- ((void) mode);
- mbedtls_arc4_init( &ctx );
- if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1,
- pwd, pwdlen,
- key, 16, NULL, 0 ) ) != 0 )
- {
- return( ret );
- }
- mbedtls_arc4_setup( &ctx, key, 16 );
- if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 )
- goto exit;
- exit:
- pkcs_zeroize( key, sizeof( key ) );
- mbedtls_arc4_free( &ctx );
- return( ret );
- #endif /* MBEDTLS_ARC4_C */
- }
- int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
- mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
- const unsigned char *pwd, size_t pwdlen,
- const unsigned char *data, size_t len,
- unsigned char *output )
- {
- int ret, keylen = 0;
- unsigned char key[32];
- unsigned char iv[16];
- const mbedtls_cipher_info_t *cipher_info;
- mbedtls_cipher_context_t cipher_ctx;
- size_t olen = 0;
- cipher_info = mbedtls_cipher_info_from_type( cipher_type );
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
- keylen = cipher_info->key_bitlen / 8;
- if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen,
- key, keylen,
- iv, cipher_info->iv_size ) ) != 0 )
- {
- return( ret );
- }
- mbedtls_cipher_init( &cipher_ctx );
- if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len,
- output, &olen ) ) != 0 )
- {
- goto exit;
- }
- if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
- ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
- exit:
- pkcs_zeroize( key, sizeof( key ) );
- pkcs_zeroize( iv, sizeof( iv ) );
- mbedtls_cipher_free( &cipher_ctx );
- return( ret );
- }
- static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
- const unsigned char *filler, size_t fill_len )
- {
- unsigned char *p = data;
- size_t use_len;
- while( data_len > 0 )
- {
- use_len = ( data_len > fill_len ) ? fill_len : data_len;
- memcpy( p, filler, use_len );
- p += use_len;
- data_len -= use_len;
- }
- }
- int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
- const unsigned char *pwd, size_t pwdlen,
- const unsigned char *salt, size_t saltlen,
- mbedtls_md_type_t md_type, int id, int iterations )
- {
- int ret;
- unsigned int j;
- unsigned char diversifier[128];
- unsigned char salt_block[128], pwd_block[128], hash_block[128];
- unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
- unsigned char *p;
- unsigned char c;
- size_t hlen, use_len, v, i;
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- // This version only allows max of 64 bytes of password or salt
- if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
- return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
- md_info = mbedtls_md_info_from_type( md_type );
- if( md_info == NULL )
- return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
- mbedtls_md_init( &md_ctx );
- if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
- return( ret );
- hlen = mbedtls_md_get_size( md_info );
- if( hlen <= 32 )
- v = 64;
- else
- v = 128;
- memset( diversifier, (unsigned char) id, v );
- pkcs12_fill_buffer( salt_block, v, salt, saltlen );
- pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen );
- p = data;
- while( datalen > 0 )
- {
- // Calculate hash( diversifier || salt_block || pwd_block )
- if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
- goto exit;
- // Perform remaining ( iterations - 1 ) recursive hash calculations
- for( i = 1; i < (size_t) iterations; i++ )
- {
- if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 )
- goto exit;
- }
- use_len = ( datalen > hlen ) ? hlen : datalen;
- memcpy( p, hash_output, use_len );
- datalen -= use_len;
- p += use_len;
- if( datalen == 0 )
- break;
- // Concatenating copies of hash_output into hash_block (B)
- pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
- // B += 1
- for( i = v; i > 0; i-- )
- if( ++hash_block[i - 1] != 0 )
- break;
- // salt_block += B
- c = 0;
- for( i = v; i > 0; i-- )
- {
- j = salt_block[i - 1] + hash_block[i - 1] + c;
- c = (unsigned char) (j >> 8);
- salt_block[i - 1] = j & 0xFF;
- }
- // pwd_block += B
- c = 0;
- for( i = v; i > 0; i-- )
- {
- j = pwd_block[i - 1] + hash_block[i - 1] + c;
- c = (unsigned char) (j >> 8);
- pwd_block[i - 1] = j & 0xFF;
- }
- }
- ret = 0;
- exit:
- pkcs_zeroize( salt_block, sizeof( salt_block ) );
- pkcs_zeroize( pwd_block, sizeof( pwd_block ) );
- pkcs_zeroize( hash_block, sizeof( hash_block ) );
- pkcs_zeroize( hash_output, sizeof( hash_output ) );
- mbedtls_md_free( &md_ctx );
- return( ret );
- }
- #endif /* MBEDTLS_PKCS12_C */
- /********* Start of file library/pkcs5.c ************/
- /**
- * \file pkcs5.c
- *
- * \brief PKCS#5 functions
- *
- * \author Mathias Olsson <mathias@kompetensum.com>
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * PKCS#5 includes PBKDF2 and more
- *
- * http://tools.ietf.org/html/rfc2898 (Specification)
- * http://tools.ietf.org/html/rfc6070 (Test vectors)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PKCS5_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif
- static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
- mbedtls_asn1_buf *salt, int *iterations,
- int *keylen, mbedtls_md_type_t *md_type )
- {
- int ret;
- mbedtls_asn1_buf prf_alg_oid;
- unsigned char *p = params->p;
- const unsigned char *end = params->p + params->len;
- if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- /*
- * PBKDF2-params ::= SEQUENCE {
- * salt OCTET STRING,
- * iterationCount INTEGER,
- * keyLength INTEGER OPTIONAL
- * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
- * }
- *
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- salt->p = p;
- p += salt->len;
- if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- if( p == end )
- return( 0 );
- if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
- {
- if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- }
- if( p == end )
- return( 0 );
- if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 )
- return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- *md_type = MBEDTLS_MD_SHA1;
- if( p != end )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
- const unsigned char *pwd, size_t pwdlen,
- const unsigned char *data, size_t datalen,
- unsigned char *output )
- {
- int ret, iterations = 0, keylen = 0;
- unsigned char *p, *end;
- mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
- mbedtls_asn1_buf salt;
- mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
- unsigned char key[32], iv[32];
- size_t olen = 0;
- const mbedtls_md_info_t *md_info;
- const mbedtls_cipher_info_t *cipher_info;
- mbedtls_md_context_t md_ctx;
- mbedtls_cipher_type_t cipher_alg;
- mbedtls_cipher_context_t cipher_ctx;
- p = pbe_params->p;
- end = p + pbe_params->len;
- /*
- * PBES2-params ::= SEQUENCE {
- * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
- * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
- * }
- */
- if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- // Only PBKDF2 supported at the moment
- //
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 )
- return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
- &salt, &iterations, &keylen,
- &md_type ) ) != 0 )
- {
- return( ret );
- }
- md_info = mbedtls_md_info_from_type( md_type );
- if( md_info == NULL )
- return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
- &enc_scheme_params ) ) != 0 )
- {
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- }
- if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
- return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- cipher_info = mbedtls_cipher_info_from_type( cipher_alg );
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- /*
- * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
- * since it is optional and we don't know if it was set or not
- */
- keylen = cipher_info->key_bitlen / 8;
- if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
- enc_scheme_params.len != cipher_info->iv_size )
- {
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT );
- }
- mbedtls_md_init( &md_ctx );
- mbedtls_cipher_init( &cipher_ctx );
- memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
- if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
- iterations, keylen, key ) ) != 0 )
- {
- goto exit;
- }
- if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
- goto exit;
- if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
- data, datalen, output, &olen ) ) != 0 )
- ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
- exit:
- mbedtls_md_free( &md_ctx );
- mbedtls_cipher_free( &cipher_ctx );
- return( ret );
- }
- int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
- size_t plen, const unsigned char *salt, size_t slen,
- unsigned int iteration_count,
- uint32_t key_length, unsigned char *output )
- {
- int ret, j;
- unsigned int i;
- unsigned char md1[MBEDTLS_MD_MAX_SIZE];
- unsigned char work[MBEDTLS_MD_MAX_SIZE];
- unsigned char md_size = mbedtls_md_get_size( ctx->md_info );
- size_t use_len;
- unsigned char *out_p = output;
- unsigned char counter[4];
- memset( counter, 0, 4 );
- counter[3] = 1;
- if( iteration_count > 0xFFFFFFFF )
- return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
- while( key_length )
- {
- // U1 ends up in work
- //
- if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
- return( ret );
- memcpy( md1, work, md_size );
- for( i = 1; i < iteration_count; i++ )
- {
- // U2 ends up in md1
- //
- if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
- return( ret );
- // U1 xor U2
- //
- for( j = 0; j < md_size; j++ )
- work[j] ^= md1[j];
- }
- use_len = ( key_length < md_size ) ? key_length : md_size;
- memcpy( out_p, work, use_len );
- key_length -= (uint32_t) use_len;
- out_p += use_len;
- for( i = 4; i > 0; i-- )
- if( ++counter[i - 1] != 0 )
- break;
- }
- return( 0 );
- }
- #if defined(MBEDTLS_SELF_TEST)
- #if !defined(MBEDTLS_SHA1_C)
- int mbedtls_pkcs5_self_test( int verbose )
- {
- if( verbose != 0 )
- mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" );
- return( 0 );
- }
- #else
- #define MAX_TESTS 6
- static const size_t plen[MAX_TESTS] =
- { 8, 8, 8, 24, 9 };
- static const unsigned char password[MAX_TESTS][32] =
- {
- "password",
- "password",
- "password",
- "passwordPASSWORDpassword",
- "pass\0word",
- };
- static const size_t slen[MAX_TESTS] =
- { 4, 4, 4, 36, 5 };
- static const unsigned char salt[MAX_TESTS][40] =
- {
- "salt",
- "salt",
- "salt",
- "saltSALTsaltSALTsaltSALTsaltSALTsalt",
- "sa\0lt",
- };
- static const uint32_t it_cnt[MAX_TESTS] =
- { 1, 2, 4096, 4096, 4096 };
- static const uint32_t key_len[MAX_TESTS] =
- { 20, 20, 20, 25, 16 };
- static const unsigned char result_key[MAX_TESTS][32] =
- {
- { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
- 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
- 0x2f, 0xe0, 0x37, 0xa6 },
- { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
- 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
- 0xd8, 0xde, 0x89, 0x57 },
- { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
- 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
- 0x65, 0xa4, 0x29, 0xc1 },
- { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
- 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
- 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
- 0x38 },
- { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
- 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
- };
- int mbedtls_pkcs5_self_test( int verbose )
- {
- mbedtls_md_context_t sha1_ctx;
- const mbedtls_md_info_t *info_sha1;
- int ret, i;
- unsigned char key[64];
- mbedtls_md_init( &sha1_ctx );
- info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
- if( info_sha1 == NULL )
- {
- ret = 1;
- goto exit;
- }
- if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
- {
- ret = 1;
- goto exit;
- }
- for( i = 0; i < MAX_TESTS; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
- ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
- slen[i], it_cnt[i], key_len[i], key );
- if( ret != 0 ||
- memcmp( result_key[i], key, key_len[i] ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- mbedtls_printf( "\n" );
- exit:
- mbedtls_md_free( &sha1_ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_PKCS5_C */
- /********* Start of file library/pkparse.c ************/
- /*
- * Public Key layer for parsing key files and structures
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PK_PARSE_C)
- #include <string.h>
- #if defined(MBEDTLS_RSA_C)
- #endif
- #if defined(MBEDTLS_ECP_C)
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- #endif
- #if defined(MBEDTLS_PEM_PARSE_C)
- #endif
- #if defined(MBEDTLS_PKCS5_C)
- #endif
- #if defined(MBEDTLS_PKCS12_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if defined(MBEDTLS_FS_IO)
- /* Implementation that should never be optimized out by the compiler */
- static void pkparse_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Load all data from a file into a given buffer.
- *
- * The file is expected to contain either PEM or DER encoded data.
- * A terminating null byte is always appended. It is included in the announced
- * length only if the data looks like it is PEM encoded.
- */
- int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
- {
- FILE *f;
- long size;
- if( ( f = fopen( path, "rb" ) ) == NULL )
- return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
- fseek( f, 0, SEEK_END );
- if( ( size = ftell( f ) ) == -1 )
- {
- fclose( f );
- return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
- }
- fseek( f, 0, SEEK_SET );
- *n = (size_t) size;
- if( *n + 1 == 0 ||
- ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
- {
- fclose( f );
- return( MBEDTLS_ERR_PK_ALLOC_FAILED );
- }
- if( fread( *buf, 1, *n, f ) != *n )
- {
- fclose( f );
- mbedtls_free( *buf );
- return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
- }
- fclose( f );
- (*buf)[*n] = '\0';
- if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
- ++*n;
- return( 0 );
- }
- /*
- * Load and parse a private key
- */
- int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
- const char *path, const char *pwd )
- {
- int ret;
- size_t n;
- unsigned char *buf;
- if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
- return( ret );
- if( pwd == NULL )
- ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
- else
- ret = mbedtls_pk_parse_key( ctx, buf, n,
- (const unsigned char *) pwd, strlen( pwd ) );
- pkparse_zeroize( buf, n );
- mbedtls_free( buf );
- return( ret );
- }
- /*
- * Load and parse a public key
- */
- int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
- {
- int ret;
- size_t n;
- unsigned char *buf;
- if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
- return( ret );
- ret = mbedtls_pk_parse_public_key( ctx, buf, n );
- pkparse_zeroize( buf, n );
- mbedtls_free( buf );
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- #if defined(MBEDTLS_ECP_C)
- /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
- *
- * ECParameters ::= CHOICE {
- * namedCurve OBJECT IDENTIFIER
- * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
- * -- implicitCurve NULL
- * }
- */
- static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
- mbedtls_asn1_buf *params )
- {
- int ret;
- /* Tag may be either OID or SEQUENCE */
- params->tag = **p;
- if( params->tag != MBEDTLS_ASN1_OID
- #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
- && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE )
- #endif
- )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- }
- if( ( ret = mbedtls_asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- params->p = *p;
- *p += params->len;
- if( *p != end )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
- /*
- * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
- * WARNING: the resulting group should only be used with
- * pk_group_id_from_specified(), since its base point may not be set correctly
- * if it was encoded compressed.
- *
- * SpecifiedECDomain ::= SEQUENCE {
- * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
- * fieldID FieldID {{FieldTypes}},
- * curve Curve,
- * base ECPoint,
- * order INTEGER,
- * cofactor INTEGER OPTIONAL,
- * hash HashAlgorithm OPTIONAL,
- * ...
- * }
- *
- * We only support prime-field as field type, and ignore hash and cofactor.
- */
- static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
- {
- int ret;
- unsigned char *p = params->p;
- const unsigned char * const end = params->p + params->len;
- const unsigned char *end_field, *end_curve;
- size_t len;
- int ver;
- /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
- if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( ver < 1 || ver > 3 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
- /*
- * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
- * fieldType FIELD-ID.&id({IOSet}),
- * parameters FIELD-ID.&Type({IOSet}{@fieldType})
- * }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( ret );
- end_field = p + len;
- /*
- * FIELD-ID ::= TYPE-IDENTIFIER
- * FieldTypes FIELD-ID ::= {
- * { Prime-p IDENTIFIED BY prime-field } |
- * { Characteristic-two IDENTIFIED BY characteristic-two-field }
- * }
- * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( ret );
- if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
- memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
- {
- return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- }
- p += len;
- /* Prime-p ::= INTEGER -- Field of size p. */
- if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- grp->pbits = mbedtls_mpi_bitlen( &grp->P );
- if( p != end_field )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- /*
- * Curve ::= SEQUENCE {
- * a FieldElement,
- * b FieldElement,
- * seed BIT STRING OPTIONAL
- * -- Shall be present if used in SpecifiedECDomain
- * -- with version equal to ecdpVer2 or ecdpVer3
- * }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( ret );
- end_curve = p + len;
- /*
- * FieldElement ::= OCTET STRING
- * containing an integer in the case of a prime field
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
- ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- p += len;
- if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
- ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- p += len;
- /* Ignore seed BIT STRING OPTIONAL */
- if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 )
- p += len;
- if( p != end_curve )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- /*
- * ECPoint ::= OCTET STRING
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
- ( const unsigned char *) p, len ) ) != 0 )
- {
- /*
- * If we can't read the point because it's compressed, cheat by
- * reading only the X coordinate and the parity bit of Y.
- */
- if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ||
- ( p[0] != 0x02 && p[0] != 0x03 ) ||
- len != mbedtls_mpi_size( &grp->P ) + 1 ||
- mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
- mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
- mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
- }
- }
- p += len;
- /*
- * order INTEGER
- */
- if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- grp->nbits = mbedtls_mpi_bitlen( &grp->N );
- /*
- * Allow optional elements by purposefully not enforcing p == end here.
- */
- return( 0 );
- }
- /*
- * Find the group id associated with an (almost filled) group as generated by
- * pk_group_from_specified(), or return an error if unknown.
- */
- static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id )
- {
- int ret = 0;
- mbedtls_ecp_group ref;
- const mbedtls_ecp_group_id *id;
- mbedtls_ecp_group_init( &ref );
- for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ )
- {
- /* Load the group associated to that id */
- mbedtls_ecp_group_free( &ref );
- MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) );
- /* Compare to the group we were given, starting with easy tests */
- if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
- mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
- mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
- mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
- mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
- mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
- mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
- /* For Y we may only know the parity bit, so compare only that */
- mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) )
- {
- break;
- }
- }
- cleanup:
- mbedtls_ecp_group_free( &ref );
- *grp_id = *id;
- if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE )
- ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
- return( ret );
- }
- /*
- * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
- */
- static int pk_group_id_from_specified( const mbedtls_asn1_buf *params,
- mbedtls_ecp_group_id *grp_id )
- {
- int ret;
- mbedtls_ecp_group grp;
- mbedtls_ecp_group_init( &grp );
- if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
- goto cleanup;
- ret = pk_group_id_from_group( &grp, grp_id );
- cleanup:
- mbedtls_ecp_group_free( &grp );
- return( ret );
- }
- #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
- /*
- * Use EC parameters to initialise an EC group
- *
- * ECParameters ::= CHOICE {
- * namedCurve OBJECT IDENTIFIER
- * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
- * -- implicitCurve NULL
- */
- static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
- {
- int ret;
- mbedtls_ecp_group_id grp_id;
- if( params->tag == MBEDTLS_ASN1_OID )
- {
- if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 )
- return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
- }
- else
- {
- #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
- if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
- return( ret );
- #else
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
- #endif
- }
- /*
- * grp may already be initilialized; if so, make sure IDs match
- */
- if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
- if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 )
- return( ret );
- return( 0 );
- }
- /*
- * EC public key is an EC point
- *
- * The caller is responsible for clearing the structure upon failure if
- * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
- * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
- */
- static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
- mbedtls_ecp_keypair *key )
- {
- int ret;
- if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q,
- (const unsigned char *) *p, end - *p ) ) == 0 )
- {
- ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q );
- }
- /*
- * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
- */
- *p = (unsigned char *) end;
- return( ret );
- }
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_RSA_C)
- /*
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e
- * }
- */
- static int pk_get_rsapubkey( unsigned char **p,
- const unsigned char *end,
- mbedtls_rsa_context *rsa )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
- if( *p + len != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
- if( *p != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
- rsa->len = mbedtls_mpi_size( &rsa->N );
- return( 0 );
- }
- #endif /* MBEDTLS_RSA_C */
- /* Get a PK algorithm identifier
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- */
- static int pk_get_pk_alg( unsigned char **p,
- const unsigned char *end,
- mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params )
- {
- int ret;
- mbedtls_asn1_buf alg_oid;
- memset( params, 0, sizeof(mbedtls_asn1_buf) );
- if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_ALG + ret );
- if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- /*
- * No parameters with RSA (only for EC)
- */
- if( *pk_alg == MBEDTLS_PK_RSA &&
- ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) ||
- params->len != 0 ) )
- {
- return( MBEDTLS_ERR_PK_INVALID_ALG );
- }
- return( 0 );
- }
- /*
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- */
- int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
- mbedtls_pk_context *pk )
- {
- int ret;
- size_t len;
- mbedtls_asn1_buf alg_params;
- mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
- const mbedtls_pk_info_t *pk_info;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- end = *p + len;
- if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
- if( *p + len != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
- return( ret );
- #if defined(MBEDTLS_RSA_C)
- if( pk_alg == MBEDTLS_PK_RSA )
- {
- ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) );
- } else
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY )
- {
- ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp );
- if( ret == 0 )
- ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) );
- } else
- #endif /* MBEDTLS_ECP_C */
- ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
- if( ret == 0 && *p != end )
- ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
- if( ret != 0 )
- mbedtls_pk_free( pk );
- return( ret );
- }
- #if defined(MBEDTLS_RSA_C)
- /*
- * Parse a PKCS#1 encoded private RSA key
- */
- static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
- const unsigned char *key,
- size_t keylen )
- {
- int ret;
- size_t len;
- unsigned char *p, *end;
- p = (unsigned char *) key;
- end = p + keylen;
- /*
- * This function parses the RSAPrivateKey (PKCS#1)
- *
- * RSAPrivateKey ::= SEQUENCE {
- * version Version,
- * modulus INTEGER, -- n
- * publicExponent INTEGER, -- e
- * privateExponent INTEGER, -- d
- * prime1 INTEGER, -- p
- * prime2 INTEGER, -- q
- * exponent1 INTEGER, -- d mod (p-1)
- * exponent2 INTEGER, -- d mod (q-1)
- * coefficient INTEGER, -- (inverse of q) mod p
- * otherPrimeInfos OtherPrimeInfos OPTIONAL
- * }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- end = p + len;
- if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- if( rsa->ver != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
- }
- if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
- ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
- {
- mbedtls_rsa_free( rsa );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- rsa->len = mbedtls_mpi_size( &rsa->N );
- if( p != end )
- {
- mbedtls_rsa_free( rsa );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 )
- {
- mbedtls_rsa_free( rsa );
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- /*
- * Parse a SEC1 encoded private EC key
- */
- static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
- const unsigned char *key,
- size_t keylen )
- {
- int ret;
- int version, pubkey_done;
- size_t len;
- mbedtls_asn1_buf params;
- unsigned char *p = (unsigned char *) key;
- unsigned char *end = p + keylen;
- unsigned char *end2;
- /*
- * RFC 5915, or SEC1 Appendix C.4
- *
- * ECPrivateKey ::= SEQUENCE {
- * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
- * privateKey OCTET STRING,
- * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
- * publicKey [1] BIT STRING OPTIONAL
- * }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- end = p + len;
- if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( version != 1 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
- {
- mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- p += len;
- pubkey_done = 0;
- if( p != end )
- {
- /*
- * Is 'parameters' present?
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
- {
- if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 ||
- ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 )
- {
- mbedtls_ecp_keypair_free( eck );
- return( ret );
- }
- }
- else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- {
- mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- /*
- * Is 'publickey' present? If not, or if we can't read it (eg because it
- * is compressed), create it from the private key.
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
- {
- end2 = p + len;
- if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( p + len != end2 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
- pubkey_done = 1;
- else
- {
- /*
- * The only acceptable failure mode of pk_get_ecpubkey() above
- * is if the point format is not recognized.
- */
- if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
- }
- }
- else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- {
- mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- }
- if( ! pubkey_done &&
- ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
- NULL, NULL ) ) != 0 )
- {
- mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
- {
- mbedtls_ecp_keypair_free( eck );
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_ECP_C */
- /*
- * Parse an unencrypted PKCS#8 encoded private key
- */
- static int pk_parse_key_pkcs8_unencrypted_der(
- mbedtls_pk_context *pk,
- const unsigned char* key,
- size_t keylen )
- {
- int ret, version;
- size_t len;
- mbedtls_asn1_buf params;
- unsigned char *p = (unsigned char *) key;
- unsigned char *end = p + keylen;
- mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
- const mbedtls_pk_info_t *pk_info;
- /*
- * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
- *
- * PrivateKeyInfo ::= SEQUENCE {
- * version Version,
- * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
- * privateKey PrivateKey,
- * attributes [0] IMPLICIT Attributes OPTIONAL }
- *
- * Version ::= INTEGER
- * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
- * PrivateKey ::= OCTET STRING
- *
- * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- end = p + len;
- if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( version != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
- if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( len < 1 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
- return( ret );
- #if defined(MBEDTLS_RSA_C)
- if( pk_alg == MBEDTLS_PK_RSA )
- {
- if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- return( ret );
- }
- } else
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
- {
- if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
- ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- return( ret );
- }
- } else
- #endif /* MBEDTLS_ECP_C */
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- return( 0 );
- }
- /*
- * Parse an encrypted PKCS#8 encoded private key
- */
- #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
- static int pk_parse_key_pkcs8_encrypted_der(
- mbedtls_pk_context *pk,
- const unsigned char *key, size_t keylen,
- const unsigned char *pwd, size_t pwdlen )
- {
- int ret, decrypted = 0;
- size_t len;
- unsigned char buf[2048];
- unsigned char *p, *end;
- mbedtls_asn1_buf pbe_alg_oid, pbe_params;
- #if defined(MBEDTLS_PKCS12_C)
- mbedtls_cipher_type_t cipher_alg;
- mbedtls_md_type_t md_alg;
- #endif
- memset( buf, 0, sizeof( buf ) );
- p = (unsigned char *) key;
- end = p + keylen;
- if( pwdlen == 0 )
- return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
- /*
- * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
- *
- * EncryptedPrivateKeyInfo ::= SEQUENCE {
- * encryptionAlgorithm EncryptionAlgorithmIdentifier,
- * encryptedData EncryptedData
- * }
- *
- * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * EncryptedData ::= OCTET STRING
- *
- * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- }
- end = p + len;
- if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- if( len > sizeof( buf ) )
- return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
- /*
- * Decrypt EncryptedData with appropriate PDE
- */
- #if defined(MBEDTLS_PKCS12_C)
- if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
- {
- if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT,
- cipher_alg, md_alg,
- pwd, pwdlen, p, len, buf ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH )
- return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
- return( ret );
- }
- decrypted = 1;
- }
- else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 )
- {
- if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params,
- MBEDTLS_PKCS12_PBE_DECRYPT,
- pwd, pwdlen,
- p, len, buf ) ) != 0 )
- {
- return( ret );
- }
- // Best guess for password mismatch when using RC4. If first tag is
- // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
- //
- if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
- decrypted = 1;
- }
- else
- #endif /* MBEDTLS_PKCS12_C */
- #if defined(MBEDTLS_PKCS5_C)
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 )
- {
- if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen,
- p, len, buf ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH )
- return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
- return( ret );
- }
- decrypted = 1;
- }
- else
- #endif /* MBEDTLS_PKCS5_C */
- {
- ((void) pwd);
- }
- if( decrypted == 0 )
- return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
- }
- #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
- /*
- * Parse a private key
- */
- int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
- const unsigned char *key, size_t keylen,
- const unsigned char *pwd, size_t pwdlen )
- {
- int ret;
- const mbedtls_pk_info_t *pk_info;
- #if defined(MBEDTLS_PEM_PARSE_C)
- size_t len;
- mbedtls_pem_context pem;
- mbedtls_pem_init( &pem );
- #if defined(MBEDTLS_RSA_C)
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN RSA PRIVATE KEY-----",
- "-----END RSA PRIVATE KEY-----",
- key, pwd, pwdlen, &len );
- if( ret == 0 )
- {
- if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
- ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
- pem.buf, pem.buflen ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- }
- mbedtls_pem_free( &pem );
- return( ret );
- }
- else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
- return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
- else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
- return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- return( ret );
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN EC PRIVATE KEY-----",
- "-----END EC PRIVATE KEY-----",
- key, pwd, pwdlen, &len );
- if( ret == 0 )
- {
- if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
- ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
- pem.buf, pem.buflen ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- }
- mbedtls_pem_free( &pem );
- return( ret );
- }
- else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
- return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
- else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
- return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- return( ret );
- #endif /* MBEDTLS_ECP_C */
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN PRIVATE KEY-----",
- "-----END PRIVATE KEY-----",
- key, NULL, 0, &len );
- if( ret == 0 )
- {
- if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
- pem.buf, pem.buflen ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- }
- mbedtls_pem_free( &pem );
- return( ret );
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- return( ret );
- #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN ENCRYPTED PRIVATE KEY-----",
- "-----END ENCRYPTED PRIVATE KEY-----",
- key, NULL, 0, &len );
- if( ret == 0 )
- {
- if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
- pem.buf, pem.buflen,
- pwd, pwdlen ) ) != 0 )
- {
- mbedtls_pk_free( pk );
- }
- mbedtls_pem_free( &pem );
- return( ret );
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- return( ret );
- #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
- #else
- ((void) ret);
- ((void) pwd);
- ((void) pwdlen);
- #endif /* MBEDTLS_PEM_PARSE_C */
- /*
- * At this point we only know it's not a PEM formatted key. Could be any
- * of the known DER encoded private key formats
- *
- * We try the different DER format parsers to see if one passes without
- * error
- */
- #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
- if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
- pwd, pwdlen ) ) == 0 )
- {
- return( 0 );
- }
- mbedtls_pk_free( pk );
- if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
- {
- return( ret );
- }
- #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
- if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
- return( 0 );
- mbedtls_pk_free( pk );
- #if defined(MBEDTLS_RSA_C)
- if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
- ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) ) == 0 )
- {
- return( 0 );
- }
- mbedtls_pk_free( pk );
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL )
- return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
- if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
- ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), key, keylen ) ) == 0 )
- {
- return( 0 );
- }
- mbedtls_pk_free( pk );
- #endif /* MBEDTLS_ECP_C */
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
- }
- /*
- * Parse a public key
- */
- int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
- const unsigned char *key, size_t keylen )
- {
- int ret;
- unsigned char *p;
- #if defined(MBEDTLS_PEM_PARSE_C)
- size_t len;
- mbedtls_pem_context pem;
- mbedtls_pem_init( &pem );
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( keylen == 0 || key[keylen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN PUBLIC KEY-----",
- "-----END PUBLIC KEY-----",
- key, NULL, 0, &len );
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- key = pem.buf;
- keylen = pem.buflen;
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- {
- mbedtls_pem_free( &pem );
- return( ret );
- }
- #endif /* MBEDTLS_PEM_PARSE_C */
- p = (unsigned char *) key;
- ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
- #if defined(MBEDTLS_PEM_PARSE_C)
- mbedtls_pem_free( &pem );
- #endif
- return( ret );
- }
- #endif /* MBEDTLS_PK_PARSE_C */
- /********* Start of file library/pkwrite.c ************/
- /*
- * Public Key layer for writing key files and structures
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PK_WRITE_C)
- #include <string.h>
- #if defined(MBEDTLS_RSA_C)
- #endif
- #if defined(MBEDTLS_ECP_C)
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- #endif
- #if defined(MBEDTLS_PEM_WRITE_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if defined(MBEDTLS_RSA_C)
- /*
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e
- * }
- */
- static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
- mbedtls_rsa_context *rsa )
- {
- int ret;
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- /*
- * EC public key is an EC point
- */
- static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
- mbedtls_ecp_keypair *ec )
- {
- int ret;
- size_t len = 0;
- unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
- if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
- MBEDTLS_ECP_PF_UNCOMPRESSED,
- &len, buf, sizeof( buf ) ) ) != 0 )
- {
- return( ret );
- }
- if( *p < start || (size_t)( *p - start ) < len )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *p -= len;
- memcpy( *p, buf, len );
- return( (int) len );
- }
- /*
- * ECParameters ::= CHOICE {
- * namedCurve OBJECT IDENTIFIER
- * }
- */
- static int pk_write_ec_param( unsigned char **p, unsigned char *start,
- mbedtls_ecp_keypair *ec )
- {
- int ret;
- size_t len = 0;
- const char *oid;
- size_t oid_len;
- if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
- return( ret );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
- return( (int) len );
- }
- #endif /* MBEDTLS_ECP_C */
- int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *key )
- {
- int ret;
- size_t len = 0;
- #if defined(MBEDTLS_RSA_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
- MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
- else
- #endif
- #if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
- MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
- else
- #endif
- return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- return( (int) len );
- }
- int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
- {
- int ret;
- unsigned char *c;
- size_t len = 0, par_len = 0, oid_len;
- const char *oid;
- c = buf + size;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
- if( c - buf < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- /*
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- */
- *--c = 0;
- len += 1;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
- if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
- &oid, &oid_len ) ) != 0 )
- {
- return( ret );
- }
- #if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
- {
- MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
- }
- #endif
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
- par_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
- {
- int ret;
- unsigned char *c = buf + size;
- size_t len = 0;
- #if defined(MBEDTLS_RSA_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
- {
- mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- }
- else
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
- {
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key );
- size_t pub_len = 0, par_len = 0;
- /*
- * RFC 5915, or SEC1 Appendix C.4
- *
- * ECPrivateKey ::= SEQUENCE {
- * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
- * privateKey OCTET STRING,
- * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
- * publicKey [1] BIT STRING OPTIONAL
- * }
- */
- /* publicKey */
- MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
- if( c - buf < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--c = 0;
- pub_len += 1;
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) );
- len += pub_len;
- /* parameters */
- MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
- MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) );
- MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
- len += par_len;
- /* privateKey: write as MPI then fix tag */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) );
- *c = MBEDTLS_ASN1_OCTET_STRING;
- /* version */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- }
- else
- #endif /* MBEDTLS_ECP_C */
- return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- return( (int) len );
- }
- #if defined(MBEDTLS_PEM_WRITE_C)
- #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
- #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
- #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
- #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
- #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
- #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
- /*
- * Max sizes of key per types. Shown as tag + len (+ content).
- */
- #if defined(MBEDTLS_RSA_C)
- /*
- * RSA public keys:
- * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
- * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
- * + 1 + 1 + 9 (rsa oid)
- * + 1 + 1 (params null)
- * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
- * RSAPublicKey ::= SEQUENCE { 1 + 3
- * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
- * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
- * }
- */
- #define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE
- /*
- * RSA private keys:
- * RSAPrivateKey ::= SEQUENCE { 1 + 3
- * version Version, 1 + 1 + 1
- * modulus INTEGER, 1 + 3 + MPI_MAX + 1
- * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
- * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
- * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
- * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
- * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
- * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
- * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
- * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
- * }
- */
- #define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \
- MBEDTLS_MPI_MAX_SIZE % 2
- #define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
- + 5 * MPI_MAX_SIZE_2
- #else /* MBEDTLS_RSA_C */
- #define RSA_PUB_DER_MAX_BYTES 0
- #define RSA_PRV_DER_MAX_BYTES 0
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_ECP_C)
- /*
- * EC public keys:
- * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
- * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
- * + 1 + 1 + 7 (ec oid)
- * + 1 + 1 + 9 (namedCurve oid)
- * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
- * + 1 (point format) [1]
- * + 2 * ECP_MAX (coords) [1]
- * }
- */
- #define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES
- /*
- * EC private keys:
- * ECPrivateKey ::= SEQUENCE { 1 + 2
- * version INTEGER , 1 + 1 + 1
- * privateKey OCTET STRING, 1 + 1 + ECP_MAX
- * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
- * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
- * }
- */
- #define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES
- #else /* MBEDTLS_ECP_C */
- #define ECP_PUB_DER_MAX_BYTES 0
- #define ECP_PRV_DER_MAX_BYTES 0
- #endif /* MBEDTLS_ECP_C */
- #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
- RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
- #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
- RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
- int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
- {
- int ret;
- unsigned char output_buf[PUB_DER_MAX_BYTES];
- size_t olen = 0;
- if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
- sizeof(output_buf) ) ) < 0 )
- {
- return( ret );
- }
- if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
- output_buf + sizeof(output_buf) - ret,
- ret, buf, size, &olen ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
- {
- int ret;
- unsigned char output_buf[PRV_DER_MAX_BYTES];
- const char *begin, *end;
- size_t olen = 0;
- if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
- return( ret );
- #if defined(MBEDTLS_RSA_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
- {
- begin = PEM_BEGIN_PRIVATE_KEY_RSA;
- end = PEM_END_PRIVATE_KEY_RSA;
- }
- else
- #endif
- #if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
- {
- begin = PEM_BEGIN_PRIVATE_KEY_EC;
- end = PEM_END_PRIVATE_KEY_EC;
- }
- else
- #endif
- return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- if( ( ret = mbedtls_pem_write_buffer( begin, end,
- output_buf + sizeof(output_buf) - ret,
- ret, buf, size, &olen ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_PEM_WRITE_C */
- #endif /* MBEDTLS_PK_WRITE_C */
- /********* Start of file library/platform.c ************/
- /*
- * Platform abstraction layer
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #if defined(MBEDTLS_PLATFORM_MEMORY)
- #if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
- static void *platform_calloc_uninit( size_t n, size_t size )
- {
- ((void) n);
- ((void) size);
- return( NULL );
- }
- #define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit
- #endif /* !MBEDTLS_PLATFORM_STD_CALLOC */
- #if !defined(MBEDTLS_PLATFORM_STD_FREE)
- static void platform_free_uninit( void *ptr )
- {
- ((void) ptr);
- }
- #define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
- #endif /* !MBEDTLS_PLATFORM_STD_FREE */
- void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
- void (*mbedtls_free)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
- int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
- void (*free_func)( void * ) )
- {
- mbedtls_calloc = calloc_func;
- mbedtls_free = free_func;
- return( 0 );
- }
- #endif /* MBEDTLS_PLATFORM_MEMORY */
- #if defined(_WIN32)
- #include <stdarg.h>
- int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
- {
- int ret;
- va_list argp;
- /* Avoid calling the invalid parameter handler by checking ourselves */
- if( s == NULL || n == 0 || fmt == NULL )
- return( -1 );
- va_start( argp, fmt );
- #if defined(_TRUNCATE)
- ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
- #else
- ret = _vsnprintf( s, n, fmt, argp );
- if( ret < 0 || (size_t) ret == n )
- {
- s[n-1] = '\0';
- ret = -1;
- }
- #endif
- va_end( argp );
- return( ret );
- }
- #endif
- #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
- #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
- /*
- * Make dummy function to prevent NULL pointer dereferences
- */
- static int platform_snprintf_uninit( char * s, size_t n,
- const char * format, ... )
- {
- ((void) s);
- ((void) n);
- ((void) format);
- return( 0 );
- }
- #define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit
- #endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */
- int (*mbedtls_snprintf)( char * s, size_t n,
- const char * format,
- ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF;
- int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
- const char * format,
- ... ) )
- {
- mbedtls_snprintf = snprintf_func;
- return( 0 );
- }
- #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
- #if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
- #if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
- /*
- * Make dummy function to prevent NULL pointer dereferences
- */
- static int platform_printf_uninit( const char *format, ... )
- {
- ((void) format);
- return( 0 );
- }
- #define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit
- #endif /* !MBEDTLS_PLATFORM_STD_PRINTF */
- int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF;
- int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) )
- {
- mbedtls_printf = printf_func;
- return( 0 );
- }
- #endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
- #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
- #if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
- /*
- * Make dummy function to prevent NULL pointer dereferences
- */
- static int platform_fprintf_uninit( FILE *stream, const char *format, ... )
- {
- ((void) stream);
- ((void) format);
- return( 0 );
- }
- #define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit
- #endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */
- int (*mbedtls_fprintf)( FILE *, const char *, ... ) =
- MBEDTLS_PLATFORM_STD_FPRINTF;
- int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) )
- {
- mbedtls_fprintf = fprintf_func;
- return( 0 );
- }
- #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
- #if defined(MBEDTLS_PLATFORM_EXIT_ALT)
- #if !defined(MBEDTLS_PLATFORM_STD_EXIT)
- /*
- * Make dummy function to prevent NULL pointer dereferences
- */
- static void platform_exit_uninit( int status )
- {
- ((void) status);
- }
- #define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit
- #endif /* !MBEDTLS_PLATFORM_STD_EXIT */
- void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT;
- int mbedtls_platform_set_exit( void (*exit_func)( int status ) )
- {
- mbedtls_exit = exit_func;
- return( 0 );
- }
- #endif /* MBEDTLS_PLATFORM_EXIT_ALT */
- #endif /* MBEDTLS_PLATFORM_C */
- /********* Start of file library/ripemd160.c ************/
- /*
- * RIPE MD-160 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The RIPEMD-160 algorithm was designed by RIPE in 1996
- * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
- * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_RIPEMD160_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- /*
- * 32-bit integer manipulation macros (little endian)
- */
- #ifndef GET_UINT32_LE
- #define GET_UINT32_LE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
- }
- #endif
- #ifndef PUT_UINT32_LE
- #define PUT_UINT32_LE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
- }
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void ripemd_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
- }
- void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
- {
- if( ctx == NULL )
- return;
- ripemd_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
- }
- void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
- const mbedtls_ripemd160_context *src )
- {
- *dst = *src;
- }
- /*
- * RIPEMD-160 context setup
- */
- void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
- {
- ctx->total[0] = 0;
- ctx->total[1] = 0;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
- }
- #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
- /*
- * Process one block
- */
- void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] )
- {
- uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
- GET_UINT32_LE( X[ 0], data, 0 );
- GET_UINT32_LE( X[ 1], data, 4 );
- GET_UINT32_LE( X[ 2], data, 8 );
- GET_UINT32_LE( X[ 3], data, 12 );
- GET_UINT32_LE( X[ 4], data, 16 );
- GET_UINT32_LE( X[ 5], data, 20 );
- GET_UINT32_LE( X[ 6], data, 24 );
- GET_UINT32_LE( X[ 7], data, 28 );
- GET_UINT32_LE( X[ 8], data, 32 );
- GET_UINT32_LE( X[ 9], data, 36 );
- GET_UINT32_LE( X[10], data, 40 );
- GET_UINT32_LE( X[11], data, 44 );
- GET_UINT32_LE( X[12], data, 48 );
- GET_UINT32_LE( X[13], data, 52 );
- GET_UINT32_LE( X[14], data, 56 );
- GET_UINT32_LE( X[15], data, 60 );
- A = Ap = ctx->state[0];
- B = Bp = ctx->state[1];
- C = Cp = ctx->state[2];
- D = Dp = ctx->state[3];
- E = Ep = ctx->state[4];
- #define F1( x, y, z ) ( x ^ y ^ z )
- #define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) )
- #define F3( x, y, z ) ( ( x | ~y ) ^ z )
- #define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) )
- #define F5( x, y, z ) ( x ^ ( y | ~z ) )
- #define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
- #define P( a, b, c, d, e, r, s, f, k ) \
- a += f( b, c, d ) + X[r] + k; \
- a = S( a, s ) + e; \
- c = S( c, 10 );
- #define P2( a, b, c, d, e, r, s, rp, sp ) \
- P( a, b, c, d, e, r, s, F, K ); \
- P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
- #define F F1
- #define K 0x00000000
- #define Fp F5
- #define Kp 0x50A28BE6
- P2( A, B, C, D, E, 0, 11, 5, 8 );
- P2( E, A, B, C, D, 1, 14, 14, 9 );
- P2( D, E, A, B, C, 2, 15, 7, 9 );
- P2( C, D, E, A, B, 3, 12, 0, 11 );
- P2( B, C, D, E, A, 4, 5, 9, 13 );
- P2( A, B, C, D, E, 5, 8, 2, 15 );
- P2( E, A, B, C, D, 6, 7, 11, 15 );
- P2( D, E, A, B, C, 7, 9, 4, 5 );
- P2( C, D, E, A, B, 8, 11, 13, 7 );
- P2( B, C, D, E, A, 9, 13, 6, 7 );
- P2( A, B, C, D, E, 10, 14, 15, 8 );
- P2( E, A, B, C, D, 11, 15, 8, 11 );
- P2( D, E, A, B, C, 12, 6, 1, 14 );
- P2( C, D, E, A, B, 13, 7, 10, 14 );
- P2( B, C, D, E, A, 14, 9, 3, 12 );
- P2( A, B, C, D, E, 15, 8, 12, 6 );
- #undef F
- #undef K
- #undef Fp
- #undef Kp
- #define F F2
- #define K 0x5A827999
- #define Fp F4
- #define Kp 0x5C4DD124
- P2( E, A, B, C, D, 7, 7, 6, 9 );
- P2( D, E, A, B, C, 4, 6, 11, 13 );
- P2( C, D, E, A, B, 13, 8, 3, 15 );
- P2( B, C, D, E, A, 1, 13, 7, 7 );
- P2( A, B, C, D, E, 10, 11, 0, 12 );
- P2( E, A, B, C, D, 6, 9, 13, 8 );
- P2( D, E, A, B, C, 15, 7, 5, 9 );
- P2( C, D, E, A, B, 3, 15, 10, 11 );
- P2( B, C, D, E, A, 12, 7, 14, 7 );
- P2( A, B, C, D, E, 0, 12, 15, 7 );
- P2( E, A, B, C, D, 9, 15, 8, 12 );
- P2( D, E, A, B, C, 5, 9, 12, 7 );
- P2( C, D, E, A, B, 2, 11, 4, 6 );
- P2( B, C, D, E, A, 14, 7, 9, 15 );
- P2( A, B, C, D, E, 11, 13, 1, 13 );
- P2( E, A, B, C, D, 8, 12, 2, 11 );
- #undef F
- #undef K
- #undef Fp
- #undef Kp
- #define F F3
- #define K 0x6ED9EBA1
- #define Fp F3
- #define Kp 0x6D703EF3
- P2( D, E, A, B, C, 3, 11, 15, 9 );
- P2( C, D, E, A, B, 10, 13, 5, 7 );
- P2( B, C, D, E, A, 14, 6, 1, 15 );
- P2( A, B, C, D, E, 4, 7, 3, 11 );
- P2( E, A, B, C, D, 9, 14, 7, 8 );
- P2( D, E, A, B, C, 15, 9, 14, 6 );
- P2( C, D, E, A, B, 8, 13, 6, 6 );
- P2( B, C, D, E, A, 1, 15, 9, 14 );
- P2( A, B, C, D, E, 2, 14, 11, 12 );
- P2( E, A, B, C, D, 7, 8, 8, 13 );
- P2( D, E, A, B, C, 0, 13, 12, 5 );
- P2( C, D, E, A, B, 6, 6, 2, 14 );
- P2( B, C, D, E, A, 13, 5, 10, 13 );
- P2( A, B, C, D, E, 11, 12, 0, 13 );
- P2( E, A, B, C, D, 5, 7, 4, 7 );
- P2( D, E, A, B, C, 12, 5, 13, 5 );
- #undef F
- #undef K
- #undef Fp
- #undef Kp
- #define F F4
- #define K 0x8F1BBCDC
- #define Fp F2
- #define Kp 0x7A6D76E9
- P2( C, D, E, A, B, 1, 11, 8, 15 );
- P2( B, C, D, E, A, 9, 12, 6, 5 );
- P2( A, B, C, D, E, 11, 14, 4, 8 );
- P2( E, A, B, C, D, 10, 15, 1, 11 );
- P2( D, E, A, B, C, 0, 14, 3, 14 );
- P2( C, D, E, A, B, 8, 15, 11, 14 );
- P2( B, C, D, E, A, 12, 9, 15, 6 );
- P2( A, B, C, D, E, 4, 8, 0, 14 );
- P2( E, A, B, C, D, 13, 9, 5, 6 );
- P2( D, E, A, B, C, 3, 14, 12, 9 );
- P2( C, D, E, A, B, 7, 5, 2, 12 );
- P2( B, C, D, E, A, 15, 6, 13, 9 );
- P2( A, B, C, D, E, 14, 8, 9, 12 );
- P2( E, A, B, C, D, 5, 6, 7, 5 );
- P2( D, E, A, B, C, 6, 5, 10, 15 );
- P2( C, D, E, A, B, 2, 12, 14, 8 );
- #undef F
- #undef K
- #undef Fp
- #undef Kp
- #define F F5
- #define K 0xA953FD4E
- #define Fp F1
- #define Kp 0x00000000
- P2( B, C, D, E, A, 4, 9, 12, 8 );
- P2( A, B, C, D, E, 0, 15, 15, 5 );
- P2( E, A, B, C, D, 5, 5, 10, 12 );
- P2( D, E, A, B, C, 9, 11, 4, 9 );
- P2( C, D, E, A, B, 7, 6, 1, 12 );
- P2( B, C, D, E, A, 12, 8, 5, 5 );
- P2( A, B, C, D, E, 2, 13, 8, 14 );
- P2( E, A, B, C, D, 10, 12, 7, 6 );
- P2( D, E, A, B, C, 14, 5, 6, 8 );
- P2( C, D, E, A, B, 1, 12, 2, 13 );
- P2( B, C, D, E, A, 3, 13, 13, 6 );
- P2( A, B, C, D, E, 8, 14, 14, 5 );
- P2( E, A, B, C, D, 11, 11, 0, 15 );
- P2( D, E, A, B, C, 6, 8, 3, 13 );
- P2( C, D, E, A, B, 15, 5, 9, 11 );
- P2( B, C, D, E, A, 13, 6, 11, 11 );
- #undef F
- #undef K
- #undef Fp
- #undef Kp
- C = ctx->state[1] + C + Dp;
- ctx->state[1] = ctx->state[2] + D + Ep;
- ctx->state[2] = ctx->state[3] + E + Ap;
- ctx->state[3] = ctx->state[4] + A + Bp;
- ctx->state[4] = ctx->state[0] + B + Cp;
- ctx->state[0] = C;
- }
- #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
- /*
- * RIPEMD-160 process buffer
- */
- void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
- const unsigned char *input, size_t ilen )
- {
- size_t fill;
- uint32_t left;
- if( ilen == 0 )
- return;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if( ctx->total[0] < (uint32_t) ilen )
- ctx->total[1]++;
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- mbedtls_ripemd160_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
- while( ilen >= 64 )
- {
- mbedtls_ripemd160_process( ctx, input );
- input += 64;
- ilen -= 64;
- }
- if( ilen > 0 )
- {
- memcpy( (void *) (ctx->buffer + left), input, ilen );
- }
- }
- static const unsigned char ripemd160_padding[64] =
- {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /*
- * RIPEMD-160 final digest
- */
- void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] )
- {
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx->total[0] >> 29 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
- last = ctx->total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
- mbedtls_ripemd160_update( ctx, msglen, 8 );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
- PUT_UINT32_LE( ctx->state[4], output, 16 );
- }
- /*
- * output = RIPEMD-160( input buffer )
- */
- void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
- unsigned char output[20] )
- {
- mbedtls_ripemd160_context ctx;
- mbedtls_ripemd160_init( &ctx );
- mbedtls_ripemd160_starts( &ctx );
- mbedtls_ripemd160_update( &ctx, input, ilen );
- mbedtls_ripemd160_finish( &ctx, output );
- mbedtls_ripemd160_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Test vectors from the RIPEMD-160 paper and
- * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
- */
- #define TESTS 8
- #define KEYS 2
- static const char *ripemd160_test_input[TESTS] =
- {
- "",
- "a",
- "abc",
- "message digest",
- "abcdefghijklmnopqrstuvwxyz",
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
- "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890",
- };
- static const unsigned char ripemd160_test_md[TESTS][20] =
- {
- { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
- 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
- { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
- 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
- { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
- 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
- { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
- 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
- { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
- 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
- { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
- 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
- { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
- 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
- { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
- 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
- };
- /*
- * Checkup routine
- */
- int mbedtls_ripemd160_self_test( int verbose )
- {
- int i;
- unsigned char output[20];
- memset( output, 0, sizeof output );
- for( i = 0; i < TESTS; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 );
- mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i],
- strlen( ripemd160_test_input[i] ),
- output );
- if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef F
- #undef K
- #undef F1
- #undef F2
- #undef F3
- #undef F4
- #undef F5
- #undef P
- #undef S
- #endif /* MBEDTLS_RIPEMD160_C */
- /********* Start of file library/rsa.c ************/
- /*
- * The RSA public-key cryptosystem
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
- *
- * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
- * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_RSA_C)
- #include <string.h>
- #if defined(MBEDTLS_PKCS1_V21)
- #endif
- #if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
- #include <stdlib.h>
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- /*
- * Initialize an RSA context
- */
- void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
- int padding,
- int hash_id )
- {
- memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
- mbedtls_rsa_set_padding( ctx, padding, hash_id );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- }
- /*
- * Set padding for an existing RSA context
- */
- void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
- {
- ctx->padding = padding;
- ctx->hash_id = hash_id;
- }
- #if defined(MBEDTLS_GENPRIME)
- /*
- * Generate an RSA keypair
- */
- int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- unsigned int nbits, int exponent )
- {
- int ret;
- mbedtls_mpi P1, Q1, H, G;
- if( f_rng == NULL || nbits < 128 || exponent < 3 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G );
- /*
- * find primes P and Q with Q < P so that:
- * GCD( E, (P-1)*(Q-1) ) == 1
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
- do
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
- f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
- f_rng, p_rng ) );
- if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
- mbedtls_mpi_swap( &ctx->P, &ctx->Q );
- if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
- continue;
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
- if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
- continue;
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
- }
- while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
- /*
- * D = E^-1 mod ((P-1)*(Q-1))
- * DP = D mod (P - 1)
- * DQ = D mod (Q - 1)
- * QP = Q^-1 mod P
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
- ctx->len = ( mbedtls_mpi_bitlen( &ctx->N ) + 7 ) >> 3;
- cleanup:
- mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G );
- if( ret != 0 )
- {
- mbedtls_rsa_free( ctx );
- return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_GENPRIME */
- /*
- * Check a public RSA key
- */
- int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
- {
- if( !ctx->N.p || !ctx->E.p )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- if( ( ctx->N.p[0] & 1 ) == 0 ||
- ( ctx->E.p[0] & 1 ) == 0 )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
- mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
- mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- return( 0 );
- }
- /*
- * Check a private RSA key
- */
- int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
- {
- int ret;
- mbedtls_mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP;
- if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
- return( ret );
- if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- mbedtls_mpi_init( &PQ ); mbedtls_mpi_init( &DE ); mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 );
- mbedtls_mpi_init( &H ); mbedtls_mpi_init( &I ); mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G2 );
- mbedtls_mpi_init( &L1 ); mbedtls_mpi_init( &L2 ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ );
- mbedtls_mpi_init( &QP );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G2, &P1, &Q1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L1, &L2, &H, &G2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &I, &DE, &L1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DP, &ctx->D, &P1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
- /*
- * Check for a valid PKCS1v2 private key
- */
- if( mbedtls_mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
- mbedtls_mpi_cmp_mpi( &DP, &ctx->DP ) != 0 ||
- mbedtls_mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 ||
- mbedtls_mpi_cmp_mpi( &QP, &ctx->QP ) != 0 ||
- mbedtls_mpi_cmp_int( &L2, 0 ) != 0 ||
- mbedtls_mpi_cmp_int( &I, 1 ) != 0 ||
- mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
- {
- ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
- }
- cleanup:
- mbedtls_mpi_free( &PQ ); mbedtls_mpi_free( &DE ); mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 );
- mbedtls_mpi_free( &H ); mbedtls_mpi_free( &I ); mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G2 );
- mbedtls_mpi_free( &L1 ); mbedtls_mpi_free( &L2 ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ );
- mbedtls_mpi_free( &QP );
- if( ret == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
- return( ret );
- if( ret != 0 )
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + ret );
- return( 0 );
- }
- /*
- * Check if contexts holding a public and private key match
- */
- int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv )
- {
- if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
- mbedtls_rsa_check_privkey( prv ) != 0 )
- {
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- }
- if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
- mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
- {
- return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
- }
- return( 0 );
- }
- /*
- * Do an RSA public key operation
- */
- int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
- const unsigned char *input,
- unsigned char *output )
- {
- int ret;
- size_t olen;
- mbedtls_mpi T;
- mbedtls_mpi_init( &T );
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
- if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
- {
- ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
- goto cleanup;
- }
- olen = ctx->len;
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
- cleanup:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- mbedtls_mpi_free( &T );
- if( ret != 0 )
- return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
- return( 0 );
- }
- /*
- * Generate or update blinding values, see section 10 of:
- * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
- * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
- * Berlin Heidelberg, 1996. p. 104-113.
- */
- static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
- {
- int ret, count = 0;
- if( ctx->Vf.p != NULL )
- {
- /* We already have blinding values, just update them by squaring */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
- goto cleanup;
- }
- /* Unblinding value: Vf = random number, invertible mod N */
- do {
- if( count++ > 10 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED );
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
- } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
- /* Blinding value: Vi = Vf^(-e) mod N */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
- cleanup:
- return( ret );
- }
- /*
- * Do an RSA private key operation
- */
- int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- const unsigned char *input,
- unsigned char *output )
- {
- int ret;
- size_t olen;
- mbedtls_mpi T, T1, T2;
- /* Make sure we have private key info, prevent possible misuse */
- if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
- if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
- {
- ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
- goto cleanup;
- }
- if( f_rng != NULL )
- {
- /*
- * Blinding
- * T = T * Vi mod N
- */
- MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
- }
- #if defined(MBEDTLS_RSA_NO_CRT)
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
- #else
- /*
- * faster decryption using the CRT
- *
- * T1 = input ^ dP mod P
- * T2 = input ^ dQ mod Q
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
- /*
- * T = (T1 - T2) * (Q^-1 mod P) mod P
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
- /*
- * T = T2 + T * Q
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
- #endif /* MBEDTLS_RSA_NO_CRT */
- if( f_rng != NULL )
- {
- /*
- * Unblind
- * T = T * Vf mod N
- */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
- }
- olen = ctx->len;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
- cleanup:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
- if( ret != 0 )
- return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
- return( 0 );
- }
- #if defined(MBEDTLS_PKCS1_V21)
- /**
- * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
- *
- * \param dst buffer to mask
- * \param dlen length of destination buffer
- * \param src source of the mask generation
- * \param slen length of the source buffer
- * \param md_ctx message digest context to use
- */
- static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
- size_t slen, mbedtls_md_context_t *md_ctx )
- {
- unsigned char mask[MBEDTLS_MD_MAX_SIZE];
- unsigned char counter[4];
- unsigned char *p;
- unsigned int hlen;
- size_t i, use_len;
- memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
- memset( counter, 0, 4 );
- hlen = mbedtls_md_get_size( md_ctx->md_info );
- // Generate and apply dbMask
- //
- p = dst;
- while( dlen > 0 )
- {
- use_len = hlen;
- if( dlen < hlen )
- use_len = dlen;
- mbedtls_md_starts( md_ctx );
- mbedtls_md_update( md_ctx, src, slen );
- mbedtls_md_update( md_ctx, counter, 4 );
- mbedtls_md_finish( md_ctx, mask );
- for( i = 0; i < use_len; ++i )
- *p++ ^= mask[i];
- counter[3]++;
- dlen -= use_len;
- }
- }
- #endif /* MBEDTLS_PKCS1_V21 */
- #if defined(MBEDTLS_PKCS1_V21)
- /*
- * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
- */
- int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- const unsigned char *label, size_t label_len,
- size_t ilen,
- const unsigned char *input,
- unsigned char *output )
- {
- size_t olen;
- int ret;
- unsigned char *p = output;
- unsigned int hlen;
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( f_rng == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- olen = ctx->len;
- hlen = mbedtls_md_get_size( md_info );
- if( olen < ilen + 2 * hlen + 2 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- memset( output, 0, olen );
- *p++ = 0;
- // Generate a random octet string seed
- //
- if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
- p += hlen;
- // Construct DB
- //
- mbedtls_md( md_info, label, label_len, p );
- p += hlen;
- p += olen - 2 * hlen - 2 - ilen;
- *p++ = 1;
- memcpy( p, input, ilen );
- mbedtls_md_init( &md_ctx );
- mbedtls_md_setup( &md_ctx, md_info, 0 );
- // maskedDB: Apply dbMask to DB
- //
- mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
- &md_ctx );
- // maskedSeed: Apply seedMask to seed
- //
- mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
- &md_ctx );
- mbedtls_md_free( &md_ctx );
- return( ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, output, output )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
- }
- #endif /* MBEDTLS_PKCS1_V21 */
- #if defined(MBEDTLS_PKCS1_V15)
- /*
- * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
- */
- int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode, size_t ilen,
- const unsigned char *input,
- unsigned char *output )
- {
- size_t nb_pad, olen;
- int ret;
- unsigned char *p = output;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( f_rng == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- olen = ctx->len;
- if( olen < ilen + 11 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- nb_pad = olen - 3 - ilen;
- *p++ = 0;
- if( mode == MBEDTLS_RSA_PUBLIC )
- {
- *p++ = MBEDTLS_RSA_CRYPT;
- while( nb_pad-- > 0 )
- {
- int rng_dl = 100;
- do {
- ret = f_rng( p_rng, p, 1 );
- } while( *p == 0 && --rng_dl && ret == 0 );
- // Check if RNG failed to generate data
- //
- if( rng_dl == 0 || ret != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
- p++;
- }
- }
- else
- {
- *p++ = MBEDTLS_RSA_SIGN;
- while( nb_pad-- > 0 )
- *p++ = 0xFF;
- }
- *p++ = 0;
- memcpy( p, input, ilen );
- return( ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, output, output )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
- }
- #endif /* MBEDTLS_PKCS1_V15 */
- /*
- * Add the message padding, then do an RSA operation
- */
- int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode, size_t ilen,
- const unsigned char *input,
- unsigned char *output )
- {
- switch( ctx->padding )
- {
- #if defined(MBEDTLS_PKCS1_V15)
- case MBEDTLS_RSA_PKCS_V15:
- return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
- input, output );
- #endif
- #if defined(MBEDTLS_PKCS1_V21)
- case MBEDTLS_RSA_PKCS_V21:
- return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
- ilen, input, output );
- #endif
- default:
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- }
- }
- #if defined(MBEDTLS_PKCS1_V21)
- /*
- * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
- */
- int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- const unsigned char *label, size_t label_len,
- size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len )
- {
- int ret;
- size_t ilen, i, pad_len;
- unsigned char *p, bad, pad_done;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
- unsigned int hlen;
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- /*
- * Parameters sanity checks
- */
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- ilen = ctx->len;
- if( ilen < 16 || ilen > sizeof( buf ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- /*
- * RSA operation
- */
- ret = ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, input, buf )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
- if( ret != 0 )
- return( ret );
- /*
- * Unmask data and generate lHash
- */
- hlen = mbedtls_md_get_size( md_info );
- mbedtls_md_init( &md_ctx );
- mbedtls_md_setup( &md_ctx, md_info, 0 );
- /* Generate lHash */
- mbedtls_md( md_info, label, label_len, lhash );
- /* seed: Apply seedMask to maskedSeed */
- mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
- &md_ctx );
- /* DB: Apply dbMask to maskedDB */
- mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
- &md_ctx );
- mbedtls_md_free( &md_ctx );
- /*
- * Check contents, in "constant-time"
- */
- p = buf;
- bad = 0;
- bad |= *p++; /* First byte must be 0 */
- p += hlen; /* Skip seed */
- /* Check lHash */
- for( i = 0; i < hlen; i++ )
- bad |= lhash[i] ^ *p++;
- /* Get zero-padding len, but always read till end of buffer
- * (minus one, for the 01 byte) */
- pad_len = 0;
- pad_done = 0;
- for( i = 0; i < ilen - 2 * hlen - 2; i++ )
- {
- pad_done |= p[i];
- pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
- }
- p += pad_len;
- bad |= *p++ ^ 0x01;
- /*
- * The only information "leaked" is whether the padding was correct or not
- * (eg, no data is copied if it was not correct). This meets the
- * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
- * the different error conditions.
- */
- if( bad != 0 )
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- if( ilen - ( p - buf ) > output_max_len )
- return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
- *olen = ilen - (p - buf);
- memcpy( output, p, *olen );
- return( 0 );
- }
- #endif /* MBEDTLS_PKCS1_V21 */
- #if defined(MBEDTLS_PKCS1_V15)
- /*
- * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
- */
- int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode, size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len)
- {
- int ret;
- size_t ilen, pad_count = 0, i;
- unsigned char *p, bad, pad_done = 0;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- ilen = ctx->len;
- if( ilen < 16 || ilen > sizeof( buf ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- ret = ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, input, buf )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
- if( ret != 0 )
- return( ret );
- p = buf;
- bad = 0;
- /*
- * Check and get padding len in "constant-time"
- */
- bad |= *p++; /* First byte must be 0 */
- /* This test does not depend on secret data */
- if( mode == MBEDTLS_RSA_PRIVATE )
- {
- bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
- /* Get padding len, but always read till end of buffer
- * (minus one, for the 00 byte) */
- for( i = 0; i < ilen - 3; i++ )
- {
- pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
- pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
- }
- p += pad_count;
- bad |= *p++; /* Must be zero */
- }
- else
- {
- bad |= *p++ ^ MBEDTLS_RSA_SIGN;
- /* Get padding len, but always read till end of buffer
- * (minus one, for the 00 byte) */
- for( i = 0; i < ilen - 3; i++ )
- {
- pad_done |= ( p[i] != 0xFF );
- pad_count += ( pad_done == 0 );
- }
- p += pad_count;
- bad |= *p++; /* Must be zero */
- }
- if( bad )
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- if( ilen - ( p - buf ) > output_max_len )
- return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
- *olen = ilen - (p - buf);
- memcpy( output, p, *olen );
- return( 0 );
- }
- #endif /* MBEDTLS_PKCS1_V15 */
- /*
- * Do an RSA operation, then remove the message padding
- */
- int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode, size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len)
- {
- switch( ctx->padding )
- {
- #if defined(MBEDTLS_PKCS1_V15)
- case MBEDTLS_RSA_PKCS_V15:
- return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
- input, output, output_max_len );
- #endif
- #if defined(MBEDTLS_PKCS1_V21)
- case MBEDTLS_RSA_PKCS_V21:
- return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
- olen, input, output,
- output_max_len );
- #endif
- default:
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- }
- }
- #if defined(MBEDTLS_PKCS1_V21)
- /*
- * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
- */
- int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig )
- {
- size_t olen;
- unsigned char *p = sig;
- unsigned char salt[MBEDTLS_MD_MAX_SIZE];
- unsigned int slen, hlen, offset = 0;
- int ret;
- size_t msb;
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( f_rng == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- olen = ctx->len;
- if( md_alg != MBEDTLS_MD_NONE )
- {
- // Gather length of hash to sign
- //
- md_info = mbedtls_md_info_from_type( md_alg );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hashlen = mbedtls_md_get_size( md_info );
- }
- md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hlen = mbedtls_md_get_size( md_info );
- slen = hlen;
- if( olen < hlen + slen + 2 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- memset( sig, 0, olen );
- // Generate salt of length slen
- //
- if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
- // Note: EMSA-PSS encoding is over the length of N - 1 bits
- //
- msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
- p += olen - hlen * 2 - 2;
- *p++ = 0x01;
- memcpy( p, salt, slen );
- p += slen;
- mbedtls_md_init( &md_ctx );
- mbedtls_md_setup( &md_ctx, md_info, 0 );
- // Generate H = Hash( M' )
- //
- mbedtls_md_starts( &md_ctx );
- mbedtls_md_update( &md_ctx, p, 8 );
- mbedtls_md_update( &md_ctx, hash, hashlen );
- mbedtls_md_update( &md_ctx, salt, slen );
- mbedtls_md_finish( &md_ctx, p );
- // Compensate for boundary condition when applying mask
- //
- if( msb % 8 == 0 )
- offset = 1;
- // maskedDB: Apply dbMask to DB
- //
- mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
- mbedtls_md_free( &md_ctx );
- msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
- sig[0] &= 0xFF >> ( olen * 8 - msb );
- p += hlen;
- *p++ = 0xBC;
- return( ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, sig, sig )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
- }
- #endif /* MBEDTLS_PKCS1_V21 */
- #if defined(MBEDTLS_PKCS1_V15)
- /*
- * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
- */
- /*
- * Do an RSA operation to sign the message digest
- */
- int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig )
- {
- size_t nb_pad, olen, oid_size = 0;
- unsigned char *p = sig;
- const char *oid = NULL;
- unsigned char *sig_try = NULL, *verif = NULL;
- size_t i;
- unsigned char diff;
- volatile unsigned char diff_no_optimize;
- int ret;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- olen = ctx->len;
- nb_pad = olen - 3;
- if( md_alg != MBEDTLS_MD_NONE )
- {
- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- nb_pad -= 10 + oid_size;
- hashlen = mbedtls_md_get_size( md_info );
- }
- nb_pad -= hashlen;
- if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- *p++ = 0;
- *p++ = MBEDTLS_RSA_SIGN;
- memset( p, 0xFF, nb_pad );
- p += nb_pad;
- *p++ = 0;
- if( md_alg == MBEDTLS_MD_NONE )
- {
- memcpy( p, hash, hashlen );
- }
- else
- {
- /*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm DigestAlgorithmIdentifier,
- * digest Digest }
- *
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Digest ::= OCTET STRING
- */
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
- *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
- *p++ = (unsigned char) ( 0x04 + oid_size );
- *p++ = MBEDTLS_ASN1_OID;
- *p++ = oid_size & 0xFF;
- memcpy( p, oid, oid_size );
- p += oid_size;
- *p++ = MBEDTLS_ASN1_NULL;
- *p++ = 0x00;
- *p++ = MBEDTLS_ASN1_OCTET_STRING;
- *p++ = hashlen;
- memcpy( p, hash, hashlen );
- }
- if( mode == MBEDTLS_RSA_PUBLIC )
- return( mbedtls_rsa_public( ctx, sig, sig ) );
- /*
- * In order to prevent Lenstra's attack, make the signature in a
- * temporary buffer and check it before returning it.
- */
- sig_try = mbedtls_calloc( 1, ctx->len );
- if( sig_try == NULL )
- return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
- verif = mbedtls_calloc( 1, ctx->len );
- if( verif == NULL )
- {
- mbedtls_free( sig_try );
- return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
- }
- MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
- MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
- /* Compare in constant time just in case */
- for( diff = 0, i = 0; i < ctx->len; i++ )
- diff |= verif[i] ^ sig[i];
- diff_no_optimize = diff;
- if( diff_no_optimize != 0 )
- {
- ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
- goto cleanup;
- }
- memcpy( sig, sig_try, ctx->len );
- cleanup:
- mbedtls_free( sig_try );
- mbedtls_free( verif );
- return( ret );
- }
- #endif /* MBEDTLS_PKCS1_V15 */
- /*
- * Do an RSA operation to sign the message digest
- */
- int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig )
- {
- switch( ctx->padding )
- {
- #if defined(MBEDTLS_PKCS1_V15)
- case MBEDTLS_RSA_PKCS_V15:
- return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
- hashlen, hash, sig );
- #endif
- #if defined(MBEDTLS_PKCS1_V21)
- case MBEDTLS_RSA_PKCS_V21:
- return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
- hashlen, hash, sig );
- #endif
- default:
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- }
- }
- #if defined(MBEDTLS_PKCS1_V21)
- /*
- * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
- */
- int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- mbedtls_md_type_t mgf1_hash_id,
- int expected_salt_len,
- const unsigned char *sig )
- {
- int ret;
- size_t siglen;
- unsigned char *p;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- unsigned char result[MBEDTLS_MD_MAX_SIZE];
- unsigned char zeros[8];
- unsigned int hlen;
- size_t slen, msb;
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- siglen = ctx->len;
- if( siglen < 16 || siglen > sizeof( buf ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- ret = ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, sig, buf )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
- if( ret != 0 )
- return( ret );
- p = buf;
- if( buf[siglen - 1] != 0xBC )
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- if( md_alg != MBEDTLS_MD_NONE )
- {
- // Gather length of hash to sign
- //
- md_info = mbedtls_md_info_from_type( md_alg );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hashlen = mbedtls_md_get_size( md_info );
- }
- md_info = mbedtls_md_info_from_type( mgf1_hash_id );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hlen = mbedtls_md_get_size( md_info );
- slen = siglen - hlen - 1; /* Currently length of salt + padding */
- memset( zeros, 0, 8 );
- // Note: EMSA-PSS verification is over the length of N - 1 bits
- //
- msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
- // Compensate for boundary condition when applying mask
- //
- if( msb % 8 == 0 )
- {
- p++;
- siglen -= 1;
- }
- if( buf[0] >> ( 8 - siglen * 8 + msb ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- mbedtls_md_init( &md_ctx );
- mbedtls_md_setup( &md_ctx, md_info, 0 );
- mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
- buf[0] &= 0xFF >> ( siglen * 8 - msb );
- while( p < buf + siglen && *p == 0 )
- p++;
- if( p == buf + siglen ||
- *p++ != 0x01 )
- {
- mbedtls_md_free( &md_ctx );
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- }
- /* Actual salt len */
- slen -= p - buf;
- if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
- slen != (size_t) expected_salt_len )
- {
- mbedtls_md_free( &md_ctx );
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- }
- // Generate H = Hash( M' )
- //
- mbedtls_md_starts( &md_ctx );
- mbedtls_md_update( &md_ctx, zeros, 8 );
- mbedtls_md_update( &md_ctx, hash, hashlen );
- mbedtls_md_update( &md_ctx, p, slen );
- mbedtls_md_finish( &md_ctx, result );
- mbedtls_md_free( &md_ctx );
- if( memcmp( p + slen, result, hlen ) == 0 )
- return( 0 );
- else
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- }
- /*
- * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
- */
- int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- const unsigned char *sig )
- {
- mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
- ? (mbedtls_md_type_t) ctx->hash_id
- : md_alg;
- return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
- md_alg, hashlen, hash,
- mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
- sig ) );
- }
- #endif /* MBEDTLS_PKCS1_V21 */
- #if defined(MBEDTLS_PKCS1_V15)
- /*
- * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
- */
- int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- const unsigned char *sig )
- {
- int ret;
- size_t len, siglen, asn1_len;
- unsigned char *p, *end;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- mbedtls_md_type_t msg_md_alg;
- const mbedtls_md_info_t *md_info;
- mbedtls_asn1_buf oid;
- if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- siglen = ctx->len;
- if( siglen < 16 || siglen > sizeof( buf ) )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- ret = ( mode == MBEDTLS_RSA_PUBLIC )
- ? mbedtls_rsa_public( ctx, sig, buf )
- : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
- if( ret != 0 )
- return( ret );
- p = buf;
- if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- while( *p != 0 )
- {
- if( p >= buf + siglen - 1 || *p != 0xFF )
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- p++;
- }
- p++;
- len = siglen - ( p - buf );
- if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
- {
- if( memcmp( p, hash, hashlen ) == 0 )
- return( 0 );
- else
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- }
- md_info = mbedtls_md_info_from_type( md_alg );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- hashlen = mbedtls_md_get_size( md_info );
- end = p + len;
- // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
- //
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( asn1_len + 2 != len )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( asn1_len + 6 + hashlen != len )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- oid.p = p;
- p += oid.len;
- if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( md_alg != msg_md_alg )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- /*
- * assume the algorithm parameters must be NULL
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( asn1_len != hashlen )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- if( memcmp( p, hash, hashlen ) != 0 )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- p += hashlen;
- if( p != end )
- return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
- return( 0 );
- }
- #endif /* MBEDTLS_PKCS1_V15 */
- /*
- * Do an RSA operation and check the message digest
- */
- int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- const unsigned char *sig )
- {
- switch( ctx->padding )
- {
- #if defined(MBEDTLS_PKCS1_V15)
- case MBEDTLS_RSA_PKCS_V15:
- return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
- hashlen, hash, sig );
- #endif
- #if defined(MBEDTLS_PKCS1_V21)
- case MBEDTLS_RSA_PKCS_V21:
- return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
- hashlen, hash, sig );
- #endif
- default:
- return( MBEDTLS_ERR_RSA_INVALID_PADDING );
- }
- }
- /*
- * Copy the components of an RSA key
- */
- int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
- {
- int ret;
- dst->ver = src->ver;
- dst->len = src->len;
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
- dst->padding = src->padding;
- dst->hash_id = src->hash_id;
- cleanup:
- if( ret != 0 )
- mbedtls_rsa_free( dst );
- return( ret );
- }
- /*
- * Free the components of an RSA key
- */
- void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
- {
- mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
- mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->RN );
- mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->DP );
- mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->D );
- mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &ctx->mutex );
- #endif
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Example RSA-1024 keypair, for test purposes
- */
- #define KEY_LEN 128
- #define RSA_N "9292758453063D803DD603D5E777D788" \
- "8ED1D5BF35786190FA2F23EBC0848AEA" \
- "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
- "7130B9CED7ACDF54CFC7555AC14EEBAB" \
- "93A89813FBF3C4F8066D2D800F7C38A8" \
- "1AE31942917403FF4946B0A83D3D3E05" \
- "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
- "5E94BB77B07507233A0BC7BAC8F90F79"
- #define RSA_E "10001"
- #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
- "66CA472BC44D253102F8B4A9D3BFA750" \
- "91386C0077937FE33FA3252D28855837" \
- "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
- "DF79C5CE07EE72C7F123142198164234" \
- "CABB724CF78B8173B9F880FC86322407" \
- "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
- "071513A1E85B5DFA031F21ECAE91A34D"
- #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
- "2C01CAD19EA484A87EA4377637E75500" \
- "FCB2005C5C7DD6EC4AC023CDA285D796" \
- "C3D9E75E1EFC42488BB4F1D13AC30A57"
- #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
- "E211C2B9E5DB1ED0BF61D0D9899620F4" \
- "910E4168387E3C30AA1E00C339A79508" \
- "8452DD96A9A5EA5D9DCA68DA636032AF"
- #define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
- "3C94D22288ACD763FD8E5600ED4A702D" \
- "F84198A5F06C2E72236AE490C93F07F8" \
- "3CC559CD27BC2D1CA488811730BB5725"
- #define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
- "D8AAEA56749EA28623272E4F7D0592AF" \
- "7C1F1313CAC9471B5C523BFE592F517B" \
- "407A1BD76C164B93DA2D32A383E58357"
- #define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
- "F38D18D2B2F0E2DD275AA977E2BF4411" \
- "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
- "A74206CEC169D74BF5A8C50D6F48EA08"
- #define PT_LEN 24
- #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
- "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
- #if defined(MBEDTLS_PKCS1_V15)
- static int myrand( void *rng_state, unsigned char *output, size_t len )
- {
- #if !defined(__OpenBSD__)
- size_t i;
- if( rng_state != NULL )
- rng_state = NULL;
- for( i = 0; i < len; ++i )
- output[i] = rand();
- #else
- if( rng_state != NULL )
- rng_state = NULL;
- arc4random_buf( output, len );
- #endif /* !OpenBSD */
- return( 0 );
- }
- #endif /* MBEDTLS_PKCS1_V15 */
- /*
- * Checkup routine
- */
- int mbedtls_rsa_self_test( int verbose )
- {
- int ret = 0;
- #if defined(MBEDTLS_PKCS1_V15)
- size_t len;
- mbedtls_rsa_context rsa;
- unsigned char rsa_plaintext[PT_LEN];
- unsigned char rsa_decrypted[PT_LEN];
- unsigned char rsa_ciphertext[KEY_LEN];
- #if defined(MBEDTLS_SHA1_C)
- unsigned char sha1sum[20];
- #endif
- mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
- rsa.len = KEY_LEN;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.N , 16, RSA_N ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.E , 16, RSA_E ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.D , 16, RSA_D ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.P , 16, RSA_P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.Q , 16, RSA_Q ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DP, 16, RSA_DP ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DQ, 16, RSA_DQ ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.QP, 16, RSA_QP ) );
- if( verbose != 0 )
- mbedtls_printf( " RSA key validation: " );
- if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
- mbedtls_rsa_check_privkey( &rsa ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n PKCS#1 encryption : " );
- memcpy( rsa_plaintext, RSA_PT, PT_LEN );
- if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, PT_LEN,
- rsa_plaintext, rsa_ciphertext ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n PKCS#1 decryption : " );
- if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, &len,
- rsa_ciphertext, rsa_decrypted,
- sizeof(rsa_decrypted) ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- #if defined(MBEDTLS_SHA1_C)
- if( verbose != 0 )
- mbedtls_printf( "PKCS#1 data sign : " );
- mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
- if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
- sha1sum, rsa_ciphertext ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
- if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
- sha1sum, rsa_ciphertext ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- #endif /* MBEDTLS_SHA1_C */
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- cleanup:
- mbedtls_rsa_free( &rsa );
- #else /* MBEDTLS_PKCS1_V15 */
- ((void) verbose);
- #endif /* MBEDTLS_PKCS1_V15 */
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_RSA_C */
- /********* Start of file library/sha1.c ************/
- /*
- * FIPS-180-1 compliant SHA-1 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The SHA-1 standard was published by NIST in 1993.
- *
- * http://www.itl.nist.gov/fipspubs/fip180-1.htm
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SHA1_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_SHA1_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void sha1_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- }
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- }
- #endif
- void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
- }
- void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
- {
- if( ctx == NULL )
- return;
- sha1_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
- }
- void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
- const mbedtls_sha1_context *src )
- {
- *dst = *src;
- }
- /*
- * SHA-1 context setup
- */
- void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
- {
- ctx->total[0] = 0;
- ctx->total[1] = 0;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
- }
- #if !defined(MBEDTLS_SHA1_PROCESS_ALT)
- void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
- {
- uint32_t temp, W[16], A, B, C, D, E;
- GET_UINT32_BE( W[ 0], data, 0 );
- GET_UINT32_BE( W[ 1], data, 4 );
- GET_UINT32_BE( W[ 2], data, 8 );
- GET_UINT32_BE( W[ 3], data, 12 );
- GET_UINT32_BE( W[ 4], data, 16 );
- GET_UINT32_BE( W[ 5], data, 20 );
- GET_UINT32_BE( W[ 6], data, 24 );
- GET_UINT32_BE( W[ 7], data, 28 );
- GET_UINT32_BE( W[ 8], data, 32 );
- GET_UINT32_BE( W[ 9], data, 36 );
- GET_UINT32_BE( W[10], data, 40 );
- GET_UINT32_BE( W[11], data, 44 );
- GET_UINT32_BE( W[12], data, 48 );
- GET_UINT32_BE( W[13], data, 52 );
- GET_UINT32_BE( W[14], data, 56 );
- GET_UINT32_BE( W[15], data, 60 );
- #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
- #define R(t) \
- ( \
- temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
- W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
- ( W[t & 0x0F] = S(temp,1) ) \
- )
- #define P(a,b,c,d,e,x) \
- { \
- e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
- }
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
- #define F(x,y,z) (z ^ (x & (y ^ z)))
- #define K 0x5A827999
- P( A, B, C, D, E, W[0] );
- P( E, A, B, C, D, W[1] );
- P( D, E, A, B, C, W[2] );
- P( C, D, E, A, B, W[3] );
- P( B, C, D, E, A, W[4] );
- P( A, B, C, D, E, W[5] );
- P( E, A, B, C, D, W[6] );
- P( D, E, A, B, C, W[7] );
- P( C, D, E, A, B, W[8] );
- P( B, C, D, E, A, W[9] );
- P( A, B, C, D, E, W[10] );
- P( E, A, B, C, D, W[11] );
- P( D, E, A, B, C, W[12] );
- P( C, D, E, A, B, W[13] );
- P( B, C, D, E, A, W[14] );
- P( A, B, C, D, E, W[15] );
- P( E, A, B, C, D, R(16) );
- P( D, E, A, B, C, R(17) );
- P( C, D, E, A, B, R(18) );
- P( B, C, D, E, A, R(19) );
- #undef K
- #undef F
- #define F(x,y,z) (x ^ y ^ z)
- #define K 0x6ED9EBA1
- P( A, B, C, D, E, R(20) );
- P( E, A, B, C, D, R(21) );
- P( D, E, A, B, C, R(22) );
- P( C, D, E, A, B, R(23) );
- P( B, C, D, E, A, R(24) );
- P( A, B, C, D, E, R(25) );
- P( E, A, B, C, D, R(26) );
- P( D, E, A, B, C, R(27) );
- P( C, D, E, A, B, R(28) );
- P( B, C, D, E, A, R(29) );
- P( A, B, C, D, E, R(30) );
- P( E, A, B, C, D, R(31) );
- P( D, E, A, B, C, R(32) );
- P( C, D, E, A, B, R(33) );
- P( B, C, D, E, A, R(34) );
- P( A, B, C, D, E, R(35) );
- P( E, A, B, C, D, R(36) );
- P( D, E, A, B, C, R(37) );
- P( C, D, E, A, B, R(38) );
- P( B, C, D, E, A, R(39) );
- #undef K
- #undef F
- #define F(x,y,z) ((x & y) | (z & (x | y)))
- #define K 0x8F1BBCDC
- P( A, B, C, D, E, R(40) );
- P( E, A, B, C, D, R(41) );
- P( D, E, A, B, C, R(42) );
- P( C, D, E, A, B, R(43) );
- P( B, C, D, E, A, R(44) );
- P( A, B, C, D, E, R(45) );
- P( E, A, B, C, D, R(46) );
- P( D, E, A, B, C, R(47) );
- P( C, D, E, A, B, R(48) );
- P( B, C, D, E, A, R(49) );
- P( A, B, C, D, E, R(50) );
- P( E, A, B, C, D, R(51) );
- P( D, E, A, B, C, R(52) );
- P( C, D, E, A, B, R(53) );
- P( B, C, D, E, A, R(54) );
- P( A, B, C, D, E, R(55) );
- P( E, A, B, C, D, R(56) );
- P( D, E, A, B, C, R(57) );
- P( C, D, E, A, B, R(58) );
- P( B, C, D, E, A, R(59) );
- #undef K
- #undef F
- #define F(x,y,z) (x ^ y ^ z)
- #define K 0xCA62C1D6
- P( A, B, C, D, E, R(60) );
- P( E, A, B, C, D, R(61) );
- P( D, E, A, B, C, R(62) );
- P( C, D, E, A, B, R(63) );
- P( B, C, D, E, A, R(64) );
- P( A, B, C, D, E, R(65) );
- P( E, A, B, C, D, R(66) );
- P( D, E, A, B, C, R(67) );
- P( C, D, E, A, B, R(68) );
- P( B, C, D, E, A, R(69) );
- P( A, B, C, D, E, R(70) );
- P( E, A, B, C, D, R(71) );
- P( D, E, A, B, C, R(72) );
- P( C, D, E, A, B, R(73) );
- P( B, C, D, E, A, R(74) );
- P( A, B, C, D, E, R(75) );
- P( E, A, B, C, D, R(76) );
- P( D, E, A, B, C, R(77) );
- P( C, D, E, A, B, R(78) );
- P( B, C, D, E, A, R(79) );
- #undef K
- #undef F
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
- }
- #endif /* !MBEDTLS_SHA1_PROCESS_ALT */
- /*
- * SHA-1 process buffer
- */
- void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
- {
- size_t fill;
- uint32_t left;
- if( ilen == 0 )
- return;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if( ctx->total[0] < (uint32_t) ilen )
- ctx->total[1]++;
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- mbedtls_sha1_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
- while( ilen >= 64 )
- {
- mbedtls_sha1_process( ctx, input );
- input += 64;
- ilen -= 64;
- }
- if( ilen > 0 )
- memcpy( (void *) (ctx->buffer + left), input, ilen );
- }
- static const unsigned char sha1_padding[64] =
- {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /*
- * SHA-1 final digest
- */
- void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
- {
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx->total[0] >> 29 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
- PUT_UINT32_BE( high, msglen, 0 );
- PUT_UINT32_BE( low, msglen, 4 );
- last = ctx->total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- mbedtls_sha1_update( ctx, sha1_padding, padn );
- mbedtls_sha1_update( ctx, msglen, 8 );
- PUT_UINT32_BE( ctx->state[0], output, 0 );
- PUT_UINT32_BE( ctx->state[1], output, 4 );
- PUT_UINT32_BE( ctx->state[2], output, 8 );
- PUT_UINT32_BE( ctx->state[3], output, 12 );
- PUT_UINT32_BE( ctx->state[4], output, 16 );
- }
- #endif /* !MBEDTLS_SHA1_ALT */
- /*
- * output = SHA-1( input buffer )
- */
- void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
- {
- mbedtls_sha1_context ctx;
- mbedtls_sha1_init( &ctx );
- mbedtls_sha1_starts( &ctx );
- mbedtls_sha1_update( &ctx, input, ilen );
- mbedtls_sha1_finish( &ctx, output );
- mbedtls_sha1_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * FIPS-180-1 test vectors
- */
- static const unsigned char sha1_test_buf[3][57] =
- {
- { "abc" },
- { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
- { "" }
- };
- static const int sha1_test_buflen[3] =
- {
- 3, 56, 1000
- };
- static const unsigned char sha1_test_sum[3][20] =
- {
- { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
- 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
- { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
- 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
- { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
- 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
- };
- /*
- * Checkup routine
- */
- int mbedtls_sha1_self_test( int verbose )
- {
- int i, j, buflen, ret = 0;
- unsigned char buf[1024];
- unsigned char sha1sum[20];
- mbedtls_sha1_context ctx;
- mbedtls_sha1_init( &ctx );
- /*
- * SHA-1
- */
- for( i = 0; i < 3; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " SHA-1 test #%d: ", i + 1 );
- mbedtls_sha1_starts( &ctx );
- if( i == 2 )
- {
- memset( buf, 'a', buflen = 1000 );
- for( j = 0; j < 1000; j++ )
- mbedtls_sha1_update( &ctx, buf, buflen );
- }
- else
- mbedtls_sha1_update( &ctx, sha1_test_buf[i],
- sha1_test_buflen[i] );
- mbedtls_sha1_finish( &ctx, sha1sum );
- if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- exit:
- mbedtls_sha1_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef F
- #undef P
- #undef R
- #undef S
- #endif /* MBEDTLS_SHA1_C */
- /********* Start of file library/sha256.c ************/
- /*
- * FIPS-180-2 compliant SHA-256 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The SHA-256 Secure Hash Standard was published by NIST in 2002.
- *
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SHA256_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_SHA256_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void sha256_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- do { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- } while( 0 )
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- do { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- } while( 0 )
- #endif
- void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
- }
- void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
- {
- if( ctx == NULL )
- return;
- sha256_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
- }
- void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
- const mbedtls_sha256_context *src )
- {
- *dst = *src;
- }
- /*
- * SHA-256 context setup
- */
- void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
- {
- ctx->total[0] = 0;
- ctx->total[1] = 0;
- if( is224 == 0 )
- {
- /* SHA-256 */
- ctx->state[0] = 0x6A09E667;
- ctx->state[1] = 0xBB67AE85;
- ctx->state[2] = 0x3C6EF372;
- ctx->state[3] = 0xA54FF53A;
- ctx->state[4] = 0x510E527F;
- ctx->state[5] = 0x9B05688C;
- ctx->state[6] = 0x1F83D9AB;
- ctx->state[7] = 0x5BE0CD19;
- }
- else
- {
- /* SHA-224 */
- ctx->state[0] = 0xC1059ED8;
- ctx->state[1] = 0x367CD507;
- ctx->state[2] = 0x3070DD17;
- ctx->state[3] = 0xF70E5939;
- ctx->state[4] = 0xFFC00B31;
- ctx->state[5] = 0x68581511;
- ctx->state[6] = 0x64F98FA7;
- ctx->state[7] = 0xBEFA4FA4;
- }
- ctx->is224 = is224;
- }
- #if !defined(MBEDTLS_SHA256_PROCESS_ALT)
- /* Amalgamated Release Mappings */
- #define K K256
- static const uint32_t K[] =
- {
- 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
- 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
- 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
- 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
- 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
- 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
- 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
- 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
- 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
- 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
- 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
- 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
- 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
- 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
- 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
- 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
- };
- #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
- #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
- #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
- #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
- #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
- #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
- #define F0(x,y,z) ((x & y) | (z & (x | y)))
- #define F1(x,y,z) (z ^ (x & (y ^ z)))
- #define R(t) \
- ( \
- W[t] = S1(W[t - 2]) + W[t - 7] + \
- S0(W[t - 15]) + W[t - 16] \
- )
- #define P(a,b,c,d,e,f,g,h,x,K) \
- { \
- temp1 = h + S3(e) + F1(e,f,g) + K + x; \
- temp2 = S2(a) + F0(a,b,c); \
- d += temp1; h = temp1 + temp2; \
- }
- void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
- {
- uint32_t temp1, temp2, W[64];
- uint32_t A[8];
- unsigned int i;
- for( i = 0; i < 8; i++ )
- A[i] = ctx->state[i];
- #if defined(MBEDTLS_SHA256_SMALLER)
- for( i = 0; i < 64; i++ )
- {
- if( i < 16 )
- GET_UINT32_BE( W[i], data, 4 * i );
- else
- R( i );
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
- temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
- A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
- }
- #else /* MBEDTLS_SHA256_SMALLER */
- for( i = 0; i < 16; i++ )
- GET_UINT32_BE( W[i], data, 4 * i );
- for( i = 0; i < 16; i += 8 )
- {
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
- P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
- P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
- P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
- P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
- P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
- P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
- P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
- }
- for( i = 16; i < 64; i += 8 )
- {
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
- P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
- P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
- P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
- P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
- P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
- P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
- P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
- }
- #endif /* MBEDTLS_SHA256_SMALLER */
- for( i = 0; i < 8; i++ )
- ctx->state[i] += A[i];
- }
- #endif /* !MBEDTLS_SHA256_PROCESS_ALT */
- /*
- * SHA-256 process buffer
- */
- void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
- size_t ilen )
- {
- size_t fill;
- uint32_t left;
- if( ilen == 0 )
- return;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if( ctx->total[0] < (uint32_t) ilen )
- ctx->total[1]++;
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- mbedtls_sha256_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
- while( ilen >= 64 )
- {
- mbedtls_sha256_process( ctx, input );
- input += 64;
- ilen -= 64;
- }
- if( ilen > 0 )
- memcpy( (void *) (ctx->buffer + left), input, ilen );
- }
- static const unsigned char sha256_padding[64] =
- {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /*
- * SHA-256 final digest
- */
- void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
- {
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx->total[0] >> 29 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
- PUT_UINT32_BE( high, msglen, 0 );
- PUT_UINT32_BE( low, msglen, 4 );
- last = ctx->total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- mbedtls_sha256_update( ctx, sha256_padding, padn );
- mbedtls_sha256_update( ctx, msglen, 8 );
- PUT_UINT32_BE( ctx->state[0], output, 0 );
- PUT_UINT32_BE( ctx->state[1], output, 4 );
- PUT_UINT32_BE( ctx->state[2], output, 8 );
- PUT_UINT32_BE( ctx->state[3], output, 12 );
- PUT_UINT32_BE( ctx->state[4], output, 16 );
- PUT_UINT32_BE( ctx->state[5], output, 20 );
- PUT_UINT32_BE( ctx->state[6], output, 24 );
- if( ctx->is224 == 0 )
- PUT_UINT32_BE( ctx->state[7], output, 28 );
- }
- #endif /* !MBEDTLS_SHA256_ALT */
- /*
- * output = SHA-256( input buffer )
- */
- void mbedtls_sha256( const unsigned char *input, size_t ilen,
- unsigned char output[32], int is224 )
- {
- mbedtls_sha256_context ctx;
- mbedtls_sha256_init( &ctx );
- mbedtls_sha256_starts( &ctx, is224 );
- mbedtls_sha256_update( &ctx, input, ilen );
- mbedtls_sha256_finish( &ctx, output );
- mbedtls_sha256_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * FIPS-180-2 test vectors
- */
- static const unsigned char sha256_test_buf[3][57] =
- {
- { "abc" },
- { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
- { "" }
- };
- static const int sha256_test_buflen[3] =
- {
- 3, 56, 1000
- };
- static const unsigned char sha256_test_sum[6][32] =
- {
- /*
- * SHA-224 test vectors
- */
- { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
- 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
- 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
- 0xE3, 0x6C, 0x9D, 0xA7 },
- { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
- 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
- 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
- 0x52, 0x52, 0x25, 0x25 },
- { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
- 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
- 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
- 0x4E, 0xE7, 0xAD, 0x67 },
- /*
- * SHA-256 test vectors
- */
- { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
- 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
- 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
- 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
- { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
- 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
- 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
- 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
- { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
- 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
- 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
- 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
- };
- /*
- * Checkup routine
- */
- int mbedtls_sha256_self_test( int verbose )
- {
- int i, j, k, buflen, ret = 0;
- unsigned char buf[1024];
- unsigned char sha256sum[32];
- mbedtls_sha256_context ctx;
- mbedtls_sha256_init( &ctx );
- for( i = 0; i < 6; i++ )
- {
- j = i % 3;
- k = i < 3;
- if( verbose != 0 )
- mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
- mbedtls_sha256_starts( &ctx, k );
- if( j == 2 )
- {
- memset( buf, 'a', buflen = 1000 );
- for( j = 0; j < 1000; j++ )
- mbedtls_sha256_update( &ctx, buf, buflen );
- }
- else
- mbedtls_sha256_update( &ctx, sha256_test_buf[j],
- sha256_test_buflen[j] );
- mbedtls_sha256_finish( &ctx, sha256sum );
- if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- exit:
- mbedtls_sha256_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef P
- #undef R
- #undef SHR
- #undef ROTR
- #undef S0
- #undef S1
- #undef S2
- #undef S3
- #undef F0
- #undef F1
- #undef K
- #endif /* MBEDTLS_SHA256_C */
- /********* Start of file library/sha512.c ************/
- /*
- * FIPS-180-2 compliant SHA-384/512 implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The SHA-512 Secure Hash Standard was published by NIST in 2002.
- *
- * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SHA512_C)
- #if defined(_MSC_VER) || defined(__WATCOMC__)
- #define UL64(x) x##ui64
- #else
- #define UL64(x) x##ULL
- #endif
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_SHA512_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void sha512_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 64-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT64_BE
- #define GET_UINT64_BE(n,b,i) \
- { \
- (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
- | ( (uint64_t) (b)[(i) + 1] << 48 ) \
- | ( (uint64_t) (b)[(i) + 2] << 40 ) \
- | ( (uint64_t) (b)[(i) + 3] << 32 ) \
- | ( (uint64_t) (b)[(i) + 4] << 24 ) \
- | ( (uint64_t) (b)[(i) + 5] << 16 ) \
- | ( (uint64_t) (b)[(i) + 6] << 8 ) \
- | ( (uint64_t) (b)[(i) + 7] ); \
- }
- #endif /* GET_UINT64_BE */
- #ifndef PUT_UINT64_BE
- #define PUT_UINT64_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
- (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 7] = (unsigned char) ( (n) ); \
- }
- #endif /* PUT_UINT64_BE */
- /*
- * Round constants
- */
- /* Amalgamated Release Mappings */
- #define K K512
- static const uint64_t K[80] =
- {
- UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
- UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
- UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
- UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
- UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
- UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
- UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
- UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
- UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
- UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
- UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
- UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
- UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
- UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
- UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
- UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
- UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
- UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
- UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
- UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
- UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
- UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
- UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
- UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
- UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
- UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
- UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
- UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
- UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
- UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
- UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
- UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
- UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
- UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
- UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
- UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
- UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
- UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
- UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
- UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
- };
- void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
- }
- void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
- {
- if( ctx == NULL )
- return;
- sha512_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
- }
- void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
- const mbedtls_sha512_context *src )
- {
- *dst = *src;
- }
- /*
- * SHA-512 context setup
- */
- void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
- {
- ctx->total[0] = 0;
- ctx->total[1] = 0;
- if( is384 == 0 )
- {
- /* SHA-512 */
- ctx->state[0] = UL64(0x6A09E667F3BCC908);
- ctx->state[1] = UL64(0xBB67AE8584CAA73B);
- ctx->state[2] = UL64(0x3C6EF372FE94F82B);
- ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
- ctx->state[4] = UL64(0x510E527FADE682D1);
- ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
- ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
- ctx->state[7] = UL64(0x5BE0CD19137E2179);
- }
- else
- {
- /* SHA-384 */
- ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
- ctx->state[1] = UL64(0x629A292A367CD507);
- ctx->state[2] = UL64(0x9159015A3070DD17);
- ctx->state[3] = UL64(0x152FECD8F70E5939);
- ctx->state[4] = UL64(0x67332667FFC00B31);
- ctx->state[5] = UL64(0x8EB44A8768581511);
- ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
- ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
- }
- ctx->is384 = is384;
- }
- #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
- void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
- {
- int i;
- uint64_t temp1, temp2, W[80];
- uint64_t A, B, C, D, E, F, G, H;
- #define SHR(x,n) (x >> n)
- #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
- #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
- #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
- #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
- #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
- #define F0(x,y,z) ((x & y) | (z & (x | y)))
- #define F1(x,y,z) (z ^ (x & (y ^ z)))
- #define P(a,b,c,d,e,f,g,h,x,K) \
- { \
- temp1 = h + S3(e) + F1(e,f,g) + K + x; \
- temp2 = S2(a) + F0(a,b,c); \
- d += temp1; h = temp1 + temp2; \
- }
- for( i = 0; i < 16; i++ )
- {
- GET_UINT64_BE( W[i], data, i << 3 );
- }
- for( ; i < 80; i++ )
- {
- W[i] = S1(W[i - 2]) + W[i - 7] +
- S0(W[i - 15]) + W[i - 16];
- }
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
- F = ctx->state[5];
- G = ctx->state[6];
- H = ctx->state[7];
- i = 0;
- do
- {
- P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
- P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
- P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
- P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
- P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
- P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
- P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
- P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
- }
- while( i < 80 );
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
- ctx->state[5] += F;
- ctx->state[6] += G;
- ctx->state[7] += H;
- }
- #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
- /*
- * SHA-512 process buffer
- */
- void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
- size_t ilen )
- {
- size_t fill;
- unsigned int left;
- if( ilen == 0 )
- return;
- left = (unsigned int) (ctx->total[0] & 0x7F);
- fill = 128 - left;
- ctx->total[0] += (uint64_t) ilen;
- if( ctx->total[0] < (uint64_t) ilen )
- ctx->total[1]++;
- if( left && ilen >= fill )
- {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- mbedtls_sha512_process( ctx, ctx->buffer );
- input += fill;
- ilen -= fill;
- left = 0;
- }
- while( ilen >= 128 )
- {
- mbedtls_sha512_process( ctx, input );
- input += 128;
- ilen -= 128;
- }
- if( ilen > 0 )
- memcpy( (void *) (ctx->buffer + left), input, ilen );
- }
- static const unsigned char sha512_padding[128] =
- {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /*
- * SHA-512 final digest
- */
- void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
- {
- size_t last, padn;
- uint64_t high, low;
- unsigned char msglen[16];
- high = ( ctx->total[0] >> 61 )
- | ( ctx->total[1] << 3 );
- low = ( ctx->total[0] << 3 );
- PUT_UINT64_BE( high, msglen, 0 );
- PUT_UINT64_BE( low, msglen, 8 );
- last = (size_t)( ctx->total[0] & 0x7F );
- padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
- mbedtls_sha512_update( ctx, sha512_padding, padn );
- mbedtls_sha512_update( ctx, msglen, 16 );
- PUT_UINT64_BE( ctx->state[0], output, 0 );
- PUT_UINT64_BE( ctx->state[1], output, 8 );
- PUT_UINT64_BE( ctx->state[2], output, 16 );
- PUT_UINT64_BE( ctx->state[3], output, 24 );
- PUT_UINT64_BE( ctx->state[4], output, 32 );
- PUT_UINT64_BE( ctx->state[5], output, 40 );
- if( ctx->is384 == 0 )
- {
- PUT_UINT64_BE( ctx->state[6], output, 48 );
- PUT_UINT64_BE( ctx->state[7], output, 56 );
- }
- }
- #endif /* !MBEDTLS_SHA512_ALT */
- /*
- * output = SHA-512( input buffer )
- */
- void mbedtls_sha512( const unsigned char *input, size_t ilen,
- unsigned char output[64], int is384 )
- {
- mbedtls_sha512_context ctx;
- mbedtls_sha512_init( &ctx );
- mbedtls_sha512_starts( &ctx, is384 );
- mbedtls_sha512_update( &ctx, input, ilen );
- mbedtls_sha512_finish( &ctx, output );
- mbedtls_sha512_free( &ctx );
- }
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * FIPS-180-2 test vectors
- */
- static const unsigned char sha512_test_buf[3][113] =
- {
- { "abc" },
- { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
- { "" }
- };
- static const int sha512_test_buflen[3] =
- {
- 3, 112, 1000
- };
- static const unsigned char sha512_test_sum[6][64] =
- {
- /*
- * SHA-384 test vectors
- */
- { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
- 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
- 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
- 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
- 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
- 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
- { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
- 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
- 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
- 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
- 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
- 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
- { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
- 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
- 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
- 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
- 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
- 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
- /*
- * SHA-512 test vectors
- */
- { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
- 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
- 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
- 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
- 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
- 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
- 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
- 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
- { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
- 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
- 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
- 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
- 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
- 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
- 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
- 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
- { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
- 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
- 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
- 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
- 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
- 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
- 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
- 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
- };
- /*
- * Checkup routine
- */
- int mbedtls_sha512_self_test( int verbose )
- {
- int i, j, k, buflen, ret = 0;
- unsigned char buf[1024];
- unsigned char sha512sum[64];
- mbedtls_sha512_context ctx;
- mbedtls_sha512_init( &ctx );
- for( i = 0; i < 6; i++ )
- {
- j = i % 3;
- k = i < 3;
- if( verbose != 0 )
- mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
- mbedtls_sha512_starts( &ctx, k );
- if( j == 2 )
- {
- memset( buf, 'a', buflen = 1000 );
- for( j = 0; j < 1000; j++ )
- mbedtls_sha512_update( &ctx, buf, buflen );
- }
- else
- mbedtls_sha512_update( &ctx, sha512_test_buf[j],
- sha512_test_buflen[j] );
- mbedtls_sha512_finish( &ctx, sha512sum );
- if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- exit:
- mbedtls_sha512_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef P
- #undef R
- #undef SHR
- #undef ROTR
- #undef S0
- #undef S1
- #undef S2
- #undef S3
- #undef F0
- #undef F1
- #undef K
- #endif /* MBEDTLS_SHA512_C */
- /********* Start of file library/ssl_cache.c ************/
- /*
- * SSL session cache implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * These session callbacks use a simple chained list
- * to store and retrieve the session information.
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_CACHE_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
- {
- memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
- cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
- cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &cache->mutex );
- #endif
- }
- int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
- {
- int ret = 1;
- #if defined(MBEDTLS_HAVE_TIME)
- time_t t = time( NULL );
- #endif
- mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
- mbedtls_ssl_cache_entry *cur, *entry;
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_lock( &cache->mutex ) != 0 )
- return( 1 );
- #endif
- cur = cache->chain;
- entry = NULL;
- while( cur != NULL )
- {
- entry = cur;
- cur = cur->next;
- #if defined(MBEDTLS_HAVE_TIME)
- if( cache->timeout != 0 &&
- (int) ( t - entry->timestamp ) > cache->timeout )
- continue;
- #endif
- if( session->ciphersuite != entry->session.ciphersuite ||
- session->compression != entry->session.compression ||
- session->id_len != entry->session.id_len )
- continue;
- if( memcmp( session->id, entry->session.id,
- entry->session.id_len ) != 0 )
- continue;
- memcpy( session->master, entry->session.master, 48 );
- session->verify_result = entry->session.verify_result;
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- /*
- * Restore peer certificate (without rest of the original chain)
- */
- if( entry->peer_cert.p != NULL )
- {
- if( ( session->peer_cert = mbedtls_calloc( 1,
- sizeof(mbedtls_x509_crt) ) ) == NULL )
- {
- ret = 1;
- goto exit;
- }
- mbedtls_x509_crt_init( session->peer_cert );
- if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p,
- entry->peer_cert.len ) != 0 )
- {
- mbedtls_free( session->peer_cert );
- session->peer_cert = NULL;
- ret = 1;
- goto exit;
- }
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- ret = 0;
- goto exit;
- }
- exit:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
- ret = 1;
- #endif
- return( ret );
- }
- int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
- {
- int ret = 1;
- #if defined(MBEDTLS_HAVE_TIME)
- time_t t = time( NULL ), oldest = 0;
- mbedtls_ssl_cache_entry *old = NULL;
- #endif
- mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
- mbedtls_ssl_cache_entry *cur, *prv;
- int count = 0;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 )
- return( ret );
- #endif
- cur = cache->chain;
- prv = NULL;
- while( cur != NULL )
- {
- count++;
- #if defined(MBEDTLS_HAVE_TIME)
- if( cache->timeout != 0 &&
- (int) ( t - cur->timestamp ) > cache->timeout )
- {
- cur->timestamp = t;
- break; /* expired, reuse this slot, update timestamp */
- }
- #endif
- if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 )
- break; /* client reconnected, keep timestamp for session id */
- #if defined(MBEDTLS_HAVE_TIME)
- if( oldest == 0 || cur->timestamp < oldest )
- {
- oldest = cur->timestamp;
- old = cur;
- }
- #endif
- prv = cur;
- cur = cur->next;
- }
- if( cur == NULL )
- {
- #if defined(MBEDTLS_HAVE_TIME)
- /*
- * Reuse oldest entry if max_entries reached
- */
- if( count >= cache->max_entries )
- {
- if( old == NULL )
- {
- ret = 1;
- goto exit;
- }
- cur = old;
- }
- #else /* MBEDTLS_HAVE_TIME */
- /*
- * Reuse first entry in chain if max_entries reached,
- * but move to last place
- */
- if( count >= cache->max_entries )
- {
- if( cache->chain == NULL )
- {
- ret = 1;
- goto exit;
- }
- cur = cache->chain;
- cache->chain = cur->next;
- cur->next = NULL;
- prv->next = cur;
- }
- #endif /* MBEDTLS_HAVE_TIME */
- else
- {
- /*
- * max_entries not reached, create new entry
- */
- cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) );
- if( cur == NULL )
- {
- ret = 1;
- goto exit;
- }
- if( prv == NULL )
- cache->chain = cur;
- else
- prv->next = cur;
- }
- #if defined(MBEDTLS_HAVE_TIME)
- cur->timestamp = t;
- #endif
- }
- memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- /*
- * If we're reusing an entry, free its certificate first
- */
- if( cur->peer_cert.p != NULL )
- {
- mbedtls_free( cur->peer_cert.p );
- memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
- }
- /*
- * Store peer certificate
- */
- if( session->peer_cert != NULL )
- {
- cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
- if( cur->peer_cert.p == NULL )
- {
- ret = 1;
- goto exit;
- }
- memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
- session->peer_cert->raw.len );
- cur->peer_cert.len = session->peer_cert->raw.len;
- cur->session.peer_cert = NULL;
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- ret = 0;
- exit:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
- ret = 1;
- #endif
- return( ret );
- }
- #if defined(MBEDTLS_HAVE_TIME)
- void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout )
- {
- if( timeout < 0 ) timeout = 0;
- cache->timeout = timeout;
- }
- #endif /* MBEDTLS_HAVE_TIME */
- void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max )
- {
- if( max < 0 ) max = 0;
- cache->max_entries = max;
- }
- void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
- {
- mbedtls_ssl_cache_entry *cur, *prv;
- cur = cache->chain;
- while( cur != NULL )
- {
- prv = cur;
- cur = cur->next;
- mbedtls_ssl_session_free( &prv->session );
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- mbedtls_free( prv->peer_cert.p );
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- mbedtls_free( prv );
- }
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &cache->mutex );
- #endif
- }
- #endif /* MBEDTLS_SSL_CACHE_C */
- /********* Start of file library/ssl_ciphersuites.c ************/
- /**
- * \file ssl_ciphersuites.c
- *
- * \brief SSL ciphersuites for mbed TLS
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_TLS_C)
- // #include <stdlib.h>
- #include <string.h>
- /*
- * Ordered from most preferred to least preferred in terms of security.
- *
- * Current rule (except rc4, weak and null which come last):
- * 1. By key exchange:
- * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
- * 2. By key length and cipher:
- * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES
- * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
- * 4. By hash function used when relevant
- * 5. By key exchange/auth again: EC > non-EC
- */
- static const int ciphersuite_preference[] =
- {
- #if defined(MBEDTLS_SSL_CIPHERSUITES)
- MBEDTLS_SSL_CIPHERSUITES,
- #else
- /* All AES-256 ephemeral suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8,
- /* All CAMELLIA-256 ephemeral suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
- /* All AES-128 ephemeral suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
- MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
- /* All CAMELLIA-128 ephemeral suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
- /* All remaining >= 128-bit ephemeral suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- /* The PSK ephemeral suites */
- MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
- MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
- MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
- MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- /* The ECJPAKE suite */
- MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
- /* All AES-256 suites */
- MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
- MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
- MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
- /* All CAMELLIA-256 suites */
- MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
- MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- /* All AES-128 suites */
- MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
- MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
- /* All CAMELLIA-128 suites */
- MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
- MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- /* All remaining >= 128-bit suites */
- MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- /* The RSA PSK suites */
- MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- /* The PSK suites */
- MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
- MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
- MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
- MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
- MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
- MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
- MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
- MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
- MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
- MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- /* RC4 suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA,
- MBEDTLS_TLS_RSA_WITH_RC4_128_SHA,
- MBEDTLS_TLS_RSA_WITH_RC4_128_MD5,
- MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA,
- MBEDTLS_TLS_PSK_WITH_RC4_128_SHA,
- /* Weak suites */
- MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA,
- MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA,
- /* NULL suites */
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA,
- MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384,
- MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256,
- MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA,
- MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384,
- MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256,
- MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA,
- MBEDTLS_TLS_RSA_WITH_NULL_SHA256,
- MBEDTLS_TLS_RSA_WITH_NULL_SHA,
- MBEDTLS_TLS_RSA_WITH_NULL_MD5,
- MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA,
- MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA,
- MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384,
- MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256,
- MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA,
- MBEDTLS_TLS_PSK_WITH_NULL_SHA384,
- MBEDTLS_TLS_PSK_WITH_NULL_SHA256,
- MBEDTLS_TLS_PSK_WITH_NULL_SHA,
- #endif /* MBEDTLS_SSL_CIPHERSUITES */
- 0
- };
- static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
- {
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_SHA1_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA512_C */
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_SHA1_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
- #if defined(MBEDTLS_SHA256_C)
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
- #if defined(MBEDTLS_SHA256_C)
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA1_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_MD5_C)
- { MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif
- #endif /* MBEDTLS_ARC4_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_SHA1_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_SHA1_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- { MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8",
- MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256",
- MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384",
- MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
- MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA",
- MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_GCM_C)
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256",
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384",
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_GCM_C */
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA",
- MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- 0 },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_ARC4_C)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA",
- MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_NODTLS },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_ARC4_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- #if defined(MBEDTLS_AES_C)
- #if defined(MBEDTLS_CCM_C)
- { MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8",
- MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_SHORT_TAG },
- #endif /* MBEDTLS_CCM_C */
- #endif /* MBEDTLS_AES_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- #if defined(MBEDTLS_MD5_C)
- { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #if defined(MBEDTLS_SHA512_C)
- { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384",
- MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- #if defined(MBEDTLS_DES_C)
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA",
- MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- #if defined(MBEDTLS_SHA1_C)
- { MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA",
- MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
- MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
- MBEDTLS_CIPHERSUITE_WEAK },
- #endif /* MBEDTLS_SHA1_C */
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* MBEDTLS_DES_C */
- #endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */
- { 0, "",
- MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE,
- 0, 0, 0, 0, 0 }
- };
- #if defined(MBEDTLS_SSL_CIPHERSUITES)
- const int *mbedtls_ssl_list_ciphersuites( void )
- {
- return( ciphersuite_preference );
- }
- #else
- #define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \
- sizeof( ciphersuite_definitions[0] )
- static int supported_ciphersuites[MAX_CIPHERSUITES];
- /* Amalgamated Release Mappings */
- #define supported_init suites_supported_init
- static int supported_init = 0;
- const int *mbedtls_ssl_list_ciphersuites( void )
- {
- /*
- * On initial call filter out all ciphersuites not supported by current
- * build based on presence in the ciphersuite_definitions.
- */
- if( supported_init == 0 )
- {
- const int *p;
- int *q;
- for( p = ciphersuite_preference, q = supported_ciphersuites;
- *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1;
- p++ )
- {
- #if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES)
- const mbedtls_ssl_ciphersuite_t *cs_info;
- if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL &&
- cs_info->cipher != MBEDTLS_CIPHER_ARC4_128 )
- #else
- if( mbedtls_ssl_ciphersuite_from_id( *p ) != NULL )
- #endif
- *(q++) = *p;
- }
- *q = 0;
- supported_init = 1;
- }
- return( supported_ciphersuites );
- }
- #endif /* MBEDTLS_SSL_CIPHERSUITES */
- const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(
- const char *ciphersuite_name )
- {
- const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions;
- if( NULL == ciphersuite_name )
- return( NULL );
- while( cur->id != 0 )
- {
- if( 0 == strcmp( cur->name, ciphersuite_name ) )
- return( cur );
- cur++;
- }
- return( NULL );
- }
- const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite )
- {
- const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions;
- while( cur->id != 0 )
- {
- if( cur->id == ciphersuite )
- return( cur );
- cur++;
- }
- return( NULL );
- }
- const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id )
- {
- const mbedtls_ssl_ciphersuite_t *cur;
- cur = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
- if( cur == NULL )
- return( "unknown" );
- return( cur->name );
- }
- int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name )
- {
- const mbedtls_ssl_ciphersuite_t *cur;
- cur = mbedtls_ssl_ciphersuite_from_string( ciphersuite_name );
- if( cur == NULL )
- return( 0 );
- return( cur->id );
- }
- #if defined(MBEDTLS_PK_C)
- mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info )
- {
- switch( info->key_exchange )
- {
- case MBEDTLS_KEY_EXCHANGE_RSA:
- case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
- case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
- return( MBEDTLS_PK_RSA );
- case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
- return( MBEDTLS_PK_ECDSA );
- case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
- return( MBEDTLS_PK_ECKEY );
- default:
- return( MBEDTLS_PK_NONE );
- }
- }
- #endif /* MBEDTLS_PK_C */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
- int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
- {
- switch( info->key_exchange )
- {
- case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
- case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
- return( 1 );
- default:
- return( 0 );
- }
- }
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
- {
- switch( info->key_exchange )
- {
- case MBEDTLS_KEY_EXCHANGE_PSK:
- case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
- case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
- return( 1 );
- default:
- return( 0 );
- }
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- /* Amalgamated Release Mappings */
- #undef supported_init
- #endif /* MBEDTLS_SSL_TLS_C */
- /********* Start of file library/ssl_cli.c ************/
- /*
- * SSLv3/TLSv1 client-side functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_CLI_C)
- #include <string.h>
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if !VXWORKS
- #include <stdint.h>
- #endif
- #if defined(MBEDTLS_HAVE_TIME)
- #include <time.h>
- #endif
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- /* Implementation that should never be optimized out by the compiler */
- static void ssl_cli_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #endif
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- static void ssl_cli_write_hostname_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- size_t hostname_len;
- *olen = 0;
- if( ssl->hostname == NULL )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
- ssl->hostname ) );
- hostname_len = strlen( ssl->hostname );
- if( end < p || (size_t)( end - p ) < hostname_len + 9 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- /*
- * struct {
- * NameType name_type;
- * select (name_type) {
- * case host_name: HostName;
- * } name;
- * } ServerName;
- *
- * enum {
- * host_name(0), (255)
- * } NameType;
- *
- * opaque HostName<1..2^16-1>;
- *
- * struct {
- * ServerName server_name_list<1..2^16-1>
- * } ServerNameList;
- */
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
- *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
- memcpy( p, ssl->hostname, hostname_len );
- *olen = hostname_len + 9;
- }
- #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- static void ssl_cli_write_renegotiation_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- *olen = 0;
- if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
- if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- /*
- * Secure renegotiation
- */
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
- *p++ = 0x00;
- *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
- *p++ = ssl->verify_data_len & 0xFF;
- memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
- *olen = 5 + ssl->verify_data_len;
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- /*
- * Only if we handle at least one key exchange that needs signatures.
- */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- static void ssl_cli_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- size_t sig_alg_len = 0;
- const int *md;
- #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
- unsigned char *sig_alg_list = buf + 6;
- #endif
- *olen = 0;
- if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
- for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
- {
- #if defined(MBEDTLS_ECDSA_C)
- sig_alg_len += 2;
- #endif
- #if defined(MBEDTLS_RSA_C)
- sig_alg_len += 2;
- #endif
- }
- if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- /*
- * Prepare signature_algorithms extension (TLS 1.2)
- */
- sig_alg_len = 0;
- for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
- {
- #if defined(MBEDTLS_ECDSA_C)
- sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
- sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
- #endif
- #if defined(MBEDTLS_RSA_C)
- sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
- sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
- #endif
- }
- /*
- * enum {
- * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
- * sha512(6), (255)
- * } HashAlgorithm;
- *
- * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
- * SignatureAlgorithm;
- *
- * struct {
- * HashAlgorithm hash;
- * SignatureAlgorithm signature;
- * } SignatureAndHashAlgorithm;
- *
- * SignatureAndHashAlgorithm
- * supported_signature_algorithms<2..2^16-2>;
- */
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
- *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
- *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
- *olen = 6 + sig_alg_len;
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static void ssl_cli_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- unsigned char *elliptic_curve_list = p + 6;
- size_t elliptic_curve_len = 0;
- const mbedtls_ecp_curve_info *info;
- #if defined(MBEDTLS_ECP_C)
- const mbedtls_ecp_group_id *grp_id;
- #else
- ((void) ssl);
- #endif
- *olen = 0;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
- #if defined(MBEDTLS_ECP_C)
- for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
- {
- info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
- #else
- for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
- {
- #endif
- elliptic_curve_len += 2;
- }
- if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- elliptic_curve_len = 0;
- #if defined(MBEDTLS_ECP_C)
- for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
- {
- info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
- #else
- for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
- {
- #endif
- elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
- elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
- }
- if( elliptic_curve_len == 0 )
- return;
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
- *olen = 6 + elliptic_curve_len;
- }
- static void ssl_cli_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- *olen = 0;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
- if( end < p || (size_t)( end - p ) < 6 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
- *p++ = 0x00;
- *p++ = 2;
- *p++ = 1;
- *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
- *olen = 6;
- }
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
- MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static void ssl_cli_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- int ret;
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- size_t kkpp_len;
- *olen = 0;
- /* Skip costly extension if we can't use EC J-PAKE anyway */
- if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
- if( end - p < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
- /*
- * We may need to send ClientHello multiple times for Hello verification.
- * We don't want to compute fresh values every time (both for performance
- * and consistency reasons), so cache the extension content.
- */
- if( ssl->handshake->ecjpake_cache == NULL ||
- ssl->handshake->ecjpake_cache_len == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
- ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
- p + 2, end - p - 2, &kkpp_len,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
- return;
- }
- ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
- if( ssl->handshake->ecjpake_cache == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
- return;
- }
- memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
- ssl->handshake->ecjpake_cache_len = kkpp_len;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
- kkpp_len = ssl->handshake->ecjpake_cache_len;
- if( (size_t)( end - p - 2 ) < kkpp_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
- }
- *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
- *olen = kkpp_len + 4;
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- static void ssl_cli_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- *olen = 0;
- if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
- if( end < p || (size_t)( end - p ) < 5 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
- *p++ = 0x00;
- *p++ = 1;
- *p++ = ssl->conf->mfl_code;
- *olen = 5;
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- static void ssl_cli_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- *olen = 0;
- if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
- {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
- if( end < p || (size_t)( end - p ) < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- static void ssl_cli_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- *olen = 0;
- if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
- ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
- "extension" ) );
- if( end < p || (size_t)( end - p ) < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- static void ssl_cli_write_extended_ms_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- *olen = 0;
- if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
- ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
- "extension" ) );
- if( end < p || (size_t)( end - p ) < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- static void ssl_cli_write_session_ticket_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- size_t tlen = ssl->session_negotiate->ticket_len;
- *olen = 0;
- if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
- {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
- if( end < p || (size_t)( end - p ) < 4 + tlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
- *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( tlen ) & 0xFF );
- *olen = 4;
- if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
- {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
- memcpy( p, ssl->session_negotiate->ticket, tlen );
- *olen += tlen;
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_SSL_ALPN)
- static void ssl_cli_write_alpn_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
- {
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- size_t alpnlen = 0;
- const char **cur;
- *olen = 0;
- if( ssl->conf->alpn_list == NULL )
- {
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
- for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
- alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
- if( end < p || (size_t)( end - p ) < 6 + alpnlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
- /*
- * opaque ProtocolName<1..2^8-1>;
- *
- * struct {
- * ProtocolName protocol_name_list<2..2^16-1>
- * } ProtocolNameList;
- */
- /* Skip writing extension and list length for now */
- p += 4;
- for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
- {
- *p = (unsigned char)( strlen( *cur ) & 0xFF );
- memcpy( p + 1, *cur, *p );
- p += 1 + *p;
- }
- *olen = p - buf;
- /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
- buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
- buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
- /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
- buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
- buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
- }
- #endif /* MBEDTLS_SSL_ALPN */
- /*
- * Generate random bytes for ClientHello
- */
- static int ssl_generate_random( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned char *p = ssl->handshake->randbytes;
- #if defined(MBEDTLS_HAVE_TIME)
- time_t t;
- #endif
- /*
- * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->verify_cookie != NULL )
- {
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_HAVE_TIME)
- t = time( NULL );
- *p++ = (unsigned char)( t >> 24 );
- *p++ = (unsigned char)( t >> 16 );
- *p++ = (unsigned char)( t >> 8 );
- *p++ = (unsigned char)( t );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
- #else
- if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
- return( ret );
- p += 4;
- #endif /* MBEDTLS_HAVE_TIME */
- if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
- return( ret );
- return( 0 );
- }
- static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
- {
- int ret;
- size_t i, n, olen, ext_len = 0;
- unsigned char *buf;
- unsigned char *p, *q;
- unsigned char offer_compress;
- const int *ciphersuites;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
- if( ssl->conf->f_rng == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
- return( MBEDTLS_ERR_SSL_NO_RNG );
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
- #endif
- {
- ssl->major_ver = ssl->conf->min_major_ver;
- ssl->minor_ver = ssl->conf->min_minor_ver;
- }
- if( ssl->conf->max_major_ver == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
- "consider using mbedtls_ssl_config_defaults()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- /*
- * 0 . 0 handshake type
- * 1 . 3 handshake length
- * 4 . 5 highest version supported
- * 6 . 9 current UNIX time
- * 10 . 37 random bytes
- */
- buf = ssl->out_msg;
- p = buf + 4;
- mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
- ssl->conf->transport, p );
- p += 2;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
- buf[4], buf[5] ) );
- if( ( ret = ssl_generate_random( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
- return( ret );
- }
- memcpy( p, ssl->handshake->randbytes, 32 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
- p += 32;
- /*
- * 38 . 38 session id length
- * 39 . 39+n session id
- * 39+n . 39+n DTLS only: cookie length (1 byte)
- * 40+n . .. DTSL only: cookie
- * .. . .. ciphersuitelist length (2 bytes)
- * .. . .. ciphersuitelist
- * .. . .. compression methods length (1 byte)
- * .. . .. compression methods
- * .. . .. extensions length (2 bytes)
- * .. . .. extensions
- */
- n = ssl->session_negotiate->id_len;
- if( n < 16 || n > 32 ||
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
- #endif
- ssl->handshake->resume == 0 )
- {
- n = 0;
- }
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- /*
- * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
- * generate and include a Session ID in the TLS ClientHello."
- */
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
- #endif
- {
- if( ssl->session_negotiate->ticket != NULL &&
- ssl->session_negotiate->ticket_len != 0 )
- {
- ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
- if( ret != 0 )
- return( ret );
- ssl->session_negotiate->id_len = n = 32;
- }
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- *p++ = (unsigned char) n;
- for( i = 0; i < n; i++ )
- *p++ = ssl->session_negotiate->id[i];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
- /*
- * DTLS cookie
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- if( ssl->handshake->verify_cookie == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
- *p++ = 0;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
- ssl->handshake->verify_cookie,
- ssl->handshake->verify_cookie_len );
- *p++ = ssl->handshake->verify_cookie_len;
- memcpy( p, ssl->handshake->verify_cookie,
- ssl->handshake->verify_cookie_len );
- p += ssl->handshake->verify_cookie_len;
- }
- }
- #endif
- /*
- * Ciphersuite list
- */
- ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
- /* Skip writing ciphersuite length for now */
- n = 0;
- q = p;
- p += 2;
- for( i = 0; ciphersuites[i] != 0; i++ )
- {
- ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
- if( ciphersuite_info == NULL )
- continue;
- if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
- ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
- continue;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
- continue;
- #endif
- #if defined(MBEDTLS_ARC4_C)
- if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
- ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
- continue;
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
- mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
- continue;
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
- ciphersuites[i] ) );
- n++;
- *p++ = (unsigned char)( ciphersuites[i] >> 8 );
- *p++ = (unsigned char)( ciphersuites[i] );
- }
- /*
- * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- */
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
- #endif
- {
- *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
- *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
- n++;
- }
- /* Some versions of OpenSSL don't handle it correctly if not at end */
- #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
- if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
- *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
- *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
- n++;
- }
- #endif
- *q++ = (unsigned char)( n >> 7 );
- *q++ = (unsigned char)( n << 1 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- offer_compress = 1;
- #else
- offer_compress = 0;
- #endif
- /*
- * We don't support compression with DTLS right now: is many records come
- * in the same datagram, uncompressing one could overwrite the next one.
- * We don't want to add complexity for handling that case unless there is
- * an actual need for it.
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- offer_compress = 0;
- #endif
- if( offer_compress )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
- MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
- *p++ = 2;
- *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
- *p++ = MBEDTLS_SSL_COMPRESS_NULL;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
- MBEDTLS_SSL_COMPRESS_NULL ) );
- *p++ = 1;
- *p++ = MBEDTLS_SSL_COMPRESS_NULL;
- }
- // First write extensions, then the total length
- //
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- ssl_cli_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl_cli_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- ssl_cli_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_cli_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- ssl_cli_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_cli_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- ssl_cli_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- ssl_cli_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- ssl_cli_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- ssl_cli_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_ALPN)
- ssl_cli_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ssl_cli_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- /* olen unused if all extensions are disabled */
- ((void) olen);
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
- ext_len ) );
- if( ext_len > 0 )
- {
- *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ext_len ) & 0xFF );
- p += ext_len;
- }
- ssl->out_msglen = p - buf;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO;
- ssl->state++;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- mbedtls_ssl_send_flight_completed( ssl );
- #endif
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
- return( 0 );
- }
- static int ssl_cli_parse_renegotiation_info( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
- {
- /* Check verify-data in constant-time. The length OTOH is no secret */
- if( len != 1 + ssl->verify_data_len * 2 ||
- buf[0] != ssl->verify_data_len * 2 ||
- mbedtls_ssl_safer_memcmp( buf + 1,
- ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
- mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
- ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- }
- else
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- {
- if( len != 1 || buf[0] != 0x00 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
- }
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- static int ssl_cli_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- /*
- * server should use the extension only if we did,
- * and if so the server's value should match ours (and len is always 1)
- */
- if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
- len != 1 ||
- buf[0] != ssl->conf->mfl_code )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- static int ssl_cli_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
- len != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- ((void) buf);
- ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- static int ssl_cli_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
- len != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- ((void) buf);
- ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- static int ssl_cli_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
- len != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- ((void) buf);
- ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- static int ssl_cli_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
- len != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- ((void) buf);
- ssl->handshake->new_session_ticket = 1;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- size_t list_size;
- const unsigned char *p;
- list_size = buf[0];
- if( list_size + 1 != len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- p = buf + 1;
- while( list_size > 0 )
- {
- if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
- p[0] == MBEDTLS_ECP_PF_COMPRESSED )
- {
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
- ssl->handshake->ecdh_ctx.point_format = p[0];
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl->handshake->ecjpake_ctx.point_format = p[0];
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
- return( 0 );
- }
- list_size--;
- p++;
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
- MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
- MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
- return( 0 );
- }
- /* If we got here, we no longer need our cached extension */
- mbedtls_free( ssl->handshake->ecjpake_cache );
- ssl->handshake->ecjpake_cache = NULL;
- ssl->handshake->ecjpake_cache_len = 0;
- if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
- buf, len ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_SSL_ALPN)
- static int ssl_cli_parse_alpn_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- size_t list_len, name_len;
- const char **p;
- /* If we didn't send it, the server shouldn't send it */
- if( ssl->conf->alpn_list == NULL )
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- /*
- * opaque ProtocolName<1..2^8-1>;
- *
- * struct {
- * ProtocolName protocol_name_list<2..2^16-1>
- * } ProtocolNameList;
- *
- * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
- */
- /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
- if( len < 4 )
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- list_len = ( buf[0] << 8 ) | buf[1];
- if( list_len != len - 2 )
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- name_len = buf[2];
- if( name_len != list_len - 1 )
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- /* Check that the server chosen protocol was in our list and save it */
- for( p = ssl->conf->alpn_list; *p != NULL; p++ )
- {
- if( name_len == strlen( *p ) &&
- memcmp( buf + 3, *p, name_len ) == 0 )
- {
- ssl->alpn_chosen = *p;
- return( 0 );
- }
- }
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- #endif /* MBEDTLS_SSL_ALPN */
- /*
- * Parse HelloVerifyRequest. Only called after verifying the HS type.
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
- {
- const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
- int major_ver, minor_ver;
- unsigned char cookie_len;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
- /*
- * struct {
- * ProtocolVersion server_version;
- * opaque cookie<0..2^8-1>;
- * } HelloVerifyRequest;
- */
- MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
- mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
- p += 2;
- /*
- * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
- * even is lower than our min version.
- */
- if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
- minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
- major_ver > ssl->conf->max_major_ver ||
- minor_ver > ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
- return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
- }
- cookie_len = *p++;
- MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
- mbedtls_free( ssl->handshake->verify_cookie );
- ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
- if( ssl->handshake->verify_cookie == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- memcpy( ssl->handshake->verify_cookie, p, cookie_len );
- ssl->handshake->verify_cookie_len = cookie_len;
- /* Start over at ClientHello */
- ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
- mbedtls_ssl_reset_checksum( ssl );
- mbedtls_ssl_recv_flight_completed( ssl );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
- {
- int ret, i;
- size_t n;
- size_t ext_len;
- unsigned char *buf, *ext;
- unsigned char comp;
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- int accept_comp;
- #endif
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- int renegotiation_info_seen = 0;
- #endif
- int handshake_failure = 0;
- const mbedtls_ssl_ciphersuite_t *suite_info;
- #if defined(MBEDTLS_DEBUG_C)
- uint32_t t;
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
- buf = ssl->in_msg;
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- ssl->renego_records_seen++;
- if( ssl->conf->renego_max_records >= 0 &&
- ssl->renego_records_seen > ssl->conf->renego_max_records )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
- "but not honored by server" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
- return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
- return( ssl_parse_hello_verify_request( ssl ) );
- }
- else
- {
- /* We made it through the verification process */
- mbedtls_free( ssl->handshake->verify_cookie );
- ssl->handshake->verify_cookie = NULL;
- ssl->handshake->verify_cookie_len = 0;
- }
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
- buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- /*
- * 0 . 1 server_version
- * 2 . 33 random (maybe including 4 bytes of Unix time)
- * 34 . 34 session_id length = n
- * 35 . 34+n session_id
- * 35+n . 36+n cipher_suite
- * 37+n . 37+n compression_method
- *
- * 38+n . 39+n extensions length (optional)
- * 40+n . .. extensions
- */
- buf += mbedtls_ssl_hs_hdr_len( ssl );
- MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
- mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
- ssl->conf->transport, buf + 0 );
- if( ssl->major_ver < ssl->conf->min_major_ver ||
- ssl->minor_ver < ssl->conf->min_minor_ver ||
- ssl->major_ver > ssl->conf->max_major_ver ||
- ssl->minor_ver > ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
- " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
- ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
- ssl->major_ver, ssl->minor_ver,
- ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
- return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
- }
- #if defined(MBEDTLS_DEBUG_C)
- t = ( (uint32_t) buf[2] << 24 )
- | ( (uint32_t) buf[3] << 16 )
- | ( (uint32_t) buf[4] << 8 )
- | ( (uint32_t) buf[5] );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
- #endif
- memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
- n = buf[34];
- MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 );
- if( n > 32 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
- {
- ext_len = ( ( buf[38 + n] << 8 )
- | ( buf[39 + n] ) );
- if( ( ext_len > 0 && ext_len < 4 ) ||
- ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- }
- else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
- {
- ext_len = 0;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- /* ciphersuite (used later) */
- i = ( buf[35 + n] << 8 ) | buf[36 + n];
- /*
- * Read and check compression
- */
- comp = buf[37 + n];
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- /* See comments in ssl_write_client_hello() */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- accept_comp = 0;
- else
- #endif
- accept_comp = 1;
- if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
- ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )
- #else /* MBEDTLS_ZLIB_SUPPORT */
- if( comp != MBEDTLS_SSL_COMPRESS_NULL )
- #endif/* MBEDTLS_ZLIB_SUPPORT */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- /*
- * Initialize update checksum functions
- */
- ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
- if( ssl->transform_negotiate->ciphersuite_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
- /*
- * Check if the session can be resumed
- */
- if( ssl->handshake->resume == 0 || n == 0 ||
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
- #endif
- ssl->session_negotiate->ciphersuite != i ||
- ssl->session_negotiate->compression != comp ||
- ssl->session_negotiate->id_len != n ||
- memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
- {
- ssl->state++;
- ssl->handshake->resume = 0;
- #if defined(MBEDTLS_HAVE_TIME)
- ssl->session_negotiate->start = time( NULL );
- #endif
- ssl->session_negotiate->ciphersuite = i;
- ssl->session_negotiate->compression = comp;
- ssl->session_negotiate->id_len = n;
- memcpy( ssl->session_negotiate->id, buf + 35, n );
- }
- else
- {
- ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
- if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- return( ret );
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
- ssl->handshake->resume ? "a" : "no" ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
- suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
- if( suite_info == NULL
- #if defined(MBEDTLS_ARC4_C)
- || ( ssl->conf->arc4_disabled &&
- suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
- #endif
- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
- i = 0;
- while( 1 )
- {
- if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
- ssl->session_negotiate->ciphersuite )
- {
- break;
- }
- }
- if( comp != MBEDTLS_SSL_COMPRESS_NULL
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
- #endif
- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- ssl->session_negotiate->compression = comp;
- ext = buf + 40 + n;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
- while( ext_len )
- {
- unsigned int ext_id = ( ( ext[0] << 8 )
- | ( ext[1] ) );
- unsigned int ext_size = ( ( ext[2] << 8 )
- | ( ext[3] ) );
- if( ext_size + 4 > ext_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- switch( ext_id )
- {
- case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- renegotiation_info_seen = 1;
- #endif
- if( ( ret = ssl_cli_parse_renegotiation_info( ssl, ext + 4,
- ext_size ) ) != 0 )
- return( ret );
- break;
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
- if( ( ret = ssl_cli_parse_max_fragment_length_ext( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
- if( ( ret = ssl_cli_parse_truncated_hmac_ext( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
- if( ( ret = ssl_cli_parse_encrypt_then_mac_ext( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
- if( ( ret = ssl_cli_parse_extended_ms_ext( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- case MBEDTLS_TLS_EXT_SESSION_TICKET:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
- if( ( ret = ssl_cli_parse_session_ticket_ext( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
- if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
- MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
- if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
- ext + 4, ext_size ) ) != 0 )
- {
- return( ret );
- }
- break;
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_SSL_ALPN)
- case MBEDTLS_TLS_EXT_ALPN:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
- if( ( ret = ssl_cli_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_ALPN */
- default:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
- ext_id ) );
- }
- ext_len -= 4 + ext_size;
- ext += 4 + ext_size;
- if( ext_len > 0 && ext_len < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- }
- /*
- * Renegotiation security checks
- */
- if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
- handshake_failure = 1;
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
- renegotiation_info_seen == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
- handshake_failure = 1;
- }
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
- handshake_failure = 1;
- }
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- renegotiation_info_seen == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
- handshake_failure = 1;
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- if( handshake_failure == 1 )
- {
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
- unsigned char *end )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- /*
- * Ephemeral DH parameters:
- *
- * struct {
- * opaque dh_p<1..2^16-1>;
- * opaque dh_g<1..2^16-1>;
- * opaque dh_Ys<1..2^16-1>;
- * } ServerDHParams;
- */
- if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
- return( ret );
- }
- if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
- ssl->handshake->dhm_ctx.len * 8,
- ssl->conf->dhm_min_bitlen ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
- return( ret );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
- {
- const mbedtls_ecp_curve_info *curve_info;
- curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id );
- if( curve_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
- #if defined(MBEDTLS_ECP_C)
- if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
- #else
- if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
- ssl->handshake->ecdh_ctx.grp.nbits > 521 )
- #endif
- return( -1 );
- MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
- unsigned char **p,
- unsigned char *end )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- /*
- * Ephemeral ECDH parameters:
- *
- * struct {
- * ECParameters curve_params;
- * ECPoint public;
- * } ServerECDHParams;
- */
- if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
- (const unsigned char **) p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
- return( ret );
- }
- if( ssl_check_server_ecdh_params( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- return( ret );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
- unsigned char **p,
- unsigned char *end )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t len;
- ((void) ssl);
- /*
- * PSK parameters:
- *
- * opaque psk_identity_hint<0..2^16-1>;
- */
- len = (*p)[0] << 8 | (*p)[1];
- *p += 2;
- if( (*p) + len > end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- // TODO: Retrieve PSK identity hint and callback to app
- //
- *p += len;
- ret = 0;
- return( ret );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- /*
- * Generate a pre-master secret and encrypt it with the server's RSA key
- */
- static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
- size_t offset, size_t *olen,
- size_t pms_offset )
- {
- int ret;
- size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
- unsigned char *p = ssl->handshake->premaster + pms_offset;
- if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- }
- /*
- * Generate (part of) the pre-master as
- * struct {
- * ProtocolVersion client_version;
- * opaque random[46];
- * } PreMasterSecret;
- */
- mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
- ssl->conf->transport, p );
- if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
- return( ret );
- }
- ssl->handshake->pmslen = 48;
- if( ssl->session_negotiate->peer_cert == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- /*
- * Now write it out, encrypted
- */
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_RSA ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
- return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
- }
- if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
- p, ssl->handshake->pmslen,
- ssl->out_msg + offset + len_bytes, olen,
- MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
- return( ret );
- }
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( len_bytes == 2 )
- {
- ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
- ssl->out_msg[offset+1] = (unsigned char)( *olen );
- *olen += 2;
- }
- #endif
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
- unsigned char **p,
- unsigned char *end,
- mbedtls_md_type_t *md_alg,
- mbedtls_pk_type_t *pk_alg )
- {
- ((void) ssl);
- *md_alg = MBEDTLS_MD_NONE;
- *pk_alg = MBEDTLS_PK_NONE;
- /* Only in TLS 1.2 */
- if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- return( 0 );
- }
- if( (*p) + 2 > end )
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- /*
- * Get hash algorithm
- */
- if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
- "HashAlgorithm %d", *(p)[0] ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- /*
- * Get signature algorithm
- */
- if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
- "SignatureAlgorithm %d", (*p)[1] ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- /*
- * Check if the hash is acceptable
- */
- if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm "
- "that was not offered" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
- *p += 2;
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- static int ssl_cli_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
- {
- int ret;
- const mbedtls_ecp_keypair *peer_key;
- if( ssl->session_negotiate->peer_cert == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_ECKEY ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
- return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
- }
- peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
- if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
- MBEDTLS_ECDH_THEIRS ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
- return( ret );
- }
- if( ssl_check_server_ecdh_params( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- return( ret );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
- {
- int ret;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- unsigned char *p, *end;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
- ssl->state++;
- return( 0 );
- }
- ((void) p);
- ((void) end);
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
- {
- if( ( ret = ssl_cli_get_ecdh_params_from_cert( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_cli_get_ecdh_params_from_cert", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
- ssl->state++;
- return( 0 );
- }
- ((void) p);
- ((void) end);
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- /*
- * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
- * doesn't use a psk_identity_hint
- */
- if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
- {
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- {
- ssl->record_read = 1;
- goto exit;
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
- end = ssl->in_msg + ssl->in_hslen;
- MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- } /* FALLTROUGH */
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- ; /* nothing more to do */
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
- {
- if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
- {
- if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
- p, end - p );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
- {
- size_t sig_len, hashlen;
- unsigned char hash[64];
- mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
- mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
- unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
- size_t params_len = p - params;
- /*
- * Handle the digitally-signed structure
- */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- if( ssl_parse_signature_algorithm( ssl, &p, end,
- &md_alg, &pk_alg ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
- /* Default hash for ECDSA is SHA-1 */
- if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
- md_alg = MBEDTLS_MD_SHA1;
- }
- else
- #endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- /*
- * Read signature
- */
- sig_len = ( p[0] << 8 ) | p[1];
- p += 2;
- if( end != p + sig_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
- /*
- * Compute the hash that has been signed
- */
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( md_alg == MBEDTLS_MD_NONE )
- {
- mbedtls_md5_context mbedtls_md5;
- mbedtls_sha1_context mbedtls_sha1;
- mbedtls_md5_init( &mbedtls_md5 );
- mbedtls_sha1_init( &mbedtls_sha1 );
- hashlen = 36;
- /*
- * digitally-signed struct {
- * opaque md5_hash[16];
- * opaque sha_hash[20];
- * };
- *
- * md5_hash
- * MD5(ClientHello.random + ServerHello.random
- * + ServerParams);
- * sha_hash
- * SHA(ClientHello.random + ServerHello.random
- * + ServerParams);
- */
- mbedtls_md5_starts( &mbedtls_md5 );
- mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
- mbedtls_md5_update( &mbedtls_md5, params, params_len );
- mbedtls_md5_finish( &mbedtls_md5, hash );
- mbedtls_sha1_starts( &mbedtls_sha1 );
- mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
- mbedtls_sha1_update( &mbedtls_sha1, params, params_len );
- mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
- mbedtls_md5_free( &mbedtls_md5 );
- mbedtls_sha1_free( &mbedtls_sha1 );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
- MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( md_alg != MBEDTLS_MD_NONE )
- {
- mbedtls_md_context_t ctx;
- mbedtls_md_init( &ctx );
- /* Info from md_alg will be used instead */
- hashlen = 0;
- /*
- * digitally-signed struct {
- * opaque client_random[32];
- * opaque server_random[32];
- * ServerDHParams params;
- * };
- */
- if( ( ret = mbedtls_md_setup( &ctx,
- mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
- return( ret );
- }
- mbedtls_md_starts( &ctx );
- mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
- mbedtls_md_update( &ctx, params, params_len );
- mbedtls_md_finish( &ctx, hash );
- mbedtls_md_free( &ctx );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
- (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
- if( ssl->session_negotiate->peer_cert == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- /*
- * Verify signature
- */
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
- return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
- }
- if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
- md_alg, hash, hashlen, p, sig_len ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
- return( ret );
- }
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- exit:
- ssl->state++;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
- return( 0 );
- }
- #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
- {
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
- ssl->state++;
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #else
- static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned char *buf, *p;
- size_t n = 0, m = 0;
- size_t cert_type_len = 0, dn_len = 0;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
- ssl->state++;
- return( 0 );
- }
- if( ssl->record_read == 0 )
- {
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- ssl->record_read = 1;
- }
- ssl->client_auth = 0;
- ssl->state++;
- if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST )
- ssl->client_auth++;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
- ssl->client_auth ? "a" : "no" ) );
- if( ssl->client_auth == 0 )
- goto exit;
- ssl->record_read = 0;
- // TODO: handshake_failure alert for an anonymous server to request
- // client authentication
- /*
- * struct {
- * ClientCertificateType certificate_types<1..2^8-1>;
- * SignatureAndHashAlgorithm
- * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
- * DistinguishedName certificate_authorities<0..2^16-1>;
- * } CertificateRequest;
- */
- buf = ssl->in_msg;
- // Retrieve cert types
- //
- cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
- n = cert_type_len;
- if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
- }
- p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
- while( cert_type_len > 0 )
- {
- #if defined(MBEDTLS_RSA_C)
- if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
- mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
- {
- ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
- break;
- }
- else
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
- mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
- {
- ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
- break;
- }
- else
- #endif
- {
- ; /* Unsupported cert type, ignore */
- }
- cert_type_len--;
- p++;
- }
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- /* Ignored, see comments about hash in write_certificate_verify */
- // TODO: should check the signature part against our pk_key though
- size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
- | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
- m += 2;
- n += sig_alg_len;
- if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
- }
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- /* Ignore certificate_authorities, we only have one cert anyway */
- // TODO: should not send cert if no CA matches
- dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
- | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
- n += dn_len;
- if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
- }
- exit:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
- return( 0 );
- }
- #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
- if( ssl->record_read == 0 )
- {
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- }
- ssl->record_read = 0;
- if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ||
- ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
- }
- ssl->state++;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- mbedtls_ssl_recv_flight_completed( ssl );
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
- return( 0 );
- }
- static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
- {
- int ret;
- size_t i, n;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
- {
- /*
- * DHM key exchange -- send G^X mod P
- */
- n = ssl->handshake->dhm_ctx.len;
- ssl->out_msg[4] = (unsigned char)( n >> 8 );
- ssl->out_msg[5] = (unsigned char)( n );
- i = 6;
- ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
- (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
- if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
- ssl->handshake->premaster,
- MBEDTLS_PREMASTER_SIZE,
- &ssl->handshake->pmslen,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
- {
- /*
- * ECDH key exchange -- send client public value
- */
- i = 4;
- ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
- &n,
- &ssl->out_msg[i], 1000,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
- if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
- &ssl->handshake->pmslen,
- ssl->handshake->premaster,
- MBEDTLS_MPI_MAX_SIZE,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- /*
- * opaque psk_identity<0..2^16-1>;
- */
- if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
- }
- i = 4;
- n = ssl->conf->psk_identity_len;
- if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
- "SSL buffer too short" ) );
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- }
- ssl->out_msg[i++] = (unsigned char)( n >> 8 );
- ssl->out_msg[i++] = (unsigned char)( n );
- memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
- i += ssl->conf->psk_identity_len;
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
- {
- n = 0;
- }
- else
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- {
- if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
- return( ret );
- }
- else
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
- {
- /*
- * ClientDiffieHellmanPublic public (DHM send G^X mod P)
- */
- n = ssl->handshake->dhm_ctx.len;
- if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
- " or SSL buffer too short" ) );
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- }
- ssl->out_msg[i++] = (unsigned char)( n >> 8 );
- ssl->out_msg[i++] = (unsigned char)( n );
- ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
- (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- /*
- * ClientECDiffieHellmanPublic public;
- */
- ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
- &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
- ciphersuite_info->key_exchange ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
- {
- i = 4;
- if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
- return( ret );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- i = 4;
- ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
- ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
- return( ret );
- }
- ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
- ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- {
- ((void) ciphersuite_info);
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- ssl->out_msglen = i + n;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
- ssl->state++;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
- return( 0 );
- }
- #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
- {
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
- if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- return( ret );
- }
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
- ssl->state++;
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #else
- static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- size_t n = 0, offset = 0;
- unsigned char hash[48];
- unsigned char *hash_start = hash;
- mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
- unsigned int hashlen;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
- if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- return( ret );
- }
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
- ssl->state++;
- return( 0 );
- }
- if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
- ssl->state++;
- return( 0 );
- }
- if( mbedtls_ssl_own_key( ssl ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
- }
- /*
- * Make an RSA signature of the handshake digests
- */
- ssl->handshake->calc_verify( ssl, hash );
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- /*
- * digitally-signed struct {
- * opaque md5_hash[16];
- * opaque sha_hash[20];
- * };
- *
- * md5_hash
- * MD5(handshake_messages);
- *
- * sha_hash
- * SHA(handshake_messages);
- */
- hashlen = 36;
- md_alg = MBEDTLS_MD_NONE;
- /*
- * For ECDSA, default hash is SHA-1 only
- */
- if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
- {
- hash_start += 16;
- hashlen -= 16;
- md_alg = MBEDTLS_MD_SHA1;
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
- MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- /*
- * digitally-signed struct {
- * opaque handshake_messages[handshake_messages_length];
- * };
- *
- * Taking shortcut here. We assume that the server always allows the
- * PRF Hash function and has sent it in the allowed signature
- * algorithms list received in the Certificate Request message.
- *
- * Until we encounter a server that does not, we will take this
- * shortcut.
- *
- * Reason: Otherwise we should have running hashes for SHA512 and SHA224
- * in order to satisfy 'weird' needs from the server side.
- */
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
- {
- md_alg = MBEDTLS_MD_SHA384;
- ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
- }
- else
- {
- md_alg = MBEDTLS_MD_SHA256;
- ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
- }
- ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
- /* Info from md_alg will be used instead */
- hashlen = 0;
- offset = 2;
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
- ssl->out_msg + 6 + offset, &n,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
- return( ret );
- }
- ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
- ssl->out_msg[5 + offset] = (unsigned char)( n );
- ssl->out_msglen = 6 + n + offset;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
- ssl->state++;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
- return( ret );
- }
- #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
- {
- int ret;
- uint32_t lifetime;
- size_t ticket_len;
- unsigned char *ticket;
- const unsigned char *msg;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- /*
- * struct {
- * uint32 ticket_lifetime_hint;
- * opaque ticket<0..2^16-1>;
- * } NewSessionTicket;
- *
- * 0 . 3 ticket_lifetime_hint
- * 4 . 5 ticket_len (n)
- * 6 . 5+n ticket content
- */
- if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
- ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
- }
- msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
- lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) |
- ( msg[2] << 8 ) | ( msg[3] );
- ticket_len = ( msg[4] << 8 ) | ( msg[5] );
- if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
- /* We're not waiting for a NewSessionTicket message any more */
- ssl->handshake->new_session_ticket = 0;
- ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
- /*
- * Zero-length ticket means the server changed his mind and doesn't want
- * to send a ticket after all, so just forget it
- */
- if( ticket_len == 0 )
- return( 0 );
- ssl_cli_zeroize( ssl->session_negotiate->ticket,
- ssl->session_negotiate->ticket_len );
- mbedtls_free( ssl->session_negotiate->ticket );
- ssl->session_negotiate->ticket = NULL;
- ssl->session_negotiate->ticket_len = 0;
- if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- memcpy( ticket, msg + 6, ticket_len );
- ssl->session_negotiate->ticket = ticket;
- ssl->session_negotiate->ticket_len = ticket_len;
- ssl->session_negotiate->ticket_lifetime = lifetime;
- /*
- * RFC 5077 section 3.4:
- * "If the client receives a session ticket from the server, then it
- * discards any Session ID that was sent in the ServerHello."
- */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
- ssl->session_negotiate->id_len = 0;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- /*
- * SSL handshake -- client side -- single step
- */
- int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
- {
- int ret = 0;
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- return( ret );
- }
- #endif
- /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
- * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
- ssl->handshake->new_session_ticket != 0 )
- {
- ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
- }
- #endif
- switch( ssl->state )
- {
- case MBEDTLS_SSL_HELLO_REQUEST:
- ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
- break;
- /*
- * ==> ClientHello
- */
- case MBEDTLS_SSL_CLIENT_HELLO:
- ret = ssl_write_client_hello( ssl );
- break;
- /*
- * <== ServerHello
- * Certificate
- * ( ServerKeyExchange )
- * ( CertificateRequest )
- * ServerHelloDone
- */
- case MBEDTLS_SSL_SERVER_HELLO:
- ret = ssl_parse_server_hello( ssl );
- break;
- case MBEDTLS_SSL_SERVER_CERTIFICATE:
- ret = mbedtls_ssl_parse_certificate( ssl );
- break;
- case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
- ret = ssl_parse_server_key_exchange( ssl );
- break;
- case MBEDTLS_SSL_CERTIFICATE_REQUEST:
- ret = ssl_parse_certificate_request( ssl );
- break;
- case MBEDTLS_SSL_SERVER_HELLO_DONE:
- ret = ssl_parse_server_hello_done( ssl );
- break;
- /*
- * ==> ( Certificate/Alert )
- * ClientKeyExchange
- * ( CertificateVerify )
- * ChangeCipherSpec
- * Finished
- */
- case MBEDTLS_SSL_CLIENT_CERTIFICATE:
- ret = mbedtls_ssl_write_certificate( ssl );
- break;
- case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
- ret = ssl_write_client_key_exchange( ssl );
- break;
- case MBEDTLS_SSL_CERTIFICATE_VERIFY:
- ret = ssl_write_certificate_verify( ssl );
- break;
- case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
- ret = mbedtls_ssl_write_change_cipher_spec( ssl );
- break;
- case MBEDTLS_SSL_CLIENT_FINISHED:
- ret = mbedtls_ssl_write_finished( ssl );
- break;
- /*
- * <== ( NewSessionTicket )
- * ChangeCipherSpec
- * Finished
- */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
- ret = ssl_parse_new_session_ticket( ssl );
- break;
- #endif
- case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
- ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
- break;
- case MBEDTLS_SSL_SERVER_FINISHED:
- ret = mbedtls_ssl_parse_finished( ssl );
- break;
- case MBEDTLS_SSL_FLUSH_BUFFERS:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
- ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
- break;
- case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
- mbedtls_ssl_handshake_wrapup( ssl );
- break;
- default:
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- return( ret );
- }
- #endif /* MBEDTLS_SSL_CLI_C */
- /********* Start of file library/ssl_cookie.c ************/
- /*
- * DTLS cookie callbacks implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * These session callbacks use a simple chained list
- * to store and retrieve the session information.
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_COOKIE_C)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #include <string.h>
- /* Implementation that should never be optimized out by the compiler */
- static void ssl_cookie_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
- * available. Try SHA-256 first, 512 wastes resources since we need to stay
- * with max 32 bytes of cookie for DTLS 1.0
- */
- #if defined(MBEDTLS_SHA256_C)
- #define COOKIE_MD MBEDTLS_MD_SHA224
- #define COOKIE_MD_OUTLEN 32
- #define COOKIE_HMAC_LEN 28
- #elif defined(MBEDTLS_SHA512_C)
- #define COOKIE_MD MBEDTLS_MD_SHA384
- #define COOKIE_MD_OUTLEN 48
- #define COOKIE_HMAC_LEN 28
- #elif defined(MBEDTLS_SHA1_C)
- #define COOKIE_MD MBEDTLS_MD_SHA1
- #define COOKIE_MD_OUTLEN 20
- #define COOKIE_HMAC_LEN 20
- #else
- #error "DTLS hello verify needs SHA-1 or SHA-2"
- #endif
- /*
- * Cookies are formed of a 4-bytes timestamp (or serial number) and
- * an HMAC of timestemp and client ID.
- */
- #define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN )
- void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx )
- {
- mbedtls_md_init( &ctx->hmac_ctx );
- #if !defined(MBEDTLS_HAVE_TIME)
- ctx->serial = 0;
- #endif
- ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT;
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- }
- void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay )
- {
- ctx->timeout = delay;
- }
- void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx )
- {
- mbedtls_md_free( &ctx->hmac_ctx );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- ssl_cookie_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
- }
- int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- unsigned char key[COOKIE_MD_OUTLEN];
- if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
- return( ret );
- ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) );
- if( ret != 0 )
- return( ret );
- ssl_cookie_zeroize( key, sizeof( key ) );
- return( 0 );
- }
- /*
- * Generate the HMAC part of a cookie
- */
- static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx,
- const unsigned char time[4],
- unsigned char **p, unsigned char *end,
- const unsigned char *cli_id, size_t cli_id_len )
- {
- unsigned char hmac_out[COOKIE_MD_OUTLEN];
- if( (size_t)( end - *p ) < COOKIE_HMAC_LEN )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 ||
- mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 ||
- mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 ||
- mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 )
- {
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- memcpy( *p, hmac_out, COOKIE_HMAC_LEN );
- *p += COOKIE_HMAC_LEN;
- return( 0 );
- }
- /*
- * Generate cookie for DTLS ClientHello verification
- */
- int mbedtls_ssl_cookie_write( void *p_ctx,
- unsigned char **p, unsigned char *end,
- const unsigned char *cli_id, size_t cli_id_len )
- {
- int ret;
- mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
- unsigned long t;
- if( ctx == NULL || cli_id == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( (size_t)( end - *p ) < COOKIE_LEN )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- #if defined(MBEDTLS_HAVE_TIME)
- t = (unsigned long) time( NULL );
- #else
- t = ctx->serial++;
- #endif
- (*p)[0] = (unsigned char)( t >> 24 );
- (*p)[1] = (unsigned char)( t >> 16 );
- (*p)[2] = (unsigned char)( t >> 8 );
- (*p)[3] = (unsigned char)( t );
- *p += 4;
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
- #endif
- ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4,
- p, end, cli_id, cli_id_len );
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
- MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- /*
- * Check a cookie
- */
- int mbedtls_ssl_cookie_check( void *p_ctx,
- const unsigned char *cookie, size_t cookie_len,
- const unsigned char *cli_id, size_t cli_id_len )
- {
- unsigned char ref_hmac[COOKIE_HMAC_LEN];
- int ret = 0;
- unsigned char *p = ref_hmac;
- mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
- unsigned long cur_time, cookie_time;
- if( ctx == NULL || cli_id == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( cookie_len != COOKIE_LEN )
- return( -1 );
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
- #endif
- if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie,
- &p, p + sizeof( ref_hmac ),
- cli_id, cli_id_len ) != 0 )
- ret = -1;
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
- MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- if( ret != 0 )
- return( ret );
- if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
- return( -1 );
- #if defined(MBEDTLS_HAVE_TIME)
- cur_time = (unsigned long) time( NULL );
- #else
- cur_time = ctx->serial;
- #endif
- cookie_time = ( (unsigned long) cookie[0] << 24 ) |
- ( (unsigned long) cookie[1] << 16 ) |
- ( (unsigned long) cookie[2] << 8 ) |
- ( (unsigned long) cookie[3] );
- if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout )
- return( -1 );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_COOKIE_C */
- /********* Start of file library/ssl_srv.c ************/
- /*
- * SSLv3/TLSv1 server-side functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_SRV_C)
- #include <string.h>
- #if defined(MBEDTLS_ECP_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #if defined(MBEDTLS_HAVE_TIME)
- #include <time.h>
- #endif
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- /* Implementation that should never be optimized out by the compiler */
- static void ssl_srv_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- #endif
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
- int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
- const unsigned char *info,
- size_t ilen )
- {
- if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- mbedtls_free( ssl->cli_id );
- if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( ssl->cli_id, info, ilen );
- ssl->cli_id_len = ilen;
- return( 0 );
- }
- void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
- mbedtls_ssl_cookie_write_t *f_cookie_write,
- mbedtls_ssl_cookie_check_t *f_cookie_check,
- void *p_cookie )
- {
- conf->f_cookie_write = f_cookie_write;
- conf->f_cookie_check = f_cookie_check;
- conf->p_cookie = p_cookie;
- }
- #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- size_t servername_list_size, hostname_len;
- const unsigned char *p;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) );
- servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
- if( servername_list_size + 2 != len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- p = buf + 2;
- while( servername_list_size > 0 )
- {
- hostname_len = ( ( p[1] << 8 ) | p[2] );
- if( hostname_len + 3 > servername_list_size )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME )
- {
- ret = ssl->conf->f_sni( ssl->conf->p_sni,
- ssl, p + 3, hostname_len );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- return( 0 );
- }
- servername_list_size -= hostname_len + 3;
- p += hostname_len + 3;
- }
- if( servername_list_size != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
- static int ssl_srv_parse_renegotiation_info( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
- {
- /* Check verify-data in constant-time. The length OTOH is no secret */
- if( len != 1 + ssl->verify_data_len ||
- buf[0] != ssl->verify_data_len ||
- mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
- ssl->verify_data_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- }
- else
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- {
- if( len != 1 || buf[0] != 0x0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
- }
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- size_t sig_alg_list_size;
- const unsigned char *p;
- const unsigned char *end = buf + len;
- const int *md_cur;
- sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
- if( sig_alg_list_size + 2 != len ||
- sig_alg_list_size % 2 != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- /*
- * For now, ignore the SignatureAlgorithm part and rely on offered
- * ciphersuites only for that part. To be fixed later.
- *
- * So, just look at the HashAlgorithm part.
- */
- for( md_cur = ssl->conf->sig_hashes; *md_cur != MBEDTLS_MD_NONE; md_cur++ ) {
- for( p = buf + 2; p < end; p += 2 ) {
- if( *md_cur == (int) mbedtls_ssl_md_alg_from_hash( p[0] ) ) {
- ssl->handshake->sig_alg = p[0];
- goto have_sig_alg;
- }
- }
- }
- /* Some key echanges do not need signatures at all */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) );
- return( 0 );
- have_sig_alg:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
- ssl->handshake->sig_alg ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- size_t list_size, our_size;
- const unsigned char *p;
- const mbedtls_ecp_curve_info *curve_info, **curves;
- list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
- if( list_size + 2 != len ||
- list_size % 2 != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- /* Should never happen unless client duplicates the extension */
- if( ssl->handshake->curves != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- /* Don't allow our peer to make us allocate too much memory,
- * and leave room for a final 0 */
- our_size = list_size / 2 + 1;
- if( our_size > MBEDTLS_ECP_DP_MAX )
- our_size = MBEDTLS_ECP_DP_MAX;
- if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- ssl->handshake->curves = curves;
- p = buf + 2;
- while( list_size > 0 && our_size > 1 )
- {
- curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] );
- if( curve_info != NULL )
- {
- *curves++ = curve_info;
- our_size--;
- }
- list_size -= 2;
- p += 2;
- }
- return( 0 );
- }
- static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- size_t list_size;
- const unsigned char *p;
- list_size = buf[0];
- if( list_size + 1 != len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- p = buf + 1;
- while( list_size > 0 )
- {
- if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
- p[0] == MBEDTLS_ECP_PF_COMPRESSED )
- {
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
- ssl->handshake->ecdh_ctx.point_format = p[0];
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl->handshake->ecjpake_ctx.point_format = p[0];
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
- return( 0 );
- }
- list_size--;
- p++;
- }
- return( 0 );
- }
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
- MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- int ret;
- if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
- return( 0 );
- }
- if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
- buf, len ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
- return( ret );
- }
- /* Only mark the extension as OK when we're sure it is */
- ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- static int ssl_srv_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ssl->session_negotiate->mfl_code = buf[0];
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- static int ssl_srv_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( len != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ((void) buf);
- if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
- ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- static int ssl_srv_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( len != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ((void) buf);
- if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED &&
- ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
- }
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- static int ssl_srv_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf,
- size_t len )
- {
- if( len != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ((void) buf);
- if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
- ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
- }
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- static int ssl_srv_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t len )
- {
- int ret;
- mbedtls_ssl_session session;
- mbedtls_ssl_session_init( &session );
- if( ssl->conf->f_ticket_parse == NULL ||
- ssl->conf->f_ticket_write == NULL )
- {
- return( 0 );
- }
- /* Remember the client asked us to send a new ticket */
- ssl->handshake->new_session_ticket = 1;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) );
- if( len == 0 )
- return( 0 );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- /*
- * Failures are ok: just ignore the ticket and proceed.
- */
- if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session,
- buf, len ) ) != 0 )
- {
- mbedtls_ssl_session_free( &session );
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) );
- else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED )
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) );
- else
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret );
- return( 0 );
- }
- /*
- * Keep the session ID sent by the client, since we MUST send it back to
- * inform them we're accepting the ticket (RFC 5077 section 3.4)
- */
- session.id_len = ssl->session_negotiate->id_len;
- memcpy( &session.id, ssl->session_negotiate->id, session.id_len );
- mbedtls_ssl_session_free( ssl->session_negotiate );
- memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) );
- /* Zeroize instead of free as we copied the content */
- ssl_srv_zeroize( &session, sizeof( mbedtls_ssl_session ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) );
- ssl->handshake->resume = 1;
- /* Don't send a new ticket after all, this one is OK */
- ssl->handshake->new_session_ticket = 0;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_SSL_ALPN)
- static int ssl_srv_parse_alpn_ext( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- size_t list_len, cur_len, ours_len;
- const unsigned char *theirs, *start, *end;
- const char **ours;
- /* If ALPN not configured, just ignore the extension */
- if( ssl->conf->alpn_list == NULL )
- return( 0 );
- /*
- * opaque ProtocolName<1..2^8-1>;
- *
- * struct {
- * ProtocolName protocol_name_list<2..2^16-1>
- * } ProtocolNameList;
- */
- /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
- if( len < 4 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- list_len = ( buf[0] << 8 ) | buf[1];
- if( list_len != len - 2 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- /*
- * Use our order of preference
- */
- start = buf + 2;
- end = buf + len;
- for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
- {
- ours_len = strlen( *ours );
- for( theirs = start; theirs != end; theirs += cur_len )
- {
- /* If the list is well formed, we should get equality first */
- if( theirs > end )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- cur_len = *theirs++;
- /* Empty strings MUST NOT be included */
- if( cur_len == 0 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- if( cur_len == ours_len &&
- memcmp( theirs, *ours, cur_len ) == 0 )
- {
- ssl->alpn_chosen = *ours;
- return( 0 );
- }
- }
- }
- /* If we get there, no match was found */
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- #endif /* MBEDTLS_SSL_ALPN */
- /*
- * Auxiliary functions for ServerHello parsing and related actions
- */
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- /*
- * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
- */
- #if defined(MBEDTLS_ECDSA_C)
- static int ssl_check_key_curve( mbedtls_pk_context *pk,
- const mbedtls_ecp_curve_info **curves )
- {
- const mbedtls_ecp_curve_info **crv = curves;
- mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id;
- while( *crv != NULL )
- {
- if( (*crv)->grp_id == grp_id )
- return( 0 );
- crv++;
- }
- return( -1 );
- }
- #endif /* MBEDTLS_ECDSA_C */
- /*
- * Try picking a certificate for this ciphersuite,
- * return 0 on success and -1 on failure.
- */
- static int ssl_pick_cert( mbedtls_ssl_context *ssl,
- const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
- {
- mbedtls_ssl_key_cert *cur, *list, *fallback = NULL;
- mbedtls_pk_type_t pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
- uint32_t flags;
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- if( ssl->handshake->sni_key_cert != NULL )
- list = ssl->handshake->sni_key_cert;
- else
- #endif
- list = ssl->conf->key_cert;
- if( pk_alg == MBEDTLS_PK_NONE )
- return( 0 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) );
- if( list == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) );
- return( -1 );
- }
- for( cur = list; cur != NULL; cur = cur->next )
- {
- MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
- cur->cert );
- if( ! mbedtls_pk_can_do( cur->key, pk_alg ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
- continue;
- }
- /*
- * This avoids sending the client a cert it'll reject based on
- * keyUsage or other extensions.
- *
- * It also allows the user to provision different certificates for
- * different uses based on keyUsage, eg if they want to avoid signing
- * and decrypting with the same RSA key.
- */
- if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info,
- MBEDTLS_SSL_IS_SERVER, &flags ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
- "(extended) key usage extension" ) );
- continue;
- }
- #if defined(MBEDTLS_ECDSA_C)
- if( pk_alg == MBEDTLS_PK_ECDSA &&
- ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
- continue;
- }
- #endif
- /*
- * Try to select a SHA-1 certificate for pre-1.2 clients, but still
- * present them a SHA-higher cert rather than failing if it's the only
- * one we got that satisfies the other conditions.
- */
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 &&
- cur->cert->sig_md != MBEDTLS_MD_SHA1 )
- {
- if( fallback == NULL )
- fallback = cur;
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: "
- "sha-2 with pre-TLS 1.2 client" ) );
- continue;
- }
- }
- /* If we get there, we got a winner */
- break;
- }
- if( cur == NULL )
- cur = fallback;
- /* Do not update ssl->handshake->key_cert unless there is a match */
- if( cur != NULL )
- {
- ssl->handshake->key_cert = cur;
- MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate",
- ssl->handshake->key_cert->cert );
- return( 0 );
- }
- return( -1 );
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- /*
- * Check if a given ciphersuite is suitable for use with our config/keys/etc
- * Sets ciphersuite_info only if the suite matches.
- */
- static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
- const mbedtls_ssl_ciphersuite_t **ciphersuite_info )
- {
- const mbedtls_ssl_ciphersuite_t *suite_info;
- suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id );
- if( suite_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) );
- if( suite_info->min_minor_ver > ssl->minor_ver ||
- suite_info->max_minor_ver < ssl->minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
- return( 0 );
- #endif
- #if defined(MBEDTLS_ARC4_C)
- if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
- suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) );
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
- ( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake "
- "not configured or ext missing" ) );
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
- if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
- ( ssl->handshake->curves == NULL ||
- ssl->handshake->curves[0] == NULL ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
- "no common elliptic curve" ) );
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- /* If the ciphersuite requires a pre-shared key and we don't
- * have one, skip it now rather than failing later */
- if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
- ssl->conf->f_psk == NULL &&
- ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
- ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- /*
- * Final check: if ciphersuite requires us to have a
- * certificate/key of a particular type:
- * - select the appropriate certificate if we have one, or
- * - try the next ciphersuite if we don't
- * This must be done last since we modify the key_cert list.
- */
- if( ssl_pick_cert( ssl, suite_info ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
- "no suitable certificate" ) );
- return( 0 );
- }
- #endif
- *ciphersuite_info = suite_info;
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
- static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
- {
- int ret, got_common_suite;
- unsigned int i, j;
- size_t n;
- unsigned int ciph_len, sess_len, chal_len;
- unsigned char *buf, *p;
- const int *ciphersuites;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- buf = ssl->in_hdr;
- MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, 5 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d",
- buf[2] ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d",
- ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]",
- buf[3], buf[4] ) );
- /*
- * SSLv2 Client Hello
- *
- * Record layer:
- * 0 . 1 message length
- *
- * SSL layer:
- * 2 . 2 message type
- * 3 . 4 protocol version
- */
- if( buf[2] != MBEDTLS_SSL_HS_CLIENT_HELLO ||
- buf[3] != MBEDTLS_SSL_MAJOR_VERSION_3 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF;
- if( n < 17 || n > 512 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
- ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver )
- ? buf[4] : ssl->conf->max_minor_ver;
- if( ssl->minor_ver < ssl->conf->min_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
- " [%d:%d] < [%d:%d]",
- ssl->major_ver, ssl->minor_ver,
- ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
- return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
- }
- ssl->handshake->max_major_ver = buf[3];
- ssl->handshake->max_minor_ver = buf[4];
- if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
- ssl->handshake->update_checksum( ssl, buf + 2, n );
- buf = ssl->in_msg;
- n = ssl->in_left - 5;
- /*
- * 0 . 1 ciphersuitelist length
- * 2 . 3 session id length
- * 4 . 5 challenge length
- * 6 . .. ciphersuitelist
- * .. . .. session id
- * .. . .. challenge
- */
- MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, n );
- ciph_len = ( buf[0] << 8 ) | buf[1];
- sess_len = ( buf[2] << 8 ) | buf[3];
- chal_len = ( buf[4] << 8 ) | buf[5];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
- ciph_len, sess_len, chal_len ) );
- /*
- * Make sure each parameter length is valid
- */
- if( ciph_len < 3 || ( ciph_len % 3 ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- if( sess_len > 32 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- if( chal_len < 8 || chal_len > 32 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- if( n != 6 + ciph_len + sess_len + chal_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
- buf + 6, ciph_len );
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id",
- buf + 6 + ciph_len, sess_len );
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, challenge",
- buf + 6 + ciph_len + sess_len, chal_len );
- p = buf + 6 + ciph_len;
- ssl->session_negotiate->id_len = sess_len;
- memset( ssl->session_negotiate->id, 0,
- sizeof( ssl->session_negotiate->id ) );
- memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len );
- p += sess_len;
- memset( ssl->handshake->randbytes, 0, 64 );
- memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len );
- /*
- * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- */
- for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
- {
- if( p[0] == 0 && p[1] == 0 && p[2] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
- "during renegotiation" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
- break;
- }
- }
- #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
- for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
- {
- if( p[0] == 0 &&
- p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
- p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) );
- if( ssl->minor_ver < ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- break;
- }
- }
- #endif /* MBEDTLS_SSL_FALLBACK_SCSV */
- got_common_suite = 0;
- ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
- ciphersuite_info = NULL;
- #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
- for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
- {
- for( i = 0; ciphersuites[i] != 0; i++ )
- #else
- for( i = 0; ciphersuites[i] != 0; i++ )
- {
- for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
- #endif
- {
- if( p[0] != 0 ||
- p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
- p[2] != ( ( ciphersuites[i] ) & 0xFF ) )
- continue;
- got_common_suite = 1;
- if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
- &ciphersuite_info ) ) != 0 )
- return( ret );
- if( ciphersuite_info != NULL )
- goto have_ciphersuite_v2;
- }
- }
- if( got_common_suite )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
- "but none of them usable" ) );
- return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
- return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
- }
- have_ciphersuite_v2:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
- ssl->session_negotiate->ciphersuite = ciphersuites[i];
- ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
- mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
- /*
- * SSLv2 Client Hello relevant renegotiation security checks
- */
- if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ssl->in_left = 0;
- ssl->state++;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
- static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
- {
- int ret, got_common_suite;
- size_t i, j;
- size_t ciph_offset, comp_offset, ext_offset;
- size_t msg_len, ciph_len, sess_len, comp_len, ext_len;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- size_t cookie_offset, cookie_len;
- #endif
- unsigned char *buf, *p, *ext;
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- int renegotiation_info_seen = 0;
- #endif
- int handshake_failure = 0;
- const int *ciphersuites;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- int major, minor;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- read_record_header:
- #endif
- /*
- * If renegotiating, then the input was read with mbedtls_ssl_read_record(),
- * otherwise read it ourselves manually in order to support SSLv2
- * ClientHello, which doesn't use the same record layer format.
- */
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
- #endif
- {
- if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
- }
- buf = ssl->in_hdr;
- #if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
- #endif
- if( ( buf[0] & 0x80 ) != 0 )
- return ssl_parse_client_hello_v2( ssl );
- #endif
- MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) );
- /*
- * SSLv3/TLS Client Hello
- *
- * Record layer:
- * 0 . 0 message type
- * 1 . 2 protocol version
- * 3 . 11 DTLS: epoch + record sequence number
- * 3 . 4 message length
- */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d",
- buf[0] ) );
- if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d",
- ( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]",
- buf[1], buf[2] ) );
- mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 );
- /* According to RFC 5246 Appendix E.1, the version here is typically
- * "{03,00}, the lowest version number supported by the client, [or] the
- * value of ClientHello.client_version", so the only meaningful check here
- * is the major version shouldn't be less than 3 */
- if( major < MBEDTLS_SSL_MAJOR_VERSION_3 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- /* For DTLS if this is the initial handshake, remember the client sequence
- * number to use it in our next message (RFC 6347 4.2.1) */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
- #endif
- )
- {
- /* Epoch should be 0 for initial handshakes */
- if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 );
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record, discarding" ) );
- ssl->next_record_offset = 0;
- ssl->in_left = 0;
- goto read_record_header;
- }
- /* No MAC to check yet, so we can update right now */
- mbedtls_ssl_dtls_replay_update( ssl );
- #endif
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
- {
- /* Set by mbedtls_ssl_read_record() */
- msg_len = ssl->in_hslen;
- }
- else
- #endif
- {
- if( msg_len > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
- /* Done reading this record, get ready for the next one */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl );
- else
- #endif
- ssl->in_left = 0;
- }
- buf = ssl->in_msg;
- MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len );
- ssl->handshake->update_checksum( ssl, buf, msg_len );
- /*
- * Handshake layer:
- * 0 . 0 handshake type
- * 1 . 3 handshake length
- * 4 . 5 DTLS only: message seqence number
- * 6 . 8 DTLS only: fragment offset
- * 9 . 11 DTLS only: fragment length
- */
- if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) );
- if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
- ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) );
- /* We don't support fragmentation of ClientHello (yet?) */
- if( buf[1] != 0 ||
- msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /*
- * Copy the client's handshake message_seq on initial handshakes,
- * check sequence number on renego.
- */
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- /* This couldn't be done in ssl_prepare_handshake_record() */
- unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) |
- ssl->in_msg[5];
- if( cli_msg_seq != ssl->handshake->in_msg_seq )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: "
- "%d (expected %d)", cli_msg_seq,
- ssl->handshake->in_msg_seq ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ssl->handshake->in_msg_seq++;
- }
- else
- #endif
- {
- unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) |
- ssl->in_msg[5];
- ssl->handshake->out_msg_seq = cli_msg_seq;
- ssl->handshake->in_msg_seq = cli_msg_seq + 1;
- }
- /*
- * For now we don't support fragmentation, so make sure
- * fragment_offset == 0 and fragment_length == length
- */
- if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 ||
- memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- buf += mbedtls_ssl_hs_hdr_len( ssl );
- msg_len -= mbedtls_ssl_hs_hdr_len( ssl );
- /*
- * ClientHello layer:
- * 0 . 1 protocol version
- * 2 . 33 random bytes (starting with 4 bytes of Unix time)
- * 34 . 35 session id length (1 byte)
- * 35 . 34+x session id
- * 35+x . 35+x DTLS only: cookie length (1 byte)
- * 36+x . .. DTLS only: cookie
- * .. . .. ciphersuite list length (2 bytes)
- * .. . .. ciphersuite list
- * .. . .. compression alg. list length (1 byte)
- * .. . .. compression alg. list
- * .. . .. extensions length (2 bytes, optional)
- * .. . .. extensions (optional)
- */
- /*
- * Minimal length (with everything empty and extensions ommitted) is
- * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
- * read at least up to session id length without worrying.
- */
- if( msg_len < 38 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- /*
- * Check and save the protocol version
- */
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 );
- mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
- ssl->conf->transport, buf );
- ssl->handshake->max_major_ver = ssl->major_ver;
- ssl->handshake->max_minor_ver = ssl->minor_ver;
- if( ssl->major_ver < ssl->conf->min_major_ver ||
- ssl->minor_ver < ssl->conf->min_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
- " [%d:%d] < [%d:%d]",
- ssl->major_ver, ssl->minor_ver,
- ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
- return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
- }
- if( ssl->major_ver > ssl->conf->max_major_ver )
- {
- ssl->major_ver = ssl->conf->max_major_ver;
- ssl->minor_ver = ssl->conf->max_minor_ver;
- }
- else if( ssl->minor_ver > ssl->conf->max_minor_ver )
- ssl->minor_ver = ssl->conf->max_minor_ver;
- /*
- * Save client random (inc. Unix time)
- */
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 );
- memcpy( ssl->handshake->randbytes, buf + 2, 32 );
- /*
- * Check the session ID length and save session ID
- */
- sess_len = buf[34];
- if( sess_len > sizeof( ssl->session_negotiate->id ) ||
- sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len );
- ssl->session_negotiate->id_len = sess_len;
- memset( ssl->session_negotiate->id, 0,
- sizeof( ssl->session_negotiate->id ) );
- memcpy( ssl->session_negotiate->id, buf + 35,
- ssl->session_negotiate->id_len );
- /*
- * Check the cookie length and content
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- cookie_offset = 35 + sess_len;
- cookie_len = buf[cookie_offset];
- if( cookie_offset + 1 + cookie_len + 2 > msg_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
- buf + cookie_offset + 1, cookie_len );
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
- if( ssl->conf->f_cookie_check != NULL
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
- #endif
- )
- {
- if( ssl->conf->f_cookie_check( ssl->conf->p_cookie,
- buf + cookie_offset + 1, cookie_len,
- ssl->cli_id, ssl->cli_id_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) );
- ssl->handshake->verify_cookie_len = 1;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) );
- ssl->handshake->verify_cookie_len = 0;
- }
- }
- else
- #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- {
- /* We know we didn't send a cookie, so it should be empty */
- if( cookie_len != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) );
- }
- /*
- * Check the ciphersuitelist length (will be parsed later)
- */
- ciph_offset = cookie_offset + 1 + cookie_len;
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- ciph_offset = 35 + sess_len;
- ciph_len = ( buf[ciph_offset + 0] << 8 )
- | ( buf[ciph_offset + 1] );
- if( ciph_len < 2 ||
- ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
- ( ciph_len % 2 ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
- buf + ciph_offset + 2, ciph_len );
- /*
- * Check the compression algorithms length and pick one
- */
- comp_offset = ciph_offset + 2 + ciph_len;
- comp_len = buf[comp_offset];
- if( comp_len < 1 ||
- comp_len > 16 ||
- comp_len + comp_offset + 1 > msg_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression",
- buf + comp_offset + 1, comp_len );
- ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- for( i = 0; i < comp_len; ++i )
- {
- if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE;
- break;
- }
- }
- #endif
- /* See comments in ssl_write_client_hello() */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
- #endif
- /*
- * Check the extension length
- */
- ext_offset = comp_offset + 1 + comp_len;
- if( msg_len > ext_offset )
- {
- if( msg_len < ext_offset + 2 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- ext_len = ( buf[ext_offset + 0] << 8 )
- | ( buf[ext_offset + 1] );
- if( ( ext_len > 0 && ext_len < 4 ) ||
- msg_len != ext_offset + 2 + ext_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- }
- else
- ext_len = 0;
- ext = buf + ext_offset + 2;
- MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
- while( ext_len != 0 )
- {
- unsigned int ext_id = ( ( ext[0] << 8 )
- | ( ext[1] ) );
- unsigned int ext_size = ( ( ext[2] << 8 )
- | ( ext[3] ) );
- if( ext_size + 4 > ext_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- switch( ext_id )
- {
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- case MBEDTLS_TLS_EXT_SERVERNAME:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
- if( ssl->conf->f_sni == NULL )
- break;
- ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
- case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- renegotiation_info_seen = 1;
- #endif
- ret = ssl_srv_parse_renegotiation_info( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- case MBEDTLS_TLS_EXT_SIG_ALG:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- break;
- #endif
- ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
- ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
- ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
- ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
- MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) );
- ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
- ret = ssl_srv_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
- ret = ssl_srv_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
- ret = ssl_srv_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
- ret = ssl_srv_parse_extended_ms_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- case MBEDTLS_TLS_EXT_SESSION_TICKET:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
- ret = ssl_srv_parse_session_ticket_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_SSL_ALPN)
- case MBEDTLS_TLS_EXT_ALPN:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
- ret = ssl_srv_parse_alpn_ext( ssl, ext + 4, ext_size );
- if( ret != 0 )
- return( ret );
- break;
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- default:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
- ext_id ) );
- }
- ext_len -= 4 + ext_size;
- ext += 4 + ext_size;
- if( ext_len > 0 && ext_len < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- }
- #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
- for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 )
- {
- if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
- p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) );
- if( ssl->minor_ver < ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- break;
- }
- }
- #endif /* MBEDTLS_SSL_FALLBACK_SCSV */
- /*
- * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- */
- for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 )
- {
- if( p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) );
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- #endif
- ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
- break;
- }
- }
- /*
- * Renegotiation security checks
- */
- if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
- handshake_failure = 1;
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
- renegotiation_info_seen == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
- handshake_failure = 1;
- }
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
- handshake_failure = 1;
- }
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- renegotiation_info_seen == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
- handshake_failure = 1;
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- if( handshake_failure == 1 )
- {
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- /*
- * Search for a matching ciphersuite
- * (At the end because we need information from the EC-based extensions
- * and certificate from the SNI callback triggered by the SNI extension.)
- */
- got_common_suite = 0;
- ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
- ciphersuite_info = NULL;
- #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
- for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
- {
- for( i = 0; ciphersuites[i] != 0; i++ )
- #else
- for( i = 0; ciphersuites[i] != 0; i++ )
- {
- for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
- #endif
- {
- if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
- p[1] != ( ( ciphersuites[i] ) & 0xFF ) )
- continue;
- got_common_suite = 1;
- if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
- &ciphersuite_info ) ) != 0 )
- return( ret );
- if( ciphersuite_info != NULL )
- goto have_ciphersuite;
- }
- }
- if( got_common_suite )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
- "but none of them usable" ) );
- mbedtls_ssl_send_fatal_handshake_failure( ssl );
- return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
- mbedtls_ssl_send_fatal_handshake_failure( ssl );
- for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) {
- int code = (p[0] & 0xFF) << 8 | (p[1] & 0xFF);
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Client cipher %s, 0x%04X", mbedtls_ssl_get_ciphersuite_name(code), code));
- }
- return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
- }
- have_ciphersuite:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
- ssl->session_negotiate->ciphersuite = ciphersuites[i];
- ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
- mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
- ssl->state++;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- mbedtls_ssl_recv_flight_completed( ssl );
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- static void ssl_srv_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- static void ssl_srv_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- const mbedtls_ssl_ciphersuite_t *suite = NULL;
- const mbedtls_cipher_info_t *cipher = NULL;
- if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- *olen = 0;
- return;
- }
- /*
- * RFC 7366: "If a server receives an encrypt-then-MAC request extension
- * from a client and then selects a stream or Authenticated Encryption
- * with Associated Data (AEAD) ciphersuite, it MUST NOT send an
- * encrypt-then-MAC response extension back to the client."
- */
- if( ( suite = mbedtls_ssl_ciphersuite_from_id(
- ssl->session_negotiate->ciphersuite ) ) == NULL ||
- ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL ||
- cipher->mode != MBEDTLS_MODE_CBC )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- static void ssl_srv_write_extended_ms_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret "
- "extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- static void ssl_srv_write_session_ticket_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- if( ssl->handshake->new_session_ticket == 0 )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
- *p++ = 0x00;
- *p++ = 0x00;
- *olen = 4;
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- static void ssl_srv_write_renegotiation_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
- {
- *p++ = 0x00;
- *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF;
- *p++ = ssl->verify_data_len * 2 & 0xFF;
- memcpy( p, ssl->peer_verify_data, ssl->verify_data_len );
- p += ssl->verify_data_len;
- memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
- p += ssl->verify_data_len;
- }
- else
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- {
- *p++ = 0x00;
- *p++ = 0x01;
- *p++ = 0x00;
- }
- *olen = p - buf;
- }
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- static void ssl_srv_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- if( ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
- *p++ = 0x00;
- *p++ = 1;
- *p++ = ssl->session_negotiate->mfl_code;
- *olen = 5;
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static void ssl_srv_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- unsigned char *p = buf;
- ((void) ssl);
- if( ( ssl->handshake->cli_exts &
- MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
- *p++ = 0x00;
- *p++ = 2;
- *p++ = 1;
- *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
- *olen = 6;
- }
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- static void ssl_srv_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf,
- size_t *olen )
- {
- int ret;
- unsigned char *p = buf;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- size_t kkpp_len;
- *olen = 0;
- /* Skip costly computation if not needed */
- if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
- MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) );
- if( end - p < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
- return;
- }
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
- ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
- p + 2, end - p - 2, &kkpp_len,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
- return;
- }
- *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
- *olen = kkpp_len + 4;
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_SSL_ALPN )
- static void ssl_srv_write_alpn_ext( mbedtls_ssl_context *ssl,
- unsigned char *buf, size_t *olen )
- {
- if( ssl->alpn_chosen == NULL )
- {
- *olen = 0;
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) );
- /*
- * 0 . 1 ext identifier
- * 2 . 3 ext length
- * 4 . 5 protocol list length
- * 6 . 6 protocol name length
- * 7 . 7+n protocol name
- */
- buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
- buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
- *olen = 7 + strlen( ssl->alpn_chosen );
- buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
- buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
- buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
- buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
- buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF );
- memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
- }
- #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
- static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned char *p = ssl->out_msg + 4;
- unsigned char *cookie_len_byte;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) );
- /*
- * struct {
- * ProtocolVersion server_version;
- * opaque cookie<0..2^8-1>;
- * } HelloVerifyRequest;
- */
- /* The RFC is not clear on this point, but sending the actual negotiated
- * version looks like the most interoperable thing to do. */
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, p );
- MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
- p += 2;
- /* If we get here, f_cookie_check is not null */
- if( ssl->conf->f_cookie_write == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- /* Skip length byte until we know the length */
- cookie_len_byte = p++;
- if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie,
- &p, ssl->out_buf + MBEDTLS_SSL_BUFFER_LEN,
- ssl->cli_id, ssl->cli_id_len ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret );
- return( ret );
- }
- *cookie_len_byte = (unsigned char)( p - ( cookie_len_byte + 1 ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte );
- ssl->out_msglen = p - ssl->out_msg;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
- ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
- {
- #if defined(MBEDTLS_HAVE_TIME)
- time_t t;
- #endif
- int ret;
- size_t olen, ext_len = 0, n;
- unsigned char *buf, *p;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->verify_cookie_len != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
- return( ssl_write_hello_verify_request( ssl ) );
- }
- #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- if( ssl->conf->f_rng == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
- return( MBEDTLS_ERR_SSL_NO_RNG );
- }
- /*
- * 0 . 0 handshake type
- * 1 . 3 handshake length
- * 4 . 5 protocol version
- * 6 . 9 UNIX time()
- * 10 . 37 random bytes
- */
- buf = ssl->out_msg;
- p = buf + 4;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, p );
- p += 2;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
- buf[4], buf[5] ) );
- #if defined(MBEDTLS_HAVE_TIME)
- t = time( NULL );
- *p++ = (unsigned char)( t >> 24 );
- *p++ = (unsigned char)( t >> 16 );
- *p++ = (unsigned char)( t >> 8 );
- *p++ = (unsigned char)( t );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
- #else
- if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
- return( ret );
- p += 4;
- #endif /* MBEDTLS_HAVE_TIME */
- if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
- return( ret );
- p += 28;
- memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
- /*
- * Resume is 0 by default, see ssl_handshake_init().
- * It may be already set to 1 by ssl_srv_parse_session_ticket_ext().
- * If not, try looking up session ID in our cache.
- */
- if( ssl->handshake->resume == 0 &&
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
- #endif
- ssl->session_negotiate->id_len != 0 &&
- ssl->conf->f_get_cache != NULL &&
- ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
- ssl->handshake->resume = 1;
- }
- if( ssl->handshake->resume == 0 )
- {
- /*
- * New session, create a new session id,
- * unless we're about to issue a session ticket
- */
- ssl->state++;
- #if defined(MBEDTLS_HAVE_TIME)
- ssl->session_negotiate->start = time( NULL );
- #endif
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if( ssl->handshake->new_session_ticket != 0 )
- {
- ssl->session_negotiate->id_len = n = 0;
- memset( ssl->session_negotiate->id, 0, 32 );
- }
- else
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- {
- ssl->session_negotiate->id_len = n = 32;
- if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id,
- n ) ) != 0 )
- return( ret );
- }
- }
- else
- {
- /*
- * Resuming a session
- */
- n = ssl->session_negotiate->id_len;
- ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
- if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- return( ret );
- }
- }
- /*
- * 38 . 38 session id length
- * 39 . 38+n session id
- * 39+n . 40+n chosen ciphersuite
- * 41+n . 41+n chosen compression alg.
- * 42+n . 43+n extensions length
- * 44+n . 43+n+m extensions
- */
- *p++ = (unsigned char) ssl->session_negotiate->id_len;
- memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len );
- p += ssl->session_negotiate->id_len;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
- ssl->handshake->resume ? "a" : "no" ) );
- *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 );
- *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite );
- *p++ = (unsigned char)( ssl->session_negotiate->compression );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s",
- mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
- ssl->session_negotiate->compression ) );
- /*
- * First write extensions, then the total length
- */
- ssl_srv_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- ssl_srv_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- ssl_srv_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- ssl_srv_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- ssl_srv_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ssl_srv_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_srv_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- ssl_srv_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- #if defined(MBEDTLS_SSL_ALPN)
- ssl_srv_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
- ext_len += olen;
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
- if( ext_len > 0 )
- {
- *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ext_len ) & 0xFF );
- p += ext_len;
- }
- ssl->out_msglen = p - buf;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO;
- ret = mbedtls_ssl_write_record( ssl );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
- return( ret );
- }
- #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
- {
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
- ssl->state++;
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #else
- static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- size_t dn_size, total_dn_size; /* excluding length bytes */
- size_t ct_len, sa_len; /* including length bytes */
- unsigned char *buf, *p;
- const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- const mbedtls_x509_crt *crt;
- int authmode;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
- ssl->state++;
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET )
- authmode = ssl->handshake->sni_authmode;
- else
- #endif
- authmode = ssl->conf->authmode;
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
- authmode == MBEDTLS_SSL_VERIFY_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
- return( 0 );
- }
- /*
- * 0 . 0 handshake type
- * 1 . 3 handshake length
- * 4 . 4 cert type count
- * 5 .. m-1 cert types
- * m .. m+1 sig alg length (TLS 1.2 only)
- * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only)
- * n .. n+1 length of all DNs
- * n+2 .. n+3 length of DN 1
- * n+4 .. ... Distinguished Name #1
- * ... .. ... length of DN 2, etc.
- */
- buf = ssl->out_msg;
- p = buf + 4;
- /*
- * Supported certificate types
- *
- * ClientCertificateType certificate_types<1..2^8-1>;
- * enum { (255) } ClientCertificateType;
- */
- ct_len = 0;
- #if defined(MBEDTLS_RSA_C)
- p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
- #endif
- p[0] = (unsigned char) ct_len++;
- p += ct_len;
- sa_len = 0;
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Add signature_algorithms for verify (TLS 1.2)
- *
- * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
- *
- * struct {
- * HashAlgorithm hash;
- * SignatureAlgorithm signature;
- * } SignatureAndHashAlgorithm;
- *
- * enum { (255) } HashAlgorithm;
- * enum { (255) } SignatureAlgorithm;
- */
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- /*
- * Only use current running hash algorithm that is already required
- * for requested ciphersuite.
- */
- ssl->handshake->verify_sig_alg = MBEDTLS_SSL_HASH_SHA256;
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
- {
- ssl->handshake->verify_sig_alg = MBEDTLS_SSL_HASH_SHA384;
- }
- /*
- * Supported signature algorithms
- */
- #if defined(MBEDTLS_RSA_C)
- p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
- p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
- p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
- #endif
- p[0] = (unsigned char)( sa_len >> 8 );
- p[1] = (unsigned char)( sa_len );
- sa_len += 2;
- p += sa_len;
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- /*
- * DistinguishedName certificate_authorities<0..2^16-1>;
- * opaque DistinguishedName<1..2^16-1>;
- */
- p += 2;
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- if( ssl->handshake->sni_ca_chain != NULL )
- crt = ssl->handshake->sni_ca_chain;
- else
- #endif
- crt = ssl->conf->ca_chain;
- total_dn_size = 0;
- while( crt != NULL && crt->version != 0 )
- {
- dn_size = crt->subject_raw.len;
- if( end < p ||
- (size_t)( end - p ) < dn_size ||
- (size_t)( end - p ) < 2 + dn_size )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) );
- break;
- }
- *p++ = (unsigned char)( dn_size >> 8 );
- *p++ = (unsigned char)( dn_size );
- memcpy( p, crt->subject_raw.p, dn_size );
- p += dn_size;
- MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size );
- total_dn_size += 2 + dn_size;
- crt = crt->next;
- }
- ssl->out_msglen = p - buf;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
- ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 );
- ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size );
- ret = mbedtls_ssl_write_record( ssl );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) );
- return( ret );
- }
- #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- static int ssl_srv_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
- {
- int ret;
- if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
- return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
- }
- if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx,
- mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ),
- MBEDTLS_ECDH_OURS ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
- {
- int ret;
- size_t n = 0;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- unsigned char *p = ssl->out_msg + 4;
- unsigned char *dig_signed = p;
- size_t dig_signed_len = 0, len;
- ((void) dig_signed);
- ((void) dig_signed_len);
- ((void) len);
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
- ssl->state++;
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
- {
- ssl_srv_get_ecdh_params_from_cert( ssl );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
- ssl->state++;
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- size_t jlen;
- const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
- ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
- p, end - p, &jlen, ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
- return( ret );
- }
- p += jlen;
- n += jlen;
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- /* TODO: Support identity hints */
- *(p++) = 0x00;
- *(p++) = 0x00;
- n += 2;
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
- {
- if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- /*
- * Ephemeral DH parameters:
- *
- * struct {
- * opaque dh_p<1..2^16-1>;
- * opaque dh_g<1..2^16-1>;
- * opaque dh_Ys<1..2^16-1>;
- * } ServerDHParams;
- */
- if( ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->conf->dhm_P ) ) != 0 ||
- ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->conf->dhm_G ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_copy", ret );
- return( ret );
- }
- if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx,
- (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
- return( ret );
- }
- dig_signed = p;
- dig_signed_len = len;
- p += len;
- n += len;
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- /*
- * Ephemeral ECDH parameters:
- *
- * struct {
- * ECParameters curve_params;
- * ECPoint public;
- * } ServerECDHParams;
- */
- const mbedtls_ecp_curve_info **curve = NULL;
- const mbedtls_ecp_group_id *gid;
- /* Match our preference list against the offered curves */
- for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
- for( curve = ssl->handshake->curves; *curve != NULL; curve++ )
- if( (*curve)->grp_id == *gid )
- goto curve_matching_done;
- curve_matching_done:
- if( curve == NULL || *curve == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
- return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
- if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp,
- (*curve)->grp_id ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret );
- return( ret );
- }
- if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
- p, MBEDTLS_SSL_MAX_CONTENT_LEN - n,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
- return( ret );
- }
- dig_signed = p;
- dig_signed_len = len;
- p += len;
- n += len;
- MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
- {
- size_t signature_len = 0;
- unsigned int hashlen = 0;
- unsigned char hash[64];
- mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
- /*
- * Choose hash algorithm. NONE means MD5 + SHA1 here.
- */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->sig_alg );
- if( md_alg == MBEDTLS_MD_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ciphersuite_info->key_exchange ==
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
- {
- md_alg = MBEDTLS_MD_SHA1;
- }
- else
- #endif
- {
- md_alg = MBEDTLS_MD_NONE;
- }
- /*
- * Compute the hash to be signed
- */
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( md_alg == MBEDTLS_MD_NONE )
- {
- mbedtls_md5_context mbedtls_md5;
- mbedtls_sha1_context mbedtls_sha1;
- mbedtls_md5_init( &mbedtls_md5 );
- mbedtls_sha1_init( &mbedtls_sha1 );
- /*
- * digitally-signed struct {
- * opaque md5_hash[16];
- * opaque sha_hash[20];
- * };
- *
- * md5_hash
- * MD5(ClientHello.random + ServerHello.random
- * + ServerParams);
- * sha_hash
- * SHA(ClientHello.random + ServerHello.random
- * + ServerParams);
- */
- mbedtls_md5_starts( &mbedtls_md5 );
- mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
- mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len );
- mbedtls_md5_finish( &mbedtls_md5, hash );
- mbedtls_sha1_starts( &mbedtls_sha1 );
- mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 );
- mbedtls_sha1_update( &mbedtls_sha1, dig_signed, dig_signed_len );
- mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 );
- hashlen = 36;
- mbedtls_md5_free( &mbedtls_md5 );
- mbedtls_sha1_free( &mbedtls_sha1 );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
- MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( md_alg != MBEDTLS_MD_NONE )
- {
- mbedtls_md_context_t ctx;
- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
- mbedtls_md_init( &ctx );
- /* Info from md_alg will be used instead */
- hashlen = 0;
- /*
- * digitally-signed struct {
- * opaque client_random[32];
- * opaque server_random[32];
- * ServerDHParams params;
- * };
- */
- if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
- return( ret );
- }
- mbedtls_md_starts( &ctx );
- mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 );
- mbedtls_md_update( &ctx, dig_signed, dig_signed_len );
- mbedtls_md_finish( &ctx, hash );
- mbedtls_md_free( &ctx );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
- (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
- /*
- * Make the signature
- */
- if( mbedtls_ssl_own_key( ssl ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
- }
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- *(p++) = ssl->handshake->sig_alg;
- *(p++) = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
- n += 2;
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen,
- p + 2 , &signature_len,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
- return( ret );
- }
- *(p++) = (unsigned char)( signature_len >> 8 );
- *(p++) = (unsigned char)( signature_len );
- n += 2;
- MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len );
- n += signature_len;
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- ssl->out_msglen = 4 + n;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
- ssl->state++;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
- return( 0 );
- }
- static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) );
- ssl->out_msglen = 4;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
- ssl->state++;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- mbedtls_ssl_send_flight_completed( ssl );
- #endif
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p,
- const unsigned char *end )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t n;
- /*
- * Receive G^Y mod P, premaster = (G^Y)^X mod P
- */
- if( *p + 2 > end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- n = ( (*p)[0] << 8 ) | (*p)[1];
- *p += 2;
- if( *p + n > end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
- }
- *p += n;
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
- return( ret );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
- const unsigned char *p,
- const unsigned char *end,
- size_t pms_offset )
- {
- int ret;
- size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) );
- unsigned char *pms = ssl->handshake->premaster + pms_offset;
- unsigned char ver[2];
- unsigned char fake_pms[48], peer_pms[48];
- unsigned char mask;
- size_t i, peer_pmslen;
- unsigned int diff;
- if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
- }
- /*
- * Decrypt the premaster using own private RSA key
- */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
- *p++ != ( ( len ) & 0xFF ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- }
- #endif
- if( p + len != end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
- ssl->handshake->max_minor_ver,
- ssl->conf->transport, ver );
- /*
- * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
- * must not cause the connection to end immediately; instead, send a
- * bad_record_mac later in the handshake.
- * Also, avoid data-dependant branches here to protect against
- * timing-based variants.
- */
- ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len,
- peer_pms, &peer_pmslen,
- sizeof( peer_pms ),
- ssl->conf->f_rng, ssl->conf->p_rng );
- diff = (unsigned int) ret;
- diff |= peer_pmslen ^ 48;
- diff |= peer_pms[0] ^ ver[0];
- diff |= peer_pms[1] ^ ver[1];
- #if defined(MBEDTLS_SSL_DEBUG_ALL)
- if( diff != 0 )
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- #endif
- if( sizeof( ssl->handshake->premaster ) < pms_offset ||
- sizeof( ssl->handshake->premaster ) - pms_offset < 48 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- ssl->handshake->pmslen = 48;
- /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
- /* MSVC has a warning about unary minus on unsigned, but this is
- * well-defined and precisely what we want to do here */
- #if defined(_MSC_VER)
- #pragma warning( push )
- #pragma warning( disable : 4146 )
- #endif
- mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
- #if defined(_MSC_VER)
- #pragma warning( pop )
- #endif
- for( i = 0; i < ssl->handshake->pmslen; i++ )
- pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] );
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p,
- const unsigned char *end )
- {
- int ret = 0;
- size_t n;
- if( ssl->conf->f_psk == NULL &&
- ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
- ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
- }
- /*
- * Receive client pre-shared key identity name
- */
- if( *p + 2 > end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- n = ( (*p)[0] << 8 ) | (*p)[1];
- *p += 2;
- if( n < 1 || n > 65535 || *p + n > end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- if( ssl->conf->f_psk != NULL )
- {
- if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 )
- ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
- }
- else
- {
- /* Identity is not a big secret since clients send it in the clear,
- * but treat it carefully anyway, just in case */
- if( n != ssl->conf->psk_identity_len ||
- mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
- {
- ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
- }
- }
- if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
- {
- MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 )
- {
- return( ret );
- }
- return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY );
- }
- *p += n;
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
- {
- int ret;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- unsigned char *p, *end;
- ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
- end = ssl->in_msg + ssl->in_hslen;
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
- {
- if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret );
- return( ret );
- }
- if( p != end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
- ssl->handshake->premaster,
- MBEDTLS_PREMASTER_SIZE,
- &ssl->handshake->pmslen,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
- }
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
- {
- if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx,
- p, end - p) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
- }
- MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
- if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
- &ssl->handshake->pmslen,
- ssl->handshake->premaster,
- MBEDTLS_MPI_MAX_SIZE,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
- }
- MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
- {
- if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
- return( ret );
- }
- if( p != end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
- ciphersuite_info->key_exchange ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- {
- if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
- return( ret );
- }
- if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
- return( ret );
- }
- if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
- ciphersuite_info->key_exchange ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
- {
- if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
- return( ret );
- }
- if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret );
- return( ret );
- }
- if( p != end )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
- }
- if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
- ciphersuite_info->key_exchange ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
- return( ret );
- }
- if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx,
- p, end - p ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
- }
- MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
- if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
- ciphersuite_info->key_exchange ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
- {
- if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
- p, end - p );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
- }
- ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
- ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
- ssl->conf->f_rng, ssl->conf->p_rng );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
- return( ret );
- }
- ssl->state++;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) );
- return( 0 );
- }
- #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
- {
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
- ssl->state++;
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #else
- static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t i, sig_len;
- unsigned char hash[48];
- unsigned char *hash_start = hash;
- size_t hashlen;
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- mbedtls_pk_type_t pk_alg;
- #endif
- mbedtls_md_type_t md_alg;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
- ssl->session_negotiate->peer_cert == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
- ssl->state++;
- return( 0 );
- }
- /* Needs to be done before read_record() to exclude current message */
- ssl->handshake->calc_verify( ssl, hash );
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- ssl->state++;
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
- ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- i = mbedtls_ssl_hs_hdr_len( ssl );
- /*
- * struct {
- * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
- * opaque signature<0..2^16-1>;
- * } DigitallySigned;
- */
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- md_alg = MBEDTLS_MD_NONE;
- hashlen = 36;
- /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
- if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_ECDSA ) )
- {
- hash_start += 16;
- hashlen -= 16;
- md_alg = MBEDTLS_MD_SHA1;
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 ||
- MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- if( i + 2 > ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- /*
- * Hash
- */
- if( ssl->in_msg[i] != ssl->handshake->verify_sig_alg )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
- " for verify message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->verify_sig_alg );
- /* Info from md_alg will be used instead */
- hashlen = 0;
- i++;
- /*
- * Signature
- */
- if( ( pk_alg = mbedtls_ssl_pk_alg_from_sig( ssl->in_msg[i] ) )
- == MBEDTLS_PK_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
- " for verify message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- /*
- * Check the certificate's key type matches the signature alg
- */
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- i++;
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- if( i + 2 > ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1];
- i += 2;
- if( i + sig_len != ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
- }
- if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
- md_alg, hash_start, hashlen,
- ssl->in_msg + i, sig_len ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
- return( ret );
- }
- #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
- {
- int ret;
- size_t tlen;
- uint32_t lifetime;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) );
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET;
- /*
- * struct {
- * uint32 ticket_lifetime_hint;
- * opaque ticket<0..2^16-1>;
- * } NewSessionTicket;
- *
- * 4 . 7 ticket_lifetime_hint (0 = unspecified)
- * 8 . 9 ticket_len (n)
- * 10 . 9+n ticket content
- */
- if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket,
- ssl->session_negotiate,
- ssl->out_msg + 10,
- ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN,
- &tlen, &lifetime ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret );
- tlen = 0;
- }
- ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF;
- ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF;
- ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF;
- ssl->out_msg[7] = ( lifetime ) & 0xFF;
- ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF );
- ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF );
- ssl->out_msglen = 10 + tlen;
- /*
- * Morally equivalent to updating ssl->state, but NewSessionTicket and
- * ChangeCipherSpec share the same state.
- */
- ssl->handshake->new_session_ticket = 0;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- /*
- * SSL handshake -- server side -- single step
- */
- int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl )
- {
- int ret = 0;
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- return( ret );
- }
- #endif
- switch( ssl->state )
- {
- case MBEDTLS_SSL_HELLO_REQUEST:
- ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
- break;
- /*
- * <== ClientHello
- */
- case MBEDTLS_SSL_CLIENT_HELLO:
- ret = ssl_parse_client_hello( ssl );
- break;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
- #endif
- /*
- * ==> ServerHello
- * Certificate
- * ( ServerKeyExchange )
- * ( CertificateRequest )
- * ServerHelloDone
- */
- case MBEDTLS_SSL_SERVER_HELLO:
- ret = ssl_write_server_hello( ssl );
- break;
- case MBEDTLS_SSL_SERVER_CERTIFICATE:
- ret = mbedtls_ssl_write_certificate( ssl );
- break;
- case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
- ret = ssl_write_server_key_exchange( ssl );
- break;
- case MBEDTLS_SSL_CERTIFICATE_REQUEST:
- ret = ssl_write_certificate_request( ssl );
- break;
- case MBEDTLS_SSL_SERVER_HELLO_DONE:
- ret = ssl_write_server_hello_done( ssl );
- break;
- /*
- * <== ( Certificate/Alert )
- * ClientKeyExchange
- * ( CertificateVerify )
- * ChangeCipherSpec
- * Finished
- */
- case MBEDTLS_SSL_CLIENT_CERTIFICATE:
- ret = mbedtls_ssl_parse_certificate( ssl );
- break;
- case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
- ret = ssl_parse_client_key_exchange( ssl );
- break;
- case MBEDTLS_SSL_CERTIFICATE_VERIFY:
- ret = ssl_parse_certificate_verify( ssl );
- break;
- case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
- ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
- break;
- case MBEDTLS_SSL_CLIENT_FINISHED:
- ret = mbedtls_ssl_parse_finished( ssl );
- break;
- /*
- * ==> ( NewSessionTicket )
- * ChangeCipherSpec
- * Finished
- */
- case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if( ssl->handshake->new_session_ticket != 0 )
- ret = ssl_write_new_session_ticket( ssl );
- else
- #endif
- ret = mbedtls_ssl_write_change_cipher_spec( ssl );
- break;
- case MBEDTLS_SSL_SERVER_FINISHED:
- ret = mbedtls_ssl_write_finished( ssl );
- break;
- case MBEDTLS_SSL_FLUSH_BUFFERS:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
- ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
- break;
- case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
- mbedtls_ssl_handshake_wrapup( ssl );
- break;
- default:
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- return( ret );
- }
- #endif /* MBEDTLS_SSL_SRV_C */
- /********* Start of file library/ssl_ticket.c ************/
- /*
- * TLS server tickets callbacks implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_TICKET_C)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- #include <string.h>
- /* Implementation that should never be optimized out by the compiler */
- static void ssl_ticket_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Initialze context
- */
- void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_ssl_ticket_context ) );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_init( &ctx->mutex );
- #endif
- }
- #define MAX_KEY_BYTES 32 /* 256 bits */
- /*
- * Generate/update a key
- */
- static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
- unsigned char index )
- {
- int ret;
- unsigned char buf[MAX_KEY_BYTES];
- mbedtls_ssl_ticket_key *key = ctx->keys + index;
- #if defined(MBEDTLS_HAVE_TIME)
- key->generation_time = (uint32_t) time( NULL );
- #endif
- if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 )
- return( ret );
- if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 )
- return( ret );
- /* With GCM and CCM, same context can encrypt & decrypt */
- ret = mbedtls_cipher_setkey( &key->ctx, buf,
- mbedtls_cipher_get_key_bitlen( &key->ctx ),
- MBEDTLS_ENCRYPT );
- ssl_ticket_zeroize( buf, sizeof( buf ) );
- return( ret );
- }
- /*
- * Rotate/generate keys if necessary
- */
- static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx )
- {
- #if !defined(MBEDTLS_HAVE_TIME)
- ((void) ctx);
- #else
- if( ctx->ticket_lifetime != 0 )
- {
- uint32_t current_time = (uint32_t) time( NULL );
- uint32_t key_time = ctx->keys[ctx->active].generation_time;
- if( current_time > key_time &&
- current_time - key_time < ctx->ticket_lifetime )
- {
- return( 0 );
- }
- ctx->active = 1 - ctx->active;
- return( ssl_ticket_gen_key( ctx, ctx->active ) );
- }
- else
- #endif /* MBEDTLS_HAVE_TIME */
- return( 0 );
- }
- /*
- * Setup context for actual use
- */
- int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
- mbedtls_cipher_type_t cipher,
- uint32_t lifetime )
- {
- int ret;
- const mbedtls_cipher_info_t *cipher_info;
- ctx->f_rng = f_rng;
- ctx->p_rng = p_rng;
- ctx->ticket_lifetime = lifetime;
- cipher_info = mbedtls_cipher_info_from_type( cipher);
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( cipher_info->mode != MBEDTLS_MODE_GCM &&
- cipher_info->mode != MBEDTLS_MODE_CCM )
- {
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 ||
- ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
- {
- return( ret );
- }
- if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 ||
- ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- /*
- * Serialize a session in the following format:
- * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
- * n . n+2 peer_cert length = m (0 if no certificate)
- * n+3 . n+2+m peer cert ASN.1
- */
- static int ssl_save_session( const mbedtls_ssl_session *session,
- unsigned char *buf, size_t buf_len,
- size_t *olen )
- {
- unsigned char *p = buf;
- size_t left = buf_len;
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- size_t cert_len;
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- if( left < sizeof( mbedtls_ssl_session ) )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- memcpy( p, session, sizeof( mbedtls_ssl_session ) );
- p += sizeof( mbedtls_ssl_session );
- left -= sizeof( mbedtls_ssl_session );
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( session->peer_cert == NULL )
- cert_len = 0;
- else
- cert_len = session->peer_cert->raw.len;
- if( left < 3 + cert_len )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- *p++ = (unsigned char)( cert_len >> 16 & 0xFF );
- *p++ = (unsigned char)( cert_len >> 8 & 0xFF );
- *p++ = (unsigned char)( cert_len & 0xFF );
- if( session->peer_cert != NULL )
- memcpy( p, session->peer_cert->raw.p, cert_len );
- p += cert_len;
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- *olen = p - buf;
- return( 0 );
- }
- /*
- * Unserialise session, see ssl_save_session()
- */
- static int ssl_load_session( mbedtls_ssl_session *session,
- const unsigned char *buf, size_t len )
- {
- const unsigned char *p = buf;
- const unsigned char * const end = buf + len;
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- size_t cert_len;
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- if( p + sizeof( mbedtls_ssl_session ) > end )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- memcpy( session, p, sizeof( mbedtls_ssl_session ) );
- p += sizeof( mbedtls_ssl_session );
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( p + 3 > end )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
- p += 3;
- if( cert_len == 0 )
- {
- session->peer_cert = NULL;
- }
- else
- {
- int ret;
- if( p + cert_len > end )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
- if( session->peer_cert == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- mbedtls_x509_crt_init( session->peer_cert );
- if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
- p, cert_len ) ) != 0 )
- {
- mbedtls_x509_crt_free( session->peer_cert );
- mbedtls_free( session->peer_cert );
- session->peer_cert = NULL;
- return( ret );
- }
- p += cert_len;
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- if( p != end )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- return( 0 );
- }
- /*
- * Create session ticket, with the following structure:
- *
- * struct {
- * opaque key_name[4];
- * opaque iv[12];
- * opaque encrypted_state<0..2^16-1>;
- * opaque tag[16];
- * } ticket;
- *
- * The key_name, iv, and length of encrypted_state are the additional
- * authenticated data.
- */
- int mbedtls_ssl_ticket_write( void *p_ticket,
- const mbedtls_ssl_session *session,
- unsigned char *start,
- const unsigned char *end,
- size_t *tlen,
- uint32_t *ticket_lifetime )
- {
- int ret;
- mbedtls_ssl_ticket_context *ctx = p_ticket;
- mbedtls_ssl_ticket_key *key;
- unsigned char *key_name = start;
- unsigned char *iv = start + 4;
- unsigned char *state_len_bytes = iv + 12;
- unsigned char *state = state_len_bytes + 2;
- unsigned char *tag;
- size_t clear_len, ciph_len;
- *tlen = 0;
- if( ctx == NULL || ctx->f_rng == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
- * in addition to session itself, that will be checked when writing it. */
- if( end - start < 4 + 12 + 2 + 16 )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 )
- goto cleanup;
- key = &ctx->keys[ctx->active];
- *ticket_lifetime = ctx->ticket_lifetime;
- memcpy( key_name, key->name, 4 );
- if( ( ret = ctx->f_rng( ctx->p_rng, iv, 12 ) ) != 0 )
- goto cleanup;
- /* Dump session state */
- if( ( ret = ssl_save_session( session,
- state, end - state, &clear_len ) ) != 0 ||
- (unsigned long) clear_len > 65535 )
- {
- goto cleanup;
- }
- state_len_bytes[0] = ( clear_len >> 8 ) & 0xff;
- state_len_bytes[1] = ( clear_len ) & 0xff;
- /* Encrypt and authenticate */
- tag = state + clear_len;
- if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx,
- iv, 12, key_name, 4 + 12 + 2,
- state, clear_len, state, &ciph_len, tag, 16 ) ) != 0 )
- {
- goto cleanup;
- }
- if( ciph_len != clear_len )
- {
- ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
- goto cleanup;
- }
- *tlen = 4 + 12 + 2 + 16 + ciph_len;
- cleanup:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- /*
- * Select key based on name
- */
- static mbedtls_ssl_ticket_key *ssl_ticket_select_key(
- mbedtls_ssl_ticket_context *ctx,
- const unsigned char name[4] )
- {
- unsigned char i;
- for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ )
- if( memcmp( name, ctx->keys[i].name, 4 ) == 0 )
- return( &ctx->keys[i] );
- return( NULL );
- }
- /*
- * Load session ticket (see mbedtls_ssl_ticket_write for structure)
- */
- int mbedtls_ssl_ticket_parse( void *p_ticket,
- mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t len )
- {
- int ret;
- mbedtls_ssl_ticket_context *ctx = p_ticket;
- mbedtls_ssl_ticket_key *key;
- unsigned char *key_name = buf;
- unsigned char *iv = buf + 4;
- unsigned char *enc_len_p = iv + 12;
- unsigned char *ticket = enc_len_p + 2;
- unsigned char *tag;
- size_t enc_len, clear_len;
- if( ctx == NULL || ctx->f_rng == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /* See mbedtls_ssl_ticket_write() */
- if( len < 4 + 12 + 2 + 16 )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- #if defined(MBEDTLS_THREADING_C)
- if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( ret );
- #endif
- if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 )
- goto cleanup;
- enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
- tag = ticket + enc_len;
- if( len != 4 + 12 + 2 + enc_len + 16 )
- {
- ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- goto cleanup;
- }
- /* Select key */
- if( ( key = ssl_ticket_select_key( ctx, key_name ) ) == NULL )
- {
- /* We can't know for sure but this is a likely option unless we're
- * under attack - this is only informative anyway */
- ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
- goto cleanup;
- }
- /* Decrypt and authenticate */
- if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, iv, 12,
- key_name, 4 + 12 + 2, ticket, enc_len,
- ticket, &clear_len, tag, 16 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
- ret = MBEDTLS_ERR_SSL_INVALID_MAC;
- goto cleanup;
- }
- if( clear_len != enc_len )
- {
- ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
- goto cleanup;
- }
- /* Actually load session */
- if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 )
- goto cleanup;
- #if defined(MBEDTLS_HAVE_TIME)
- {
- /* Check for expiration */
- time_t current_time = time( NULL );
- if( current_time < session->start ||
- (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime )
- {
- ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
- goto cleanup;
- }
- }
- #endif
- cleanup:
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- /*
- * Free context
- */
- void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx )
- {
- mbedtls_cipher_free( &ctx->keys[0].ctx );
- mbedtls_cipher_free( &ctx->keys[1].ctx );
- #if defined(MBEDTLS_THREADING_C)
- mbedtls_mutex_free( &ctx->mutex );
- #endif
- ssl_ticket_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) );
- }
- #endif /* MBEDTLS_SSL_TICKET_C */
- /********* Start of file library/ssl_tls.c ************/
- /*
- * SSLv3/TLSv1 shared functions
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The SSL 3.0 specification was drafted by Netscape in 1996,
- * and became an IETF standard in 1999.
- *
- * http://wp.netscape.com/eng/ssl3/
- * http://www.ietf.org/rfc/rfc2246.txt
- * http://www.ietf.org/rfc/rfc4346.txt
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SSL_TLS_C)
- #include <string.h>
- #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
- defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_calloc calloc
- #define mbedtls_free free
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void ssl_tls_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /* Length of the "epoch" field in the record header */
- static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 2 );
- #else
- ((void) ssl);
- #endif
- return( 0 );
- }
- /*
- * Start a timer.
- * Passing millisecs = 0 cancels a running timer.
- */
- static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
- {
- if( ssl->f_set_timer == NULL )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
- ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
- }
- /*
- * Return -1 is timer is expired, 0 if it isn't.
- */
- static int ssl_check_timer( mbedtls_ssl_context *ssl )
- {
- if( ssl->f_get_timer == NULL )
- return( 0 );
- if( ssl->f_get_timer( ssl->p_timer ) == 2 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
- return( -1 );
- }
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- /*
- * Double the retransmit timeout value, within the allowed range,
- * returning -1 if the maximum value has already been reached.
- */
- static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
- {
- uint32_t new_timeout;
- if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
- return( -1 );
- new_timeout = 2 * ssl->handshake->retransmit_timeout;
- /* Avoid arithmetic overflow and range overflow */
- if( new_timeout < ssl->handshake->retransmit_timeout ||
- new_timeout > ssl->conf->hs_timeout_max )
- {
- new_timeout = ssl->conf->hs_timeout_max;
- }
- ssl->handshake->retransmit_timeout = new_timeout;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
- ssl->handshake->retransmit_timeout ) );
- return( 0 );
- }
- static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
- {
- ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
- ssl->handshake->retransmit_timeout ) );
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- /*
- * Convert max_fragment_length codes to length.
- * RFC 6066 says:
- * enum{
- * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
- * } MaxFragmentLength;
- * and we add 0 -> extension unused
- */
- static unsigned int mfl_code_to_length[MBEDTLS_SSL_MAX_FRAG_LEN_INVALID] =
- {
- MBEDTLS_SSL_MAX_CONTENT_LEN, /* MBEDTLS_SSL_MAX_FRAG_LEN_NONE */
- 512, /* MBEDTLS_SSL_MAX_FRAG_LEN_512 */
- 1024, /* MBEDTLS_SSL_MAX_FRAG_LEN_1024 */
- 2048, /* MBEDTLS_SSL_MAX_FRAG_LEN_2048 */
- 4096, /* MBEDTLS_SSL_MAX_FRAG_LEN_4096 */
- };
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_CLI_C)
- static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src )
- {
- mbedtls_ssl_session_free( dst );
- memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( src->peer_cert != NULL )
- {
- int ret;
- dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) );
- if( dst->peer_cert == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- mbedtls_x509_crt_init( dst->peer_cert );
- if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p,
- src->peer_cert->raw.len ) ) != 0 )
- {
- mbedtls_free( dst->peer_cert );
- dst->peer_cert = NULL;
- return( ret );
- }
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
- if( src->ticket != NULL )
- {
- dst->ticket = mbedtls_calloc( 1, src->ticket_len );
- if( dst->ticket == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( dst->ticket, src->ticket, src->ticket_len );
- }
- #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_CLI_C */
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
- const unsigned char *key_enc, const unsigned char *key_dec,
- size_t keylen,
- const unsigned char *iv_enc, const unsigned char *iv_dec,
- size_t ivlen,
- const unsigned char *mac_enc, const unsigned char *mac_dec,
- size_t maclen ) = NULL;
- int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
- int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
- int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
- int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
- int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
- #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- /*
- * Key material generation
- */
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- static int ssl3_prf( const unsigned char *secret, size_t slen,
- const char *label,
- const unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t i;
- mbedtls_md5_context md5;
- mbedtls_sha1_context sha1;
- unsigned char padding[16];
- unsigned char sha1sum[20];
- ((void)label);
- mbedtls_md5_init( &md5 );
- mbedtls_sha1_init( &sha1 );
- /*
- * SSLv3:
- * block =
- * MD5( secret + SHA1( 'A' + secret + random ) ) +
- * MD5( secret + SHA1( 'BB' + secret + random ) ) +
- * MD5( secret + SHA1( 'CCC' + secret + random ) ) +
- * ...
- */
- for( i = 0; i < dlen / 16; i++ )
- {
- memset( padding, (unsigned char) ('A' + i), 1 + i );
- mbedtls_sha1_starts( &sha1 );
- mbedtls_sha1_update( &sha1, padding, 1 + i );
- mbedtls_sha1_update( &sha1, secret, slen );
- mbedtls_sha1_update( &sha1, random, rlen );
- mbedtls_sha1_finish( &sha1, sha1sum );
- mbedtls_md5_starts( &md5 );
- mbedtls_md5_update( &md5, secret, slen );
- mbedtls_md5_update( &md5, sha1sum, 20 );
- mbedtls_md5_finish( &md5, dstbuf + i * 16 );
- }
- mbedtls_md5_free( &md5 );
- mbedtls_sha1_free( &sha1 );
- ssl_tls_zeroize( padding, sizeof( padding ) );
- ssl_tls_zeroize( sha1sum, sizeof( sha1sum ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- static int tls1_prf( const unsigned char *secret, size_t slen,
- const char *label,
- const unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t nb, hs;
- size_t i, j, k;
- const unsigned char *S1, *S2;
- unsigned char tmp[128];
- unsigned char h_i[20];
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- int ret;
- mbedtls_md_init( &md_ctx );
- if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- hs = ( slen + 1 ) / 2;
- S1 = secret;
- S2 = secret + slen - hs;
- nb = strlen( label );
- memcpy( tmp + 20, label, nb );
- memcpy( tmp + 20 + nb, random, rlen );
- nb += rlen;
- /*
- * First compute P_md5(secret,label+random)[0..dlen]
- */
- if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
- return( ret );
- mbedtls_md_hmac_starts( &md_ctx, S1, hs );
- mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
- mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
- for( i = 0; i < dlen; i += 16 )
- {
- mbedtls_md_hmac_reset ( &md_ctx );
- mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
- mbedtls_md_hmac_finish( &md_ctx, h_i );
- mbedtls_md_hmac_reset ( &md_ctx );
- mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
- mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
- k = ( i + 16 > dlen ) ? dlen % 16 : 16;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = h_i[j];
- }
- mbedtls_md_free( &md_ctx );
- /*
- * XOR out with P_sha1(secret,label+random)[0..dlen]
- */
- if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
- return( ret );
- mbedtls_md_hmac_starts( &md_ctx, S2, hs );
- mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
- mbedtls_md_hmac_finish( &md_ctx, tmp );
- for( i = 0; i < dlen; i += 20 )
- {
- mbedtls_md_hmac_reset ( &md_ctx );
- mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
- mbedtls_md_hmac_finish( &md_ctx, h_i );
- mbedtls_md_hmac_reset ( &md_ctx );
- mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
- mbedtls_md_hmac_finish( &md_ctx, tmp );
- k = ( i + 20 > dlen ) ? dlen % 20 : 20;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
- }
- mbedtls_md_free( &md_ctx );
- ssl_tls_zeroize( tmp, sizeof( tmp ) );
- ssl_tls_zeroize( h_i, sizeof( h_i ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- static int tls_prf_generic( mbedtls_md_type_t md_type,
- const unsigned char *secret, size_t slen,
- const char *label,
- const unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- size_t nb;
- size_t i, j, k, md_len;
- unsigned char tmp[128];
- unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
- const mbedtls_md_info_t *md_info;
- mbedtls_md_context_t md_ctx;
- int ret;
- mbedtls_md_init( &md_ctx );
- if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- md_len = mbedtls_md_get_size( md_info );
- if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- nb = strlen( label );
- memcpy( tmp + md_len, label, nb );
- memcpy( tmp + md_len + nb, random, rlen );
- nb += rlen;
- /*
- * Compute P_<hash>(secret, label + random)[0..dlen]
- */
- if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
- return( ret );
- mbedtls_md_hmac_starts( &md_ctx, secret, slen );
- mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
- mbedtls_md_hmac_finish( &md_ctx, tmp );
- for( i = 0; i < dlen; i += md_len )
- {
- mbedtls_md_hmac_reset ( &md_ctx );
- mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
- mbedtls_md_hmac_finish( &md_ctx, h_i );
- mbedtls_md_hmac_reset ( &md_ctx );
- mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
- mbedtls_md_hmac_finish( &md_ctx, tmp );
- k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
- for( j = 0; j < k; j++ )
- dstbuf[i + j] = h_i[j];
- }
- mbedtls_md_free( &md_ctx );
- ssl_tls_zeroize( tmp, sizeof( tmp ) );
- ssl_tls_zeroize( h_i, sizeof( h_i ) );
- return( 0 );
- }
- #if defined(MBEDTLS_SHA256_C)
- static int tls_prf_sha256( const unsigned char *secret, size_t slen,
- const char *label,
- const unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen,
- label, random, rlen, dstbuf, dlen ) );
- }
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- static int tls_prf_sha384( const unsigned char *secret, size_t slen,
- const char *label,
- const unsigned char *random, size_t rlen,
- unsigned char *dstbuf, size_t dlen )
- {
- return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
- label, random, rlen, dstbuf, dlen ) );
- }
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * );
- static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * );
- static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
- static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * );
- static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
- static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * );
- static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
- {
- int ret = 0;
- unsigned char tmp[64];
- unsigned char keyblk[256];
- unsigned char *key1;
- unsigned char *key2;
- unsigned char *mac_enc;
- unsigned char *mac_dec;
- size_t iv_copy_len;
- const mbedtls_cipher_info_t *cipher_info;
- const mbedtls_md_info_t *md_info;
- mbedtls_ssl_session *session = ssl->session_negotiate;
- mbedtls_ssl_transform *transform = ssl->transform_negotiate;
- mbedtls_ssl_handshake_params *handshake = ssl->handshake;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
- cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher );
- if( cipher_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
- transform->ciphersuite_info->cipher ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac );
- if( md_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
- transform->ciphersuite_info->mac ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- /*
- * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
- */
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- handshake->tls_prf = ssl3_prf;
- handshake->calc_verify = ssl_calc_verify_ssl;
- handshake->calc_finished = ssl_calc_finished_ssl;
- }
- else
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- handshake->tls_prf = tls1_prf;
- handshake->calc_verify = ssl_calc_verify_tls;
- handshake->calc_finished = ssl_calc_finished_tls;
- }
- else
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA512_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
- transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
- {
- handshake->tls_prf = tls_prf_sha384;
- handshake->calc_verify = ssl_calc_verify_tls_sha384;
- handshake->calc_finished = ssl_calc_finished_tls_sha384;
- }
- else
- #endif
- #if defined(MBEDTLS_SHA256_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- handshake->tls_prf = tls_prf_sha256;
- handshake->calc_verify = ssl_calc_verify_tls_sha256;
- handshake->calc_finished = ssl_calc_finished_tls_sha256;
- }
- else
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- /*
- * SSLv3:
- * master =
- * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
- *
- * TLSv1+:
- * master = PRF( premaster, "master secret", randbytes )[0..47]
- */
- if( handshake->resume == 0 )
- {
- MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
- handshake->pmslen );
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
- {
- unsigned char session_hash[48];
- size_t hash_len;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
- ssl->handshake->calc_verify( ssl, session_hash );
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- #if defined(MBEDTLS_SHA512_C)
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
- {
- hash_len = 48;
- }
- else
- #endif
- hash_len = 32;
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- hash_len = 36;
- MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len );
- ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "extended master secret",
- session_hash, hash_len,
- session->master, 48 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
- }
- else
- #endif
- ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "master secret",
- handshake->randbytes, 64,
- session->master, 48 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
- ssl_tls_zeroize( handshake->premaster, sizeof(handshake->premaster) );
- }
- else
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
- /*
- * Swap the client and server random values.
- */
- memcpy( tmp, handshake->randbytes, 64 );
- memcpy( handshake->randbytes, tmp + 32, 32 );
- memcpy( handshake->randbytes + 32, tmp, 32 );
- ssl_tls_zeroize( tmp, sizeof( tmp ) );
- /*
- * SSLv3:
- * key block =
- * MD5( master + SHA1( 'A' + master + randbytes ) ) +
- * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
- * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
- * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
- * ...
- *
- * TLSv1:
- * key block = PRF( master, "key expansion", randbytes )
- */
- ret = handshake->tls_prf( session->master, 48, "key expansion",
- handshake->randbytes, 64, keyblk, 256 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
- mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
- MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
- MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
- ssl_tls_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) );
- /*
- * Determine the appropriate key, IV and MAC length.
- */
- transform->keylen = cipher_info->key_bitlen / 8;
- if( cipher_info->mode == MBEDTLS_MODE_GCM ||
- cipher_info->mode == MBEDTLS_MODE_CCM )
- {
- transform->maclen = 0;
- transform->ivlen = 12;
- transform->fixed_ivlen = 4;
- /* Minimum length is expicit IV + tag */
- transform->minlen = transform->ivlen - transform->fixed_ivlen
- + ( transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16 );
- }
- else
- {
- /* Initialize HMAC contexts */
- if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
- ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
- return( ret );
- }
- /* Get MAC length */
- transform->maclen = mbedtls_md_get_size( md_info );
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- /*
- * If HMAC is to be truncated, we shall keep the leftmost bytes,
- * (rfc 6066 page 13 or rfc 2104 section 4),
- * so we only need to adjust the length here.
- */
- if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
- transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- /* IV length */
- transform->ivlen = cipher_info->iv_size;
- /* Minimum length */
- if( cipher_info->mode == MBEDTLS_MODE_STREAM )
- transform->minlen = transform->maclen;
- else
- {
- /*
- * GenericBlockCipher:
- * 1. if EtM is in use: one block plus MAC
- * otherwise: * first multiple of blocklen greater than maclen
- * 2. IV except for SSL3 and TLS 1.0
- */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
- {
- transform->minlen = transform->maclen
- + cipher_info->block_size;
- }
- else
- #endif
- {
- transform->minlen = transform->maclen
- + cipher_info->block_size
- - transform->maclen % cipher_info->block_size;
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
- ; /* No need to adjust minlen */
- else
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
- transform->minlen += transform->ivlen;
- }
- else
- #endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
- transform->keylen, transform->minlen, transform->ivlen,
- transform->maclen ) );
- /*
- * Finally setup the cipher contexts, IVs and MAC secrets.
- */
- #if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- {
- key1 = keyblk + transform->maclen * 2;
- key2 = keyblk + transform->maclen * 2 + transform->keylen;
- mac_enc = keyblk;
- mac_dec = keyblk + transform->maclen;
- /*
- * This is not used in TLS v1.1.
- */
- iv_copy_len = ( transform->fixed_ivlen ) ?
- transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
- iv_copy_len );
- }
- else
- #endif /* MBEDTLS_SSL_CLI_C */
- #if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- {
- key1 = keyblk + transform->maclen * 2 + transform->keylen;
- key2 = keyblk + transform->maclen * 2;
- mac_enc = keyblk + transform->maclen;
- mac_dec = keyblk;
- /*
- * This is not used in TLS v1.1.
- */
- iv_copy_len = ( transform->fixed_ivlen ) ?
- transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
- iv_copy_len );
- }
- else
- #endif /* MBEDTLS_SSL_SRV_C */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( transform->maclen > sizeof transform->mac_enc )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- memcpy( transform->mac_enc, mac_enc, transform->maclen );
- memcpy( transform->mac_dec, mac_dec, transform->maclen );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen );
- mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen );
- }
- else
- #endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_init != NULL )
- {
- int ret = 0;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
- if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
- transform->iv_enc, transform->iv_dec,
- iv_copy_len,
- mac_enc, mac_dec,
- transform->maclen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
- #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- #if defined(MBEDTLS_SSL_EXPORT_KEYS)
- if( ssl->conf->f_export_keys != NULL )
- {
- ssl->conf->f_export_keys( ssl->conf->p_export_keys,
- session->master, keyblk,
- transform->maclen, transform->keylen,
- iv_copy_len );
- }
- #endif
- if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
- cipher_info ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
- return( ret );
- }
- if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
- cipher_info ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
- return( ret );
- }
- if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
- cipher_info->key_bitlen,
- MBEDTLS_ENCRYPT ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
- return( ret );
- }
- if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
- cipher_info->key_bitlen,
- MBEDTLS_DECRYPT ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
- return( ret );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- if( cipher_info->mode == MBEDTLS_MODE_CBC )
- {
- if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
- MBEDTLS_PADDING_NONE ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
- return( ret );
- }
- if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
- MBEDTLS_PADDING_NONE ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
- return( ret );
- }
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- ssl_tls_zeroize( keyblk, sizeof( keyblk ) );
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- // Initialize compression
- //
- if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ssl->compress_buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
- ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_BUFFER_LEN );
- if( ssl->compress_buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- MBEDTLS_SSL_BUFFER_LEN ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
- memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
- memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) );
- if( deflateInit( &transform->ctx_deflate,
- Z_DEFAULT_COMPRESSION ) != Z_OK ||
- inflateInit( &transform->ctx_inflate ) != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
- }
- #endif /* MBEDTLS_ZLIB_SUPPORT */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
- {
- mbedtls_md5_context md5;
- mbedtls_sha1_context sha1;
- unsigned char pad_1[48];
- unsigned char pad_2[48];
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) );
- mbedtls_md5_init( &md5 );
- mbedtls_sha1_init( &sha1 );
- mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
- mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- memset( pad_1, 0x36, 48 );
- memset( pad_2, 0x5C, 48 );
- mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 );
- mbedtls_md5_update( &md5, pad_1, 48 );
- mbedtls_md5_finish( &md5, hash );
- mbedtls_md5_starts( &md5 );
- mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 );
- mbedtls_md5_update( &md5, pad_2, 48 );
- mbedtls_md5_update( &md5, hash, 16 );
- mbedtls_md5_finish( &md5, hash );
- mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 );
- mbedtls_sha1_update( &sha1, pad_1, 40 );
- mbedtls_sha1_finish( &sha1, hash + 16 );
- mbedtls_sha1_starts( &sha1 );
- mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 );
- mbedtls_sha1_update( &sha1, pad_2, 40 );
- mbedtls_sha1_update( &sha1, hash + 16, 20 );
- mbedtls_sha1_finish( &sha1, hash + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- mbedtls_md5_free( &md5 );
- mbedtls_sha1_free( &sha1 );
- return;
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
- {
- mbedtls_md5_context md5;
- mbedtls_sha1_context sha1;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) );
- mbedtls_md5_init( &md5 );
- mbedtls_sha1_init( &sha1 );
- mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
- mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- mbedtls_md5_finish( &md5, hash );
- mbedtls_sha1_finish( &sha1, hash + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- mbedtls_md5_free( &md5 );
- mbedtls_sha1_free( &sha1 );
- return;
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
- {
- mbedtls_sha256_context sha256;
- mbedtls_sha256_init( &sha256 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
- mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
- mbedtls_sha256_finish( &sha256, hash );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- mbedtls_sha256_free( &sha256 );
- return;
- }
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
- {
- mbedtls_sha512_context sha512;
- mbedtls_sha512_init( &sha512 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
- mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
- mbedtls_sha512_finish( &sha512, hash );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
- mbedtls_sha512_free( &sha512 );
- return;
- }
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
- {
- unsigned char *p = ssl->handshake->premaster;
- unsigned char *end = p + sizeof( ssl->handshake->premaster );
- const unsigned char *psk = ssl->conf->psk;
- size_t psk_len = ssl->conf->psk_len;
- /* If the psk callback was called, use its result */
- if( ssl->handshake->psk != NULL )
- {
- psk = ssl->handshake->psk;
- psk_len = ssl->handshake->psk_len;
- }
- /*
- * PMS = struct {
- * opaque other_secret<0..2^16-1>;
- * opaque psk<0..2^16-1>;
- * };
- * with "other_secret" depending on the particular key exchange
- */
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
- if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
- {
- if( end - p < 2 )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- *(p++) = (unsigned char)( psk_len >> 8 );
- *(p++) = (unsigned char)( psk_len );
- if( end < p || (size_t)( end - p ) < psk_len )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- memset( p, 0, psk_len );
- p += psk_len;
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- {
- /*
- * other_secret already set by the ClientKeyExchange message,
- * and is 48 bytes long
- */
- *p++ = 0;
- *p++ = 48;
- p += 48;
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
- {
- int ret;
- size_t len;
- /* Write length only when we know the actual value */
- if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
- p + 2, end - ( p + 2 ), &len,
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
- return( ret );
- }
- *(p++) = (unsigned char)( len >> 8 );
- *(p++) = (unsigned char)( len );
- p += len;
- MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
- {
- int ret;
- size_t zlen;
- if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
- p + 2, end - ( p + 2 ),
- ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
- return( ret );
- }
- *(p++) = (unsigned char)( zlen >> 8 );
- *(p++) = (unsigned char)( zlen );
- p += zlen;
- MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
- }
- else
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- /* opaque psk<0..2^16-1>; */
- if( end - p < 2 )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- *(p++) = (unsigned char)( psk_len >> 8 );
- *(p++) = (unsigned char)( psk_len );
- if( end < p || (size_t)( end - p ) < psk_len )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- memcpy( p, psk, psk_len );
- p += psk_len;
- ssl->handshake->pmslen = p - ssl->handshake->premaster;
- return( 0 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- /*
- * SSLv3.0 MAC functions
- */
- static void ssl_mac( mbedtls_md_context_t *md_ctx, unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
- {
- unsigned char header[11];
- unsigned char padding[48];
- int padlen;
- int md_size = mbedtls_md_get_size( md_ctx->md_info );
- int md_type = mbedtls_md_get_type( md_ctx->md_info );
- /* Only MD5 and SHA-1 supported */
- if( md_type == MBEDTLS_MD_MD5 )
- padlen = 48;
- else
- padlen = 40;
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
- memset( padding, 0x36, padlen );
- mbedtls_md_starts( md_ctx );
- mbedtls_md_update( md_ctx, secret, md_size );
- mbedtls_md_update( md_ctx, padding, padlen );
- mbedtls_md_update( md_ctx, header, 11 );
- mbedtls_md_update( md_ctx, buf, len );
- mbedtls_md_finish( md_ctx, buf + len );
- memset( padding, 0x5C, padlen );
- mbedtls_md_starts( md_ctx );
- mbedtls_md_update( md_ctx, secret, md_size );
- mbedtls_md_update( md_ctx, padding, padlen );
- mbedtls_md_update( md_ctx, buf + len, md_size );
- mbedtls_md_finish( md_ctx, buf + len );
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
- ( defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) )
- #define SSL_SOME_MODES_USE_MAC
- #endif
- /*
- * Encryption/decryption functions
- */
- static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
- {
- mbedtls_cipher_mode_t mode;
- int auth_done = 0;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
- if( ssl->session_out == NULL || ssl->transform_out == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc );
- MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
- /*
- * Add MAC before if needed
- */
- #if defined(SSL_SOME_MODES_USE_MAC)
- if( mode == MBEDTLS_MODE_STREAM ||
- ( mode == MBEDTLS_MODE_CBC
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
- #endif
- ) )
- {
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ssl_mac( &ssl->transform_out->md_ctx_enc,
- ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- }
- else
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 );
- mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 );
- mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 );
- mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
- ssl->out_msg, ssl->out_msglen );
- mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc,
- ssl->out_msg + ssl->out_msglen );
- mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
- }
- else
- #endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac",
- ssl->out_msg + ssl->out_msglen,
- ssl->transform_out->maclen );
- ssl->out_msglen += ssl->transform_out->maclen;
- auth_done++;
- }
- #endif /* AEAD not the only option */
- /*
- * Encrypt
- */
- #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- if( mode == MBEDTLS_MODE_STREAM )
- {
- int ret;
- size_t olen = 0;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
- if( ssl->out_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
- #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
- #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
- if( mode == MBEDTLS_MODE_GCM ||
- mode == MBEDTLS_MODE_CCM )
- {
- int ret;
- size_t enc_msglen, olen;
- unsigned char *enc_msg;
- unsigned char add_data[13];
- unsigned char taglen = ssl->transform_out->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
- memcpy( add_data, ssl->out_ctr, 8 );
- add_data[8] = ssl->out_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, add_data + 9 );
- add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->out_msglen & 0xFF;
- MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
- add_data, 13 );
- /*
- * Generate IV
- */
- #if defined(MBEDTLS_SSL_AEAD_RANDOM_IV)
- ret = ssl->conf->f_rng( ssl->conf->p_rng,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- if( ret != 0 )
- return( ret );
- memcpy( ssl->out_iv,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- #else
- if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 )
- {
- /* Reminder if we ever add an AEAD mode with a different size */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->out_ctr, 8 );
- memcpy( ssl->out_iv, ssl->out_ctr, 8 );
- #endif
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
- /*
- * Encrypt and authenticate
- */
- if( ( ret = mbedtls_cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- add_data, 13,
- enc_msg, enc_msglen,
- enc_msg, &olen,
- enc_msg + enc_msglen, taglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
- return( ret );
- }
- if( olen != enc_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- ssl->out_msglen += taglen;
- auth_done++;
- MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen );
- }
- else
- #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) )
- if( mode == MBEDTLS_MODE_CBC )
- {
- int ret;
- unsigned char *enc_msg;
- size_t enc_msglen, padlen, olen = 0, i;
- padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
- ssl->transform_out->ivlen;
- if( padlen == ssl->transform_out->ivlen )
- padlen = 0;
- for( i = 0; i <= padlen; i++ )
- ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
- ssl->out_msglen += padlen + 1;
- enc_msglen = ssl->out_msglen;
- enc_msg = ssl->out_msg;
- #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Prepend per-record IV for block cipher in TLS v1.1 and up as per
- * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Generate IV
- */
- ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
- if( ret != 0 )
- return( ret );
- memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen;
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of IV and %d bytes of padding",
- ssl->out_msglen, ssl->transform_out->ivlen,
- padlen + 1 ) );
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- enc_msg, enc_msglen,
- enc_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
- if( enc_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Save IV in SSL3 and TLS1
- */
- memcpy( ssl->transform_out->iv_enc,
- ssl->transform_out->cipher_ctx_enc.iv,
- ssl->transform_out->ivlen );
- }
- #endif
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( auth_done == 0 )
- {
- /*
- * MAC(MAC_write_key, seq_num +
- * TLSCipherText.type +
- * TLSCipherText.version +
- * length_of( (IV +) ENC(...) ) +
- * IV + // except for TLS 1.0
- * ENC(content + padding + padding_length));
- */
- unsigned char pseudo_hdr[13];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
- memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 );
- memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 );
- pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF );
- pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF );
- MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
- mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
- mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
- ssl->out_iv, ssl->out_msglen );
- mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc,
- ssl->out_iv + ssl->out_msglen );
- mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
- ssl->out_msglen += ssl->transform_out->maclen;
- auth_done++;
- }
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- }
- else
- #endif /* MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- /* Make extra sure authentication was performed, exactly once */
- if( auth_done != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
- return( 0 );
- }
- #define SSL_MAX_MAC_SIZE 48
- static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
- {
- size_t i;
- mbedtls_cipher_mode_t mode;
- int auth_done = 0;
- #if defined(SSL_SOME_MODES_USE_MAC)
- size_t padlen = 0, correct = 1;
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
- if( ssl->session_in == NULL || ssl->transform_in == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec );
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
- ssl->in_msglen, ssl->transform_in->minlen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- if( mode == MBEDTLS_MODE_STREAM )
- {
- int ret;
- size_t olen = 0;
- padlen = 0;
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
- if( ssl->in_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
- #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
- #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
- if( mode == MBEDTLS_MODE_GCM ||
- mode == MBEDTLS_MODE_CCM )
- {
- int ret;
- size_t dec_msglen, olen;
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- unsigned char add_data[13];
- unsigned char taglen = ssl->transform_in->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
- size_t explicit_iv_len = ssl->transform_in->ivlen -
- ssl->transform_in->fixed_ivlen;
- if( ssl->in_msglen < explicit_iv_len + taglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
- "+ taglen (%d)", ssl->in_msglen,
- explicit_iv_len, taglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- dec_msglen = ssl->in_msglen - explicit_iv_len - taglen;
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
- ssl->in_msglen = dec_msglen;
- memcpy( add_data, ssl->in_ctr, 8 );
- add_data[8] = ssl->in_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, add_data + 9 );
- add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->in_msglen & 0xFF;
- MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
- add_data, 13 );
- memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
- ssl->in_iv,
- ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen );
- /*
- * Decrypt and authenticate
- */
- if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- add_data, 13,
- dec_msg, dec_msglen,
- dec_msg_result, &olen,
- dec_msg + dec_msglen, taglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
- if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- return( ret );
- }
- auth_done++;
- if( olen != dec_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
- #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
- #if defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) )
- if( mode == MBEDTLS_MODE_CBC )
- {
- /*
- * Decrypt and check the padding
- */
- int ret;
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- size_t dec_msglen;
- size_t minlen = 0;
- size_t olen = 0;
- /*
- * Check immediate ciphertext sanity
- */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- minlen += ssl->transform_in->ivlen;
- #endif
- if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
- ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
- "+ 1 ) ( + expl IV )", ssl->in_msglen,
- ssl->transform_in->ivlen,
- ssl->transform_in->maclen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- dec_msglen = ssl->in_msglen;
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
- /*
- * Authenticate before decrypt if enabled
- */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
- {
- unsigned char computed_mac[SSL_MAX_MAC_SIZE];
- unsigned char pseudo_hdr[13];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
- dec_msglen -= ssl->transform_in->maclen;
- ssl->in_msglen -= ssl->transform_in->maclen;
- memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 );
- memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 );
- pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF );
- pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF );
- MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec,
- ssl->in_iv, ssl->in_msglen );
- mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, computed_mac );
- mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
- MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen,
- ssl->transform_in->maclen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", computed_mac,
- ssl->transform_in->maclen );
- if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, computed_mac,
- ssl->transform_in->maclen ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- auth_done++;
- }
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- /*
- * Check length sanity
- */
- if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
- ssl->in_msglen, ssl->transform_in->ivlen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Initialize for prepended IV for block cipher in TLS v1.1 and up
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- dec_msglen -= ssl->transform_in->ivlen;
- ssl->in_msglen -= ssl->transform_in->ivlen;
- for( i = 0; i < ssl->transform_in->ivlen; i++ )
- ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- dec_msg, dec_msglen,
- dec_msg_result, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
- if( dec_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Save IV in SSL3 and TLS1
- */
- memcpy( ssl->transform_in->iv_dec,
- ssl->transform_in->cipher_ctx_dec.iv,
- ssl->transform_in->ivlen );
- }
- #endif
- padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
- if( ssl->in_msglen < ssl->transform_in->maclen + padlen &&
- auth_done == 0 )
- {
- #if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
- ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
- #endif
- padlen = 0;
- correct = 0;
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( padlen > ssl->transform_in->ivlen )
- {
- #if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
- "should be no more than %d",
- padlen, ssl->transform_in->ivlen ) );
- #endif
- correct = 0;
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /*
- * TLSv1+: always check the padding up to the first failure
- * and fake check up to 256 bytes of padding
- */
- size_t pad_count = 0, real_count = 1;
- size_t padding_idx = ssl->in_msglen - padlen - 1;
- /*
- * Padding is guaranteed to be incorrect if:
- * 1. padlen >= ssl->in_msglen
- *
- * 2. padding_idx >= MBEDTLS_SSL_MAX_CONTENT_LEN +
- * ssl->transform_in->maclen
- *
- * In both cases we reset padding_idx to a safe value (0) to
- * prevent out-of-buffer reads.
- */
- correct &= ( ssl->in_msglen >= padlen + 1 );
- correct &= ( padding_idx < MBEDTLS_SSL_MAX_CONTENT_LEN +
- ssl->transform_in->maclen );
- padding_idx *= correct;
- for( i = 1; i <= 256; i++ )
- {
- real_count &= ( i <= padlen );
- pad_count += real_count *
- ( ssl->in_msg[padding_idx + i] == padlen - 1 );
- }
- correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
- #if defined(MBEDTLS_SSL_DEBUG_ALL)
- if( padlen > 0 && correct == 0 )
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
- #endif
- padlen &= correct * 0x1FF;
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- ssl->in_msglen -= padlen;
- }
- else
- #endif /* MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
- ssl->in_msg, ssl->in_msglen );
- /*
- * Authenticate if not done yet.
- * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
- */
- #if defined(SSL_SOME_MODES_USE_MAC)
- if( auth_done == 0 )
- {
- unsigned char tmp[SSL_MAX_MAC_SIZE];
- ssl->in_msglen -= ssl->transform_in->maclen;
- ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
- ssl->in_len[1] = (unsigned char)( ssl->in_msglen );
- memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ssl_mac( &ssl->transform_in->md_ctx_dec,
- ssl->transform_in->mac_dec,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_ctr, ssl->in_msgtype );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /*
- * Process MAC and always update for padlen afterwards to make
- * total time independent of padlen
- *
- * extra_run compensates MAC check for padlen
- *
- * Known timing attacks:
- * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
- *
- * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
- * correctly. (We round down instead of up, so -56 is the correct
- * value for our calculations instead of -55)
- */
- size_t j, extra_run = 0;
- extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
- ( 13 + ssl->in_msglen + 8 ) / 64;
- extra_run &= correct * 0xFF;
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
- ssl->in_msglen );
- mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec,
- ssl->in_msg + ssl->in_msglen );
- /* Call mbedtls_md_process at least once due to cache attacks */
- for( j = 0; j < extra_run + 1; j++ )
- mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
- mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen,
- ssl->transform_in->maclen );
- if( mbedtls_ssl_safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen,
- ssl->transform_in->maclen ) != 0 )
- {
- #if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
- #endif
- correct = 0;
- }
- auth_done++;
- /*
- * Finally check the correct flag
- */
- if( correct == 0 )
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- #endif /* SSL_SOME_MODES_USE_MAC */
- /* Make extra sure authentication was performed, exactly once */
- if( auth_done != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- if( ssl->in_msglen == 0 )
- {
- ssl->nb_zero++;
- /*
- * Three or more empty messages may be a DoS attack
- * (excessive CPU consumption).
- */
- if( ssl->nb_zero > 3 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
- "messages, possible DoS attack" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- }
- else
- ssl->nb_zero = 0;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ; /* in_ctr read from peer, not maintained internally */
- }
- else
- #endif
- {
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->in_ctr[i - 1] != 0 )
- break;
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
- return( 0 );
- }
- #undef MAC_NONE
- #undef MAC_PLAINTEXT
- #undef MAC_CIPHERTEXT
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- /*
- * Compression/decompression functions
- */
- static int ssl_compress_buf( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned char *msg_post = ssl->out_msg;
- size_t len_pre = ssl->out_msglen;
- unsigned char *msg_pre = ssl->compress_buf;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
- if( len_pre == 0 )
- return( 0 );
- memcpy( msg_pre, ssl->out_msg, len_pre );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
- ssl->out_msglen ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
- ssl->out_msg, ssl->out_msglen );
- ssl->transform_out->ctx_deflate.next_in = msg_pre;
- ssl->transform_out->ctx_deflate.avail_in = len_pre;
- ssl->transform_out->ctx_deflate.next_out = msg_post;
- ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN;
- ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
- if( ret != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
- ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN -
- ssl->transform_out->ctx_deflate.avail_out;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
- ssl->out_msglen ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
- ssl->out_msg, ssl->out_msglen );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
- return( 0 );
- }
- static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned char *msg_post = ssl->in_msg;
- size_t len_pre = ssl->in_msglen;
- unsigned char *msg_pre = ssl->compress_buf;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
- if( len_pre == 0 )
- return( 0 );
- memcpy( msg_pre, ssl->in_msg, len_pre );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
- ssl->in_msglen ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
- ssl->in_msg, ssl->in_msglen );
- ssl->transform_in->ctx_inflate.next_in = msg_pre;
- ssl->transform_in->ctx_inflate.avail_in = len_pre;
- ssl->transform_in->ctx_inflate.next_out = msg_post;
- ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_MAX_CONTENT_LEN;
- ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
- if( ret != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
- ssl->in_msglen = MBEDTLS_SSL_MAX_CONTENT_LEN -
- ssl->transform_in->ctx_inflate.avail_out;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
- ssl->in_msglen ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
- ssl->in_msg, ssl->in_msglen );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_ZLIB_SUPPORT */
- #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
- {
- /* If renegotiation is not enforced, retransmit until we would reach max
- * timeout if we were using the usual handshake doubling scheme */
- if( ssl->conf->renego_max_records < 0 )
- {
- uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
- unsigned char doublings = 1;
- while( ratio != 0 )
- {
- ++doublings;
- ratio >>= 1;
- }
- if( ++ssl->renego_records_seen > doublings )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) );
- return( 0 );
- }
- }
- return( ssl_write_hello_request( ssl ) );
- }
- #endif
- #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
- /*
- * Fill the input message buffer by appending data to it.
- * The amount of data already fetched is in ssl->in_left.
- *
- * If we return 0, is it guaranteed that (at least) nb_want bytes are
- * available (from this read and/or a previous one). Otherwise, an error code
- * is returned (possibly EOF or WANT_READ).
- *
- * With stream transport (TLS) on success ssl->in_left == nb_want, but
- * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
- * since we always read a whole datagram at once.
- *
- * For DTLS, it is up to the caller to set ssl->next_record_offset when
- * they're done reading a record.
- */
- int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
- {
- int ret;
- size_t len;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
- if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
- "or mbedtls_ssl_set_bio()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- if( nb_want > MBEDTLS_SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- uint32_t timeout;
- /* Just to be sure */
- if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
- "mbedtls_ssl_set_timer_cb() for DTLS" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- /*
- * The point is, we need to always read a full datagram at once, so we
- * sometimes read more then requested, and handle the additional data.
- * It could be the rest of the current record (while fetching the
- * header) and/or some other records in the same datagram.
- */
- /*
- * Move to the next record in the already read datagram if applicable
- */
- if( ssl->next_record_offset != 0 )
- {
- if( ssl->in_left < ssl->next_record_offset )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- ssl->in_left -= ssl->next_record_offset;
- if( ssl->in_left != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
- ssl->next_record_offset ) );
- memmove( ssl->in_hdr,
- ssl->in_hdr + ssl->next_record_offset,
- ssl->in_left );
- }
- ssl->next_record_offset = 0;
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
- /*
- * Done if we already have enough data.
- */
- if( nb_want <= ssl->in_left)
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
- return( 0 );
- }
- /*
- * A record can't be split accross datagrams. If we need to read but
- * are not at the beginning of a new record, the caller did something
- * wrong.
- */
- if( ssl->in_left != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- /*
- * Don't even try to read if time's out already.
- * This avoids by-passing the timer when repeatedly receiving messages
- * that will end up being dropped.
- */
- if( ssl_check_timer( ssl ) != 0 )
- ret = MBEDTLS_ERR_SSL_TIMEOUT;
- else
- {
- len = MBEDTLS_SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- timeout = ssl->handshake->retransmit_timeout;
- else
- timeout = ssl->conf->read_timeout;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
- if( ssl->f_recv_timeout != NULL )
- ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
- timeout );
- else
- ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_CONN_EOF );
- }
- if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
- ssl_set_timer( ssl, 0 );
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- if( ssl_double_retransmit_timeout( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
- return( MBEDTLS_ERR_SSL_TIMEOUT );
- }
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
- return( ret );
- }
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
- }
- if( ret < 0 )
- return( ret );
- ssl->in_left = ret;
- }
- else
- #endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
- while( ssl->in_left < nb_want )
- {
- len = nb_want - ssl->in_left;
- if( ssl_check_timer( ssl ) != 0 )
- ret = MBEDTLS_ERR_SSL_TIMEOUT;
- else
- {
- if( ssl->f_recv_timeout != NULL )
- {
- ret = ssl->f_recv_timeout( ssl->p_bio,
- ssl->in_hdr + ssl->in_left, len,
- ssl->conf->read_timeout );
- }
- else
- {
- ret = ssl->f_recv( ssl->p_bio,
- ssl->in_hdr + ssl->in_left, len );
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_CONN_EOF );
- if( ret < 0 )
- return( ret );
- ssl->in_left += ret;
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
- return( 0 );
- }
- /*
- * Flush any data not yet written
- */
- int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned char *buf, i;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
- if( ssl->f_send == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
- "or mbedtls_ssl_set_bio()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- /* Avoid incrementing counter if data is flushed */
- if( ssl->out_left == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
- return( 0 );
- }
- while( ssl->out_left > 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
- mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
- buf = ssl->out_hdr + mbedtls_ssl_hdr_len( ssl ) +
- ssl->out_msglen - ssl->out_left;
- ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
- if( ret <= 0 )
- return( ret );
- ssl->out_left -= ret;
- }
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->out_ctr[i - 1] != 0 )
- break;
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
- return( 0 );
- }
- /*
- * Functions to handle the DTLS retransmission state machine
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- /*
- * Append current handshake message to current outgoing flight
- */
- static int ssl_flight_append( mbedtls_ssl_context *ssl )
- {
- mbedtls_ssl_flight_item *msg;
- /* Allocate space for current message */
- if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
- sizeof( mbedtls_ssl_flight_item ) ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
- mbedtls_free( msg );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- /* Copy current handshake message with headers */
- memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
- msg->len = ssl->out_msglen;
- msg->type = ssl->out_msgtype;
- msg->next = NULL;
- /* Append to the current flight */
- if( ssl->handshake->flight == NULL )
- ssl->handshake->flight = msg;
- else
- {
- mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
- while( cur->next != NULL )
- cur = cur->next;
- cur->next = msg;
- }
- return( 0 );
- }
- /*
- * Free the current flight of handshake messages
- */
- static void ssl_flight_free( mbedtls_ssl_flight_item *flight )
- {
- mbedtls_ssl_flight_item *cur = flight;
- mbedtls_ssl_flight_item *next;
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur->p );
- mbedtls_free( cur );
- cur = next;
- }
- }
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
- #endif
- /*
- * Swap transform_out and out_ctr with the alternative ones
- */
- static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
- {
- mbedtls_ssl_transform *tmp_transform;
- unsigned char tmp_out_ctr[8];
- if( ssl->transform_out == ssl->handshake->alt_transform_out )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
- return;
- }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
- /* Swap transforms */
- tmp_transform = ssl->transform_out;
- ssl->transform_out = ssl->handshake->alt_transform_out;
- ssl->handshake->alt_transform_out = tmp_transform;
- /* Swap epoch + sequence_number */
- memcpy( tmp_out_ctr, ssl->out_ctr, 8 );
- memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 );
- memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
- /* Adjust to the newly activated transform */
- if( ssl->transform_out != NULL &&
- ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->out_msg = ssl->out_iv + ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
- }
- else
- ssl->out_msg = ssl->out_iv;
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
- {
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
- #endif
- }
- /*
- * Retransmit the current flight of messages.
- *
- * Need to remember the current message in case flush_output returns
- * WANT_WRITE, causing us to exit this function and come back later.
- * This function must be called until state is no longer SENDING.
- */
- int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
- if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise resending" ) );
- ssl->handshake->cur_msg = ssl->handshake->flight;
- ssl_swap_epochs( ssl );
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
- }
- while( ssl->handshake->cur_msg != NULL )
- {
- int ret;
- mbedtls_ssl_flight_item *cur = ssl->handshake->cur_msg;
- /* Swap epochs before sending Finished: we can't do it after
- * sending ChangeCipherSpec, in case write returns WANT_READ.
- * Must be done before copying, may change out_msg pointer */
- if( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
- cur->p[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl_swap_epochs( ssl );
- }
- memcpy( ssl->out_msg, cur->p, cur->len );
- ssl->out_msglen = cur->len;
- ssl->out_msgtype = cur->type;
- ssl->handshake->cur_msg = cur->next;
- MBEDTLS_SSL_DEBUG_BUF( 3, "resent handshake message header", ssl->out_msg, 12 );
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- }
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- else
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
- return( 0 );
- }
- /*
- * To be called when the last message of an incoming flight is received.
- */
- void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
- {
- /* We won't need to resend that one any more */
- ssl_flight_free( ssl->handshake->flight );
- ssl->handshake->flight = NULL;
- ssl->handshake->cur_msg = NULL;
- /* The next incoming flight will start with this msg_seq */
- ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
- /* Cancel timer */
- ssl_set_timer( ssl, 0 );
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- }
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
- }
- /*
- * To be called when the last message of an outgoing flight is send.
- */
- void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
- {
- ssl_reset_retransmit_timeout( ssl );
- ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- }
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- /*
- * Record layer functions
- */
- /*
- * Write current record.
- * Uses ssl->out_msgtype, ssl->out_msglen and bytes at ssl->out_msg.
- */
- int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
- {
- int ret, done = 0;
- size_t len = ssl->out_msglen;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- ; /* Skip special handshake treatment when resending */
- }
- else
- #endif
- if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST &&
- ssl->handshake == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 );
- ssl->out_msg[2] = (unsigned char)( ( len - 4 ) >> 8 );
- ssl->out_msg[3] = (unsigned char)( ( len - 4 ) );
- /*
- * DTLS has additional fields in the Handshake layer,
- * between the length field and the actual payload:
- * uint16 message_seq;
- * uint24 fragment_offset;
- * uint24 fragment_length;
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Make room for the additional DTLS fields */
- memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 );
- ssl->out_msglen += 8;
- len += 8;
- /* Write message_seq and update it, except for HelloRequest */
- if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST )
- {
- ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
- ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF;
- ++( ssl->handshake->out_msg_seq );
- }
- else
- {
- ssl->out_msg[4] = 0;
- ssl->out_msg[5] = 0;
- }
- /* We don't fragment, so frag_offset = 0 and frag_len = len */
- memset( ssl->out_msg + 6, 0x00, 3 );
- memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST )
- ssl->handshake->update_checksum( ssl, ssl->out_msg, len );
- }
- /* Save handshake and CCS messages for resending */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING &&
- ( ssl->out_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ||
- ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) )
- {
- if( ( ret = ssl_flight_append( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
- return( ret );
- }
- }
- #endif
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->transform_out != NULL &&
- ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
- return( ret );
- }
- len = ssl->out_msglen;
- }
- #endif /*MBEDTLS_ZLIB_SUPPORT */
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_write != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
- ret = mbedtls_ssl_hw_record_write( ssl );
- if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- if( ret == 0 )
- done = 1;
- }
- #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- if( !done )
- {
- ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, ssl->out_hdr + 1 );
- ssl->out_len[0] = (unsigned char)( len >> 8 );
- ssl->out_len[1] = (unsigned char)( len );
- if( ssl->transform_out != NULL )
- {
- if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
- return( ret );
- }
- len = ssl->out_msglen;
- ssl->out_len[0] = (unsigned char)( len >> 8 );
- ssl->out_len[1] = (unsigned char)( len );
- }
- ssl->out_left = mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2],
- ( ssl->out_len[0] << 8 ) | ssl->out_len[1] ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen );
- }
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- /*
- * Mark bits in bitmask (used for DTLS HS reassembly)
- */
- static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
- {
- unsigned int start_bits, end_bits;
- start_bits = 8 - ( offset % 8 );
- if( start_bits != 8 )
- {
- size_t first_byte_idx = offset / 8;
- /* Special case */
- if( len <= start_bits )
- {
- for( ; len != 0; len-- )
- mask[first_byte_idx] |= 1 << ( start_bits - len );
- /* Avoid potential issues with offset or len becoming invalid */
- return;
- }
- offset += start_bits; /* Now offset % 8 == 0 */
- len -= start_bits;
- for( ; start_bits != 0; start_bits-- )
- mask[first_byte_idx] |= 1 << ( start_bits - 1 );
- }
- end_bits = len % 8;
- if( end_bits != 0 )
- {
- size_t last_byte_idx = ( offset + len ) / 8;
- len -= end_bits; /* Now len % 8 == 0 */
- for( ; end_bits != 0; end_bits-- )
- mask[last_byte_idx] |= 1 << ( 8 - end_bits );
- }
- memset( mask + offset / 8, 0xFF, len / 8 );
- }
- /*
- * Check that bitmask is full
- */
- static int ssl_bitmask_check( unsigned char *mask, size_t len )
- {
- size_t i;
- for( i = 0; i < len / 8; i++ )
- if( mask[i] != 0xFF )
- return( -1 );
- for( i = 0; i < len % 8; i++ )
- if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
- return( -1 );
- return( 0 );
- }
- /*
- * Reassemble fragmented DTLS handshake messages.
- *
- * Use a temporary buffer for reassembly, divided in two parts:
- * - the first holds the reassembled message (including handshake header),
- * - the second holds a bitmask indicating which parts of the message
- * (excluding headers) have been received so far.
- */
- static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl )
- {
- unsigned char *msg, *bitmask;
- size_t frag_len, frag_off;
- size_t msg_len = ssl->in_hslen - 12; /* Without headers */
- if( ssl->handshake == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "not supported outside handshake (for now)" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- /*
- * For first fragment, check size and allocate buffer
- */
- if( ssl->handshake->hs_msg == NULL )
- {
- size_t alloc_len;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
- msg_len ) );
- if( ssl->in_hslen > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too large" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- /* The bitmask needs one bit per byte of message excluding header */
- alloc_len = 12 + msg_len + msg_len / 8 + ( msg_len % 8 != 0 );
- ssl->handshake->hs_msg = mbedtls_calloc( 1, alloc_len );
- if( ssl->handshake->hs_msg == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", alloc_len ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- /* Prepare final header: copy msg_type, length and message_seq,
- * then add standardised fragment_offset and fragment_length */
- memcpy( ssl->handshake->hs_msg, ssl->in_msg, 6 );
- memset( ssl->handshake->hs_msg + 6, 0, 3 );
- memcpy( ssl->handshake->hs_msg + 9,
- ssl->handshake->hs_msg + 1, 3 );
- }
- else
- {
- /* Make sure msg_type and length are consistent */
- if( memcmp( ssl->handshake->hs_msg, ssl->in_msg, 4 ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment header mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
- msg = ssl->handshake->hs_msg + 12;
- bitmask = msg + msg_len;
- /*
- * Check and copy current fragment
- */
- frag_off = ( ssl->in_msg[6] << 16 ) |
- ( ssl->in_msg[7] << 8 ) |
- ssl->in_msg[8];
- frag_len = ( ssl->in_msg[9] << 16 ) |
- ( ssl->in_msg[10] << 8 ) |
- ssl->in_msg[11];
- if( frag_off + frag_len > msg_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment offset/len: %d + %d > %d",
- frag_off, frag_len, msg_len ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- if( frag_len + 12 > ssl->in_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment length: %d + 12 > %d",
- frag_len, ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
- frag_off, frag_len ) );
- memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
- ssl_bitmask_set( bitmask, frag_off, frag_len );
- /*
- * Do we have the complete message by now?
- * If yes, finalize it, else ask to read the next record.
- */
- if( ssl_bitmask_check( bitmask, msg_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "message is not complete yet" ) );
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake message completed" ) );
- if( frag_len + 12 < ssl->in_msglen )
- {
- /*
- * We'got more handshake messages in the same record.
- * This case is not handled now because no know implementation does
- * that and it's hard to test, so we prefer to fail cleanly for now.
- */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "last fragment not alone in its record" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- if( ssl->in_left > ssl->next_record_offset )
- {
- /*
- * We've got more data in the buffer after the current record,
- * that we don't want to overwrite. Move it before writing the
- * reassembled message, and adjust in_left and next_record_offset.
- */
- unsigned char *cur_remain = ssl->in_hdr + ssl->next_record_offset;
- unsigned char *new_remain = ssl->in_msg + ssl->in_hslen;
- size_t remain_len = ssl->in_left - ssl->next_record_offset;
- /* First compute and check new lengths */
- ssl->next_record_offset = new_remain - ssl->in_hdr;
- ssl->in_left = ssl->next_record_offset + remain_len;
- if( ssl->in_left > MBEDTLS_SSL_BUFFER_LEN -
- (size_t)( ssl->in_hdr - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "reassembled message too large for buffer" ) );
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- }
- memmove( new_remain, cur_remain, remain_len );
- }
- memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen );
- mbedtls_free( ssl->handshake->hs_msg );
- ssl->handshake->hs_msg = NULL;
- MBEDTLS_SSL_DEBUG_BUF( 3, "reassembled handshake message",
- ssl->in_msg, ssl->in_hslen );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- static int ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
- {
- if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + (
- ( ssl->in_msg[1] << 16 ) |
- ( ssl->in_msg[2] << 8 ) |
- ssl->in_msg[3] );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
- " %d, type = %d, hslen = %d",
- ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- int ret;
- unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
- /* ssl->handshake is NULL when receiving ClientHello for renego */
- if( ssl->handshake != NULL &&
- recv_msg_seq != ssl->handshake->in_msg_seq )
- {
- /* Retransmit only on last message from previous flight, to avoid
- * too many retransmissions.
- * Besides, No sane server ever retransmits HelloVerifyRequest */
- if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
- "message_seq = %d, start_of_flight = %d",
- recv_msg_seq,
- ssl->handshake->in_flight_start_seq ) );
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
- "message_seq = %d, expected = %d",
- recv_msg_seq,
- ssl->handshake->in_msg_seq ) );
- }
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- /* Wait until message completion to increment in_msg_seq */
- /* Reassemble if current message is fragmented or reassembly is
- * already in progress */
- if( ssl->in_msglen < ssl->in_hslen ||
- memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
- memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ||
- ( ssl->handshake != NULL && ssl->handshake->hs_msg != NULL ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
- if( ( ret = ssl_reassemble_dtls_handshake( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_reassemble_dtls_handshake", ret );
- return( ret );
- }
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- /* With TLS we don't handle fragmentation (for now) */
- if( ssl->in_msglen < ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
- ssl->handshake != NULL )
- {
- ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
- }
- /* Handshake message is complete, increment counter */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL )
- {
- ssl->handshake->in_msg_seq++;
- }
- #endif
- return( 0 );
- }
- /*
- * DTLS anti-replay: RFC 6347 4.1.2.6
- *
- * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
- * Bit n is set iff record number in_window_top - n has been seen.
- *
- * Usually, in_window_top is the last record number seen and the lsb of
- * in_window is set. The only exception is the initial state (record number 0
- * not seen yet).
- */
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
- {
- ssl->in_window_top = 0;
- ssl->in_window = 0;
- }
- static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
- {
- return( ( (uint64_t) buf[0] << 40 ) |
- ( (uint64_t) buf[1] << 32 ) |
- ( (uint64_t) buf[2] << 24 ) |
- ( (uint64_t) buf[3] << 16 ) |
- ( (uint64_t) buf[4] << 8 ) |
- ( (uint64_t) buf[5] ) );
- }
- /*
- * Return 0 if sequence number is acceptable, -1 otherwise
- */
- int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl )
- {
- uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
- uint64_t bit;
- if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
- return( 0 );
- if( rec_seqnum > ssl->in_window_top )
- return( 0 );
- bit = ssl->in_window_top - rec_seqnum;
- if( bit >= 64 )
- return( -1 );
- if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
- return( -1 );
- return( 0 );
- }
- /*
- * Update replay window on new validated record
- */
- void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
- {
- uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
- if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
- return;
- if( rec_seqnum > ssl->in_window_top )
- {
- /* Update window_top and the contents of the window */
- uint64_t shift = rec_seqnum - ssl->in_window_top;
- if( shift >= 64 )
- ssl->in_window = 1;
- else
- {
- ssl->in_window <<= shift;
- ssl->in_window |= 1;
- }
- ssl->in_window_top = rec_seqnum;
- }
- else
- {
- /* Mark that number as seen in the current window */
- uint64_t bit = ssl->in_window_top - rec_seqnum;
- if( bit < 64 ) /* Always true, but be extra sure */
- ssl->in_window |= (uint64_t) 1 << bit;
- }
- }
- #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
- /* Forward declaration */
- static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
- /*
- * Without any SSL context, check if a datagram looks like a ClientHello with
- * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
- * Both input and output include full DTLS headers.
- *
- * - if cookie is valid, return 0
- * - if ClientHello looks superficially valid but cookie is not,
- * fill obuf and set olen, then
- * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
- * - otherwise return a specific error code
- */
- static int ssl_check_dtls_clihlo_cookie(
- mbedtls_ssl_cookie_write_t *f_cookie_write,
- mbedtls_ssl_cookie_check_t *f_cookie_check,
- void *p_cookie,
- const unsigned char *cli_id, size_t cli_id_len,
- const unsigned char *in, size_t in_len,
- unsigned char *obuf, size_t buf_len, size_t *olen )
- {
- size_t sid_len, cookie_len;
- unsigned char *p;
- if( f_cookie_write == NULL || f_cookie_check == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /*
- * Structure of ClientHello with record and handshake headers,
- * and expected values. We don't need to check a lot, more checks will be
- * done when actually parsing the ClientHello - skipping those checks
- * avoids code duplication and does not make cookie forging any easier.
- *
- * 0-0 ContentType type; copied, must be handshake
- * 1-2 ProtocolVersion version; copied
- * 3-4 uint16 epoch; copied, must be 0
- * 5-10 uint48 sequence_number; copied
- * 11-12 uint16 length; (ignored)
- *
- * 13-13 HandshakeType msg_type; (ignored)
- * 14-16 uint24 length; (ignored)
- * 17-18 uint16 message_seq; copied
- * 19-21 uint24 fragment_offset; copied, must be 0
- * 22-24 uint24 fragment_length; (ignored)
- *
- * 25-26 ProtocolVersion client_version; (ignored)
- * 27-58 Random random; (ignored)
- * 59-xx SessionID session_id; 1 byte len + sid_len content
- * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
- * ...
- *
- * Minimum length is 61 bytes.
- */
- if( in_len < 61 ||
- in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
- in[3] != 0 || in[4] != 0 ||
- in[19] != 0 || in[20] != 0 || in[21] != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
- sid_len = in[59];
- if( sid_len > in_len - 61 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- cookie_len = in[60 + sid_len];
- if( cookie_len > in_len - 60 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
- cli_id, cli_id_len ) == 0 )
- {
- /* Valid cookie */
- return( 0 );
- }
- /*
- * If we get here, we've got an invalid cookie, let's prepare HVR.
- *
- * 0-0 ContentType type; copied
- * 1-2 ProtocolVersion version; copied
- * 3-4 uint16 epoch; copied
- * 5-10 uint48 sequence_number; copied
- * 11-12 uint16 length; olen - 13
- *
- * 13-13 HandshakeType msg_type; hello_verify_request
- * 14-16 uint24 length; olen - 25
- * 17-18 uint16 message_seq; copied
- * 19-21 uint24 fragment_offset; copied
- * 22-24 uint24 fragment_length; olen - 25
- *
- * 25-26 ProtocolVersion server_version; 0xfe 0xff
- * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
- *
- * Minimum length is 28.
- */
- if( buf_len < 28 )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
- /* Copy most fields and adapt others */
- memcpy( obuf, in, 25 );
- obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
- obuf[25] = 0xfe;
- obuf[26] = 0xff;
- /* Generate and write actual cookie */
- p = obuf + 28;
- if( f_cookie_write( p_cookie,
- &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
- {
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- *olen = p - obuf;
- /* Go back and fill length fields */
- obuf[27] = (unsigned char)( *olen - 28 );
- obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
- obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 );
- obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) );
- obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 );
- obuf[12] = (unsigned char)( ( *olen - 13 ) );
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
- }
- /*
- * Handle possible client reconnect with the same UDP quadruplet
- * (RFC 6347 Section 4.2.8).
- *
- * Called by ssl_parse_record_header() in case we receive an epoch 0 record
- * that looks like a ClientHello.
- *
- * - if the input looks like a ClientHello without cookies,
- * send back HelloVerifyRequest, then
- * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
- * - if the input looks like a ClientHello with a valid cookie,
- * reset the session of the current context, and
- * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
- * - if anything goes wrong, return a specific error code
- *
- * mbedtls_ssl_read_record() will ignore the record if anything else than
- * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function
- * cannot not return 0.
- */
- static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
- {
- int ret;
- size_t len;
- ret = ssl_check_dtls_clihlo_cookie(
- ssl->conf->f_cookie_write,
- ssl->conf->f_cookie_check,
- ssl->conf->p_cookie,
- ssl->cli_id, ssl->cli_id_len,
- ssl->in_buf, ssl->in_left,
- ssl->out_buf, MBEDTLS_SSL_MAX_CONTENT_LEN, &len );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
- if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
- {
- /* Dont check write errors as we can't do anything here.
- * If the error is permanent we'll catch it later,
- * if it's not, then hopefully it'll work next time. */
- (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
- }
- if( ret == 0 )
- {
- /* Got a valid cookie, partially reset context */
- if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
- return( ret );
- }
- return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
- }
- return( ret );
- }
- #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
- /*
- * ContentType type;
- * ProtocolVersion version;
- * uint16 epoch; // DTLS only
- * uint48 sequence_number; // DTLS only
- * uint16 length;
- *
- * Return 0 if header looks sane (and, for DTLS, the record is expected)
- * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
- * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
- *
- * With DTLS, mbedtls_ssl_read_record() will:
- * 1. proceed with the record if this function returns 0
- * 2. drop only the current record if this function returns UNEXPECTED_RECORD
- * 3. return CLIENT_RECONNECT if this function return that value
- * 4. drop the whole datagram if this function returns anything else.
- * Point 2 is needed when the peer is resending, and we have already received
- * the first record from a datagram but are still waiting for the others.
- */
- static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
- {
- int ret;
- int major_ver, minor_ver;
- MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) );
- ssl->in_msgtype = ssl->in_hdr[0];
- ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
- mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->in_msgtype,
- major_ver, minor_ver, ssl->in_msglen ) );
- /* Check record type */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ) ) != 0 )
- {
- return( ret );
- }
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- /* Check version */
- if( major_ver != ssl->major_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- if( minor_ver > ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- /* Check length against the size of our buffer */
- if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN
- - (size_t)( ssl->in_msg - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- /* Check length against bounds of the current transform and version */
- if( ssl->transform_in == NULL )
- {
- if( ssl->in_msglen < 1 ||
- ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
- else
- {
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * TLS encrypted messages can have up to 256 bytes of padding
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
- ssl->in_msglen > ssl->transform_in->minlen +
- MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- #endif
- }
- /*
- * DTLS-related tests done last, because most of them may result in
- * silently dropping the record (but not the whole datagram), and we only
- * want to consider that after ensuring that the "basic" fields (type,
- * version, length) are sane.
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
- /* Drop unexpected ChangeCipherSpec messages */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
- ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
- ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- /* Drop unexpected ApplicationData records,
- * except at the beginning of renegotiations */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
- ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->state == MBEDTLS_SSL_SERVER_HELLO )
- #endif
- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- /* Check epoch (and sequence number) with DTLS */
- if( rec_epoch != ssl->in_epoch )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
- "expected %d, received %d",
- ssl->in_epoch, rec_epoch ) );
- #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
- /*
- * Check for an epoch 0 ClientHello. We can't use in_msg here to
- * access the first byte of record content (handshake type), as we
- * have an active transform (possibly iv_len != 0), so use the
- * fact that the record header len is 13 instead.
- */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
- rec_epoch == 0 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_left > 13 &&
- ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
- "from the same port" ) );
- return( ssl_handle_possible_reconnect( ssl ) );
- }
- else
- #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- /* Replay detection only works for the current epoch */
- if( rec_epoch == ssl->in_epoch &&
- mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- #endif
- }
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- return( 0 );
- }
- /*
- * If applicable, decrypt (and decompress) record content
- */
- static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
- {
- int ret, done = 0;
- MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
- ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen );
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_read != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
- ret = mbedtls_ssl_hw_record_read( ssl );
- if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- if( ret == 0 )
- done = 1;
- }
- #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- if( !done && ssl->transform_in != NULL )
- {
- if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
- ssl->in_msg, ssl->in_msglen );
- if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->transform_in != NULL &&
- ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
- return( ret );
- }
- // TODO: what's the purpose of these lines? is in_len used?
- ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
- ssl->in_len[1] = (unsigned char)( ssl->in_msglen );
- }
- #endif /* MBEDTLS_ZLIB_SUPPORT */
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- mbedtls_ssl_dtls_replay_update( ssl );
- }
- #endif
- return( 0 );
- }
- static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
- /*
- * Read a record.
- *
- * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
- * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
- *
- */
- int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
- if( ssl->in_hslen != 0 && ssl->in_hslen < ssl->in_msglen )
- {
- /*
- * Get next Handshake message in the current record
- */
- ssl->in_msglen -= ssl->in_hslen;
- memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
- ssl->in_msglen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
- ssl->in_msg, ssl->in_msglen );
- if( ( ret = ssl_prepare_handshake_record( ssl ) ) != 0 )
- return( ret );
- return( 0 );
- }
- ssl->in_hslen = 0;
- /*
- * Read the record header and parse it
- */
- read_record_header:
- if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
- if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
- {
- if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
- {
- /* Skip unexpected record (but not whole datagram) */
- ssl->next_record_offset = ssl->in_msglen
- + mbedtls_ssl_hdr_len( ssl );
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
- "(header)" ) );
- }
- else
- {
- /* Skip invalid record and the rest of the datagram */
- ssl->next_record_offset = 0;
- ssl->in_left = 0;
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
- "(header)" ) );
- }
- /* Get next record */
- goto read_record_header;
- }
- #endif
- return( ret );
- }
- /*
- * Read and optionally decrypt the message contents
- */
- if( ( ret = mbedtls_ssl_fetch_input( ssl,
- mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
- /* Done reading this record, get ready for the next one */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl );
- else
- #endif
- ssl->in_left = 0;
- if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Silently discard invalid records */
- if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
- ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- /* Except when waiting for Finished as a bad mac here
- * probably means something went wrong in the handshake
- * (eg wrong psk used, mitm downgrade attempt, etc.) */
- if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
- ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
- {
- #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
- }
- #endif
- return( ret );
- }
- #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
- if( ssl->conf->badmac_limit != 0 &&
- ++ssl->badmac_seen >= ssl->conf->badmac_limit )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
- goto read_record_header;
- }
- return( ret );
- }
- else
- #endif
- {
- /* Error out (and send alert) on invalid records */
- #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
- }
- #endif
- return( ret );
- }
- }
- /*
- * When we sent the last flight of the handshake, we MUST respond to a
- * retransmit of the peer's previous flight with a retransmit. (In
- * practice, only the Finished message will make it, other messages
- * including CCS use the old transform so they're dropped as invalid.)
- *
- * If the record we received is not a handshake message, however, it
- * means the peer received our last flight so we can clean up
- * handshake info.
- *
- * This check needs to be done before prepare_handshake() due to an edge
- * case: if the client immediately requests renegotiation, this
- * finishes the current handshake first, avoiding the new ClientHello
- * being mistaken for an ancient message in the current handshake.
- */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received retransmit of last flight" ) );
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- else
- {
- ssl_handshake_wrapup_free_hs_transform( ssl );
- }
- }
- #endif
- /*
- * Handle particular types of records
- */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- if( ( ret = ssl_prepare_handshake_record( ssl ) ) != 0 )
- return( ret );
- }
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
- ssl->in_msg[0], ssl->in_msg[1] ) );
- /*
- * Ignore non-fatal alerts, except close_notify and no_renegotiation
- */
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
- ssl->in_msg[1] ) );
- return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
- }
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
- return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
- /* Will be handled when trying to parse ServerHello */
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
- /* Will be handled in mbedtls_ssl_parse_certificate() */
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
- /* Silently ignore: fetch new message */
- goto read_record_header;
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
- return( 0 );
- }
- int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
- {
- int ret;
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
- unsigned char level,
- unsigned char message )
- {
- int ret;
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
- ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
- ssl->out_msglen = 2;
- ssl->out_msg[0] = level;
- ssl->out_msg[1] = message;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
- return( 0 );
- }
- /*
- * Handshake functions
- */
- #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
- {
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
- ssl->state++;
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
- {
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- #else
- int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t i, n;
- const mbedtls_x509_crt *crt;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
- ssl->state++;
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- {
- if( ssl->client_auth == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
- ssl->state++;
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- /*
- * If using SSLv3 and got no cert, send an Alert message
- * (otherwise an empty Certificate message will be sent).
- */
- if( mbedtls_ssl_own_cert( ssl ) == NULL &&
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ssl->out_msglen = 2;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
- ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING;
- ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
- goto write_msg;
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- }
- #endif /* MBEDTLS_SSL_CLI_C */
- #if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- {
- if( mbedtls_ssl_own_cert( ssl ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) );
- return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED );
- }
- }
- #endif
- MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) );
- /*
- * 0 . 0 handshake type
- * 1 . 3 handshake length
- * 4 . 6 length of all certs
- * 7 . 9 length of cert. 1
- * 10 . n-1 peer certificate
- * n . n+2 length of cert. 2
- * n+3 . ... upper level cert, etc.
- */
- i = 7;
- crt = mbedtls_ssl_own_cert( ssl );
- while( crt != NULL )
- {
- n = crt->raw.len;
- if( n > MBEDTLS_SSL_MAX_CONTENT_LEN - 3 - i )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
- i + 3 + n, MBEDTLS_SSL_MAX_CONTENT_LEN ) );
- return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
- }
- ssl->out_msg[i ] = (unsigned char)( n >> 16 );
- ssl->out_msg[i + 1] = (unsigned char)( n >> 8 );
- ssl->out_msg[i + 2] = (unsigned char)( n );
- i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
- i += n; crt = crt->next;
- }
- ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 );
- ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 );
- ssl->out_msg[6] = (unsigned char)( ( i - 7 ) );
- ssl->out_msglen = i;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
- #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
- write_msg:
- #endif
- ssl->state++;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
- return( ret );
- }
- int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t i, n;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
- int authmode = ssl->conf->authmode;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET )
- authmode = ssl->handshake->sni_authmode;
- #endif
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- authmode == MBEDTLS_SSL_VERIFY_NONE )
- {
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
- }
- #endif
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- ssl->state++;
- #if defined(MBEDTLS_SSL_SRV_C)
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- /*
- * Check if the client sent an empty certificate
- */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( ssl->in_msglen == 2 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
- ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
- return( 0 );
- else
- return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
- }
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
- memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
- return( 0 );
- else
- return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
- }
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- #endif /* MBEDTLS_SSL_SRV_C */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
- ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- i = mbedtls_ssl_hs_hdr_len( ssl );
- /*
- * Same message structure as in mbedtls_ssl_write_certificate()
- */
- n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2];
- if( ssl->in_msg[i] != 0 ||
- ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- /* In case we tried to reuse a session but it failed */
- if( ssl->session_negotiate->peer_cert != NULL )
- {
- mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert );
- mbedtls_free( ssl->session_negotiate->peer_cert );
- }
- if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1,
- sizeof( mbedtls_x509_crt ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- sizeof( mbedtls_x509_crt ) ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
- i += 3;
- while( i < ssl->in_hslen )
- {
- if( ssl->in_msg[i] != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
- | (unsigned int) ssl->in_msg[i + 2];
- i += 3;
- if( n < 128 || i + n > ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
- ssl->in_msg + i, n );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
- return( ret );
- }
- i += n;
- }
- MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
- /*
- * On client, make sure the server cert doesn't change during renego to
- * avoid "triple handshake" attack: https://secure-resumption.com/
- */
- #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- if( ssl->session->peer_cert == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- if( ssl->session->peer_cert->raw.len !=
- ssl->session_negotiate->peer_cert->raw.len ||
- memcmp( ssl->session->peer_cert->raw.p,
- ssl->session_negotiate->peer_cert->raw.p,
- ssl->session->peer_cert->raw.len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
- if( authmode != MBEDTLS_SSL_VERIFY_NONE )
- {
- mbedtls_x509_crt *ca_chain;
- mbedtls_x509_crl *ca_crl;
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- if( ssl->handshake->sni_ca_chain != NULL )
- {
- ca_chain = ssl->handshake->sni_ca_chain;
- ca_crl = ssl->handshake->sni_ca_crl;
- }
- else
- #endif
- {
- ca_chain = ssl->conf->ca_chain;
- ca_crl = ssl->conf->ca_crl;
- }
- if( ca_chain == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
- return( MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED );
- }
- /*
- * Main check: verify certificate
- */
- ret = mbedtls_x509_crt_verify_with_profile(
- ssl->session_negotiate->peer_cert,
- ca_chain, ca_crl,
- ssl->conf->cert_profile,
- ssl->hostname,
- &ssl->session_negotiate->verify_result,
- ssl->conf->f_vrfy, ssl->conf->p_vrfy );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
- }
- /*
- * Secondary checks: always done, but change 'ret' only if it was 0
- */
- #if defined(MBEDTLS_ECP_C)
- {
- const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk;
- /* If certificate uses an EC key, make sure the curve is OK */
- if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
- mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
- if( ret == 0 )
- ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
- }
- }
- #endif /* MBEDTLS_ECP_C */
- if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
- ciphersuite_info,
- ! ssl->conf->endpoint,
- &ssl->session_negotiate->verify_result ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
- if( ret == 0 )
- ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
- }
- if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
- ret = 0;
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
- return( ret );
- }
- #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
- ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
- ssl->out_msglen = 1;
- ssl->out_msg[0] = 1;
- ssl->state++;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
- return( 0 );
- }
- int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC );
- }
- /*
- * Switch to our negotiated transform and session parameters for inbound
- * data.
- */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
- ssl->transform_in = ssl->transform_negotiate;
- ssl->session_in = ssl->session_negotiate;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- ssl_dtls_replay_reset( ssl );
- #endif
- /* Increment epoch */
- if( ++ssl->in_epoch == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->in_ctr, 0, 8 );
- /*
- * Set the in_msg pointer to the correct location based on IV length
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
- ssl->transform_negotiate->fixed_ivlen;
- }
- else
- ssl->in_msg = ssl->in_iv;
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
- {
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
- #endif
- ssl->state++;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
- return( 0 );
- }
- void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
- {
- ((void) ciphersuite_info);
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
- ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
- else
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA512_C)
- if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
- ssl->handshake->update_checksum = ssl_update_checksum_sha384;
- else
- #endif
- #if defined(MBEDTLS_SHA256_C)
- if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 )
- ssl->handshake->update_checksum = ssl_update_checksum_sha256;
- else
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return;
- }
- }
- void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
- {
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_starts( &ssl->handshake->fin_md5 );
- mbedtls_sha1_starts( &ssl->handshake->fin_sha1 );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 );
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- }
- static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len );
- mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len );
- mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len );
- }
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
- }
- #endif
- #if defined(MBEDTLS_SHA512_C)
- static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
- }
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- static void ssl_calc_finished_ssl(
- mbedtls_ssl_context *ssl, unsigned char *buf, int from )
- {
- const char *sender;
- mbedtls_md5_context md5;
- mbedtls_sha1_context sha1;
- unsigned char padbuf[48];
- unsigned char md5sum[16];
- unsigned char sha1sum[20];
- mbedtls_ssl_session *session = ssl->session_negotiate;
- if( !session )
- session = ssl->session;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) );
- mbedtls_md5_init( &md5 );
- mbedtls_sha1_init( &sha1 );
- mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
- mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- /*
- * SSLv3:
- * hash =
- * MD5( master + pad2 +
- * MD5( handshake + sender + master + pad1 ) )
- * + SHA1( master + pad2 +
- * SHA1( handshake + sender + master + pad1 ) )
- */
- #if !defined(MBEDTLS_MD5_ALT)
- MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
- md5.state, sizeof( md5.state ) );
- #endif
- #if !defined(MBEDTLS_SHA1_ALT)
- MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
- sha1.state, sizeof( sha1.state ) );
- #endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT"
- : "SRVR";
- memset( padbuf, 0x36, 48 );
- mbedtls_md5_update( &md5, (const unsigned char *) sender, 4 );
- mbedtls_md5_update( &md5, session->master, 48 );
- mbedtls_md5_update( &md5, padbuf, 48 );
- mbedtls_md5_finish( &md5, md5sum );
- mbedtls_sha1_update( &sha1, (const unsigned char *) sender, 4 );
- mbedtls_sha1_update( &sha1, session->master, 48 );
- mbedtls_sha1_update( &sha1, padbuf, 40 );
- mbedtls_sha1_finish( &sha1, sha1sum );
- memset( padbuf, 0x5C, 48 );
- mbedtls_md5_starts( &md5 );
- mbedtls_md5_update( &md5, session->master, 48 );
- mbedtls_md5_update( &md5, padbuf, 48 );
- mbedtls_md5_update( &md5, md5sum, 16 );
- mbedtls_md5_finish( &md5, buf );
- mbedtls_sha1_starts( &sha1 );
- mbedtls_sha1_update( &sha1, session->master, 48 );
- mbedtls_sha1_update( &sha1, padbuf , 40 );
- mbedtls_sha1_update( &sha1, sha1sum, 20 );
- mbedtls_sha1_finish( &sha1, buf + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
- mbedtls_md5_free( &md5 );
- mbedtls_sha1_free( &sha1 );
- ssl_tls_zeroize( padbuf, sizeof( padbuf ) );
- ssl_tls_zeroize( md5sum, sizeof( md5sum ) );
- ssl_tls_zeroize( sha1sum, sizeof( sha1sum ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
- }
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- static void ssl_calc_finished_tls(
- mbedtls_ssl_context *ssl, unsigned char *buf, int from )
- {
- int len = 12;
- const char *sender;
- mbedtls_md5_context md5;
- mbedtls_sha1_context sha1;
- unsigned char padbuf[36];
- mbedtls_ssl_session *session = ssl->session_negotiate;
- if( !session )
- session = ssl->session;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) );
- mbedtls_md5_init( &md5 );
- mbedtls_sha1_init( &sha1 );
- mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
- mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- /*
- * TLSv1:
- * hash = PRF( master, finished_label,
- * MD5( handshake ) + SHA1( handshake ) )[0..11]
- */
- #if !defined(MBEDTLS_MD5_ALT)
- MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
- md5.state, sizeof( md5.state ) );
- #endif
- #if !defined(MBEDTLS_SHA1_ALT)
- MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
- sha1.state, sizeof( sha1.state ) );
- #endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
- mbedtls_md5_finish( &md5, padbuf );
- mbedtls_sha1_finish( &sha1, padbuf + 16 );
- ssl->handshake->tls_prf( session->master, 48, sender,
- padbuf, 36, buf, len );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_md5_free( &md5 );
- mbedtls_sha1_free( &sha1 );
- ssl_tls_zeroize( padbuf, sizeof( padbuf ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
- }
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- static void ssl_calc_finished_tls_sha256(
- mbedtls_ssl_context *ssl, unsigned char *buf, int from )
- {
- int len = 12;
- const char *sender;
- mbedtls_sha256_context sha256;
- unsigned char padbuf[32];
- mbedtls_ssl_session *session = ssl->session_negotiate;
- if( !session )
- session = ssl->session;
- mbedtls_sha256_init( &sha256 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
- mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
- /*
- * TLSv1.2:
- * hash = PRF( master, finished_label,
- * Hash( handshake ) )[0.11]
- */
- #if !defined(MBEDTLS_SHA256_ALT)
- MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
- sha256.state, sizeof( sha256.state ) );
- #endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
- mbedtls_sha256_finish( &sha256, padbuf );
- ssl->handshake->tls_prf( session->master, 48, sender,
- padbuf, 32, buf, len );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha256_free( &sha256 );
- ssl_tls_zeroize( padbuf, sizeof( padbuf ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
- }
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- static void ssl_calc_finished_tls_sha384(
- mbedtls_ssl_context *ssl, unsigned char *buf, int from )
- {
- int len = 12;
- const char *sender;
- mbedtls_sha512_context sha512;
- unsigned char padbuf[48];
- mbedtls_ssl_session *session = ssl->session_negotiate;
- if( !session )
- session = ssl->session;
- mbedtls_sha512_init( &sha512 );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
- mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
- /*
- * TLSv1.2:
- * hash = PRF( master, finished_label,
- * Hash( handshake ) )[0.11]
- */
- #if !defined(MBEDTLS_SHA512_ALT)
- MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
- sha512.state, sizeof( sha512.state ) );
- #endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
- mbedtls_sha512_finish( &sha512, padbuf );
- ssl->handshake->tls_prf( session->master, 48, sender,
- padbuf, 48, buf, len );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha512_free( &sha512 );
- ssl_tls_zeroize( padbuf, sizeof( padbuf ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
- }
- #endif /* MBEDTLS_SHA512_C */
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
- /*
- * Free our handshake params
- */
- mbedtls_ssl_handshake_free( ssl->handshake );
- mbedtls_free( ssl->handshake );
- ssl->handshake = NULL;
- /*
- * Free the previous transform and swith in the current one
- */
- if( ssl->transform )
- {
- mbedtls_ssl_transform_free( ssl->transform );
- mbedtls_free( ssl->transform );
- }
- ssl->transform = ssl->transform_negotiate;
- ssl->transform_negotiate = NULL;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) );
- }
- void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
- {
- int resume = ssl->handshake->resume;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE;
- ssl->renego_records_seen = 0;
- }
- #endif
- /*
- * Free the previous session and switch in the current one
- */
- if( ssl->session )
- {
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- /* RFC 7366 3.1: keep the EtM state */
- ssl->session_negotiate->encrypt_then_mac =
- ssl->session->encrypt_then_mac;
- #endif
- mbedtls_ssl_session_free( ssl->session );
- mbedtls_free( ssl->session );
- }
- ssl->session = ssl->session_negotiate;
- ssl->session_negotiate = NULL;
- /*
- * Add cache entry
- */
- if( ssl->conf->f_set_cache != NULL &&
- ssl->session->id_len != 0 &&
- resume == 0 )
- {
- if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 )
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->flight != NULL )
- {
- /* Cancel handshake timer */
- ssl_set_timer( ssl, 0 );
- /* Keep last flight around in case we need to resend it:
- * we need the handshake and transform structures for that */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) );
- }
- else
- #endif
- ssl_handshake_wrapup_free_hs_transform( ssl );
- ssl->state++;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
- }
- int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
- {
- int ret, hash_len;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
- /*
- * Set the out_msg pointer to the correct location based on IV length
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
- ssl->transform_negotiate->fixed_ivlen;
- }
- else
- ssl->out_msg = ssl->out_iv;
- ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
- // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
- hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->verify_data_len = hash_len;
- memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
- #endif
- ssl->out_msglen = 4 + hash_len;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED;
- /*
- * In case of session resuming, invert the client and server
- * ChangeCipherSpec messages order.
- */
- if( ssl->handshake->resume != 0 )
- {
- #if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
- #endif
- #if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
- #endif
- }
- else
- ssl->state++;
- /*
- * Switch to our negotiated transform and session parameters for outbound
- * data.
- */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- unsigned char i;
- /* Remember current epoch settings for resending */
- ssl->handshake->alt_transform_out = ssl->transform_out;
- memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 );
- /* Set sequence_number to zero */
- memset( ssl->out_ctr + 2, 0, 6 );
- /* Increment epoch */
- for( i = 2; i > 0; i-- )
- if( ++ssl->out_ctr[i - 1] != 0 )
- break;
- /* The loop goes to its end iff the counter is wrapping */
- if( i == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->out_ctr, 0, 8 );
- ssl->transform_out = ssl->transform_negotiate;
- ssl->session_out = ssl->session_negotiate;
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
- {
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
- #endif
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- mbedtls_ssl_send_flight_completed( ssl );
- #endif
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- #define SSL_MAX_HASH_LEN 36
- #else
- #define SSL_MAX_HASH_LEN 12
- #endif
- int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
- {
- int ret;
- unsigned int hash_len;
- unsigned char buf[SSL_MAX_HASH_LEN];
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
- ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- /* There is currently no ciphersuite using another length with TLS 1.2 */
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- hash_len = 36;
- else
- #endif
- hash_len = 12;
- if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
- ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
- }
- if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
- buf, hash_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
- return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->verify_data_len = hash_len;
- memcpy( ssl->peer_verify_data, buf, hash_len );
- #endif
- if( ssl->handshake->resume != 0 )
- {
- #if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
- #endif
- #if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
- #endif
- }
- else
- ssl->state++;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- mbedtls_ssl_recv_flight_completed( ssl );
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
- return( 0 );
- }
- static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
- {
- memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) );
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_init( &handshake->fin_md5 );
- mbedtls_sha1_init( &handshake->fin_sha1 );
- mbedtls_md5_starts( &handshake->fin_md5 );
- mbedtls_sha1_starts( &handshake->fin_sha1 );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_init( &handshake->fin_sha256 );
- mbedtls_sha256_starts( &handshake->fin_sha256, 0 );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_init( &handshake->fin_sha512 );
- mbedtls_sha512_starts( &handshake->fin_sha512, 1 );
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- handshake->update_checksum = ssl_update_checksum_start;
- handshake->sig_alg = MBEDTLS_SSL_HASH_SHA1;
- #if defined(MBEDTLS_DHM_C)
- mbedtls_dhm_init( &handshake->dhm_ctx );
- #endif
- #if defined(MBEDTLS_ECDH_C)
- mbedtls_ecdh_init( &handshake->ecdh_ctx );
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
- #if defined(MBEDTLS_SSL_CLI_C)
- handshake->ecjpake_cache = NULL;
- handshake->ecjpake_cache_len = 0;
- #endif
- #endif
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
- #endif
- }
- static void ssl_transform_init( mbedtls_ssl_transform *transform )
- {
- memset( transform, 0, sizeof(mbedtls_ssl_transform) );
- mbedtls_cipher_init( &transform->cipher_ctx_enc );
- mbedtls_cipher_init( &transform->cipher_ctx_dec );
- mbedtls_md_init( &transform->md_ctx_enc );
- mbedtls_md_init( &transform->md_ctx_dec );
- }
- void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
- {
- memset( session, 0, sizeof(mbedtls_ssl_session) );
- }
- static int ssl_handshake_init( mbedtls_ssl_context *ssl )
- {
- /* Clear old handshake information if present */
- if( ssl->transform_negotiate )
- mbedtls_ssl_transform_free( ssl->transform_negotiate );
- if( ssl->session_negotiate )
- mbedtls_ssl_session_free( ssl->session_negotiate );
- if( ssl->handshake )
- mbedtls_ssl_handshake_free( ssl->handshake );
- /*
- * Either the pointers are now NULL or cleared properly and can be freed.
- * Now allocate missing structures.
- */
- if( ssl->transform_negotiate == NULL )
- {
- ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) );
- }
- if( ssl->session_negotiate == NULL )
- {
- ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) );
- }
- if( ssl->handshake == NULL )
- {
- ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
- }
- /* All pointers should exist and can be directly freed without issue */
- if( ssl->handshake == NULL ||
- ssl->transform_negotiate == NULL ||
- ssl->session_negotiate == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) );
- mbedtls_free( ssl->handshake );
- mbedtls_free( ssl->transform_negotiate );
- mbedtls_free( ssl->session_negotiate );
- ssl->handshake = NULL;
- ssl->transform_negotiate = NULL;
- ssl->session_negotiate = NULL;
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- /* Initialize structures */
- mbedtls_ssl_session_init( ssl->session_negotiate );
- ssl_transform_init( ssl->transform_negotiate );
- ssl_handshake_params_init( ssl->handshake );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->handshake->alt_transform_out = ssl->transform_out;
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- ssl_set_timer( ssl, 0 );
- }
- #endif
- return( 0 );
- }
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
- /* Dummy cookie callbacks for defaults */
- static int ssl_cookie_write_dummy( void *ctx,
- unsigned char **p, unsigned char *end,
- const unsigned char *cli_id, size_t cli_id_len )
- {
- ((void) ctx);
- ((void) p);
- ((void) end);
- ((void) cli_id);
- ((void) cli_id_len);
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- static int ssl_cookie_check_dummy( void *ctx,
- const unsigned char *cookie, size_t cookie_len,
- const unsigned char *cli_id, size_t cli_id_len )
- {
- ((void) ctx);
- ((void) cookie);
- ((void) cookie_len);
- ((void) cli_id);
- ((void) cli_id_len);
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
- #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
- /*
- * Initialize an SSL context
- */
- void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
- {
- memset( ssl, 0, sizeof( mbedtls_ssl_context ) );
- }
- /*
- * Setup an SSL context
- */
- int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
- const mbedtls_ssl_config *conf )
- {
- int ret;
- const size_t len = MBEDTLS_SSL_BUFFER_LEN;
- ssl->conf = conf;
- /*
- * Prepare base structures
- */
- if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL ||
- ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) );
- mbedtls_free( ssl->in_buf );
- ssl->in_buf = NULL;
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_hdr = ssl->out_buf;
- ssl->out_ctr = ssl->out_buf + 3;
- ssl->out_len = ssl->out_buf + 11;
- ssl->out_iv = ssl->out_buf + 13;
- ssl->out_msg = ssl->out_buf + 13;
- ssl->in_hdr = ssl->in_buf;
- ssl->in_ctr = ssl->in_buf + 3;
- ssl->in_len = ssl->in_buf + 11;
- ssl->in_iv = ssl->in_buf + 13;
- ssl->in_msg = ssl->in_buf + 13;
- }
- else
- #endif
- {
- ssl->out_ctr = ssl->out_buf;
- ssl->out_hdr = ssl->out_buf + 8;
- ssl->out_len = ssl->out_buf + 11;
- ssl->out_iv = ssl->out_buf + 13;
- ssl->out_msg = ssl->out_buf + 13;
- ssl->in_ctr = ssl->in_buf;
- ssl->in_hdr = ssl->in_buf + 8;
- ssl->in_len = ssl->in_buf + 11;
- ssl->in_iv = ssl->in_buf + 13;
- ssl->in_msg = ssl->in_buf + 13;
- }
- if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
- return( ret );
- return( 0 );
- }
- /*
- * Reset an initialized and used SSL context for re-use while retaining
- * all application-set variables, function pointers and data.
- *
- * If partial is non-zero, keep data in the input buffer and client ID.
- * (Use when a DTLS client reconnects from the same port.)
- */
- static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
- {
- int ret;
- ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
- /* Cancel any possibly running timer */
- ssl_set_timer( ssl, 0 );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
- ssl->renego_records_seen = 0;
- ssl->verify_data_len = 0;
- memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
- memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
- #endif
- ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
- ssl->in_offt = NULL;
- ssl->in_msg = ssl->in_buf + 13;
- ssl->in_msgtype = 0;
- ssl->in_msglen = 0;
- if( partial == 0 )
- ssl->in_left = 0;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- ssl->next_record_offset = 0;
- ssl->in_epoch = 0;
- #endif
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- ssl_dtls_replay_reset( ssl );
- #endif
- ssl->in_hslen = 0;
- ssl->nb_zero = 0;
- ssl->record_read = 0;
- ssl->out_msg = ssl->out_buf + 13;
- ssl->out_msgtype = 0;
- ssl->out_msglen = 0;
- ssl->out_left = 0;
- #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED )
- ssl->split_done = 0;
- #endif
- ssl->transform_in = NULL;
- ssl->transform_out = NULL;
- memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
- if( partial == 0 )
- memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_reset != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) );
- if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
- #endif
- if( ssl->transform )
- {
- mbedtls_ssl_transform_free( ssl->transform );
- mbedtls_free( ssl->transform );
- ssl->transform = NULL;
- }
- if( ssl->session )
- {
- mbedtls_ssl_session_free( ssl->session );
- mbedtls_free( ssl->session );
- ssl->session = NULL;
- }
- #if defined(MBEDTLS_SSL_ALPN)
- ssl->alpn_chosen = NULL;
- #endif
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
- if( partial == 0 )
- {
- mbedtls_free( ssl->cli_id );
- ssl->cli_id = NULL;
- ssl->cli_id_len = 0;
- }
- #endif
- if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
- return( ret );
- return( 0 );
- }
- /*
- * Reset an initialized and used SSL context for re-use while retaining
- * all application-set variables, function pointers and data.
- */
- int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
- {
- return( ssl_session_reset_int( ssl, 0 ) );
- }
- /*
- * SSL set accessors
- */
- void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint )
- {
- conf->endpoint = endpoint;
- }
- void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
- {
- conf->transport = transport;
- }
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode )
- {
- conf->anti_replay = mode;
- }
- #endif
- #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
- void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit )
- {
- conf->badmac_limit = limit;
- }
- #endif
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max )
- {
- conf->hs_timeout_min = min;
- conf->hs_timeout_max = max;
- }
- #endif
- void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode )
- {
- conf->authmode = authmode;
- }
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
- {
- conf->f_vrfy = f_vrfy;
- conf->p_vrfy = p_vrfy;
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- conf->f_rng = f_rng;
- conf->p_rng = p_rng;
- }
- void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
- void (*f_dbg)(void *, int, const char *, int, const char *),
- void *p_dbg )
- {
- conf->f_dbg = f_dbg;
- conf->p_dbg = p_dbg;
- }
- void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
- void *p_bio,
- int (*f_send)(void *, const unsigned char *, size_t),
- int (*f_recv)(void *, unsigned char *, size_t),
- int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) )
- {
- ssl->p_bio = p_bio;
- ssl->f_send = f_send;
- ssl->f_recv = f_recv;
- ssl->f_recv_timeout = f_recv_timeout;
- }
- void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout )
- {
- conf->read_timeout = timeout;
- }
- void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
- void *p_timer,
- void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms),
- int (*f_get_timer)(void *) )
- {
- ssl->p_timer = p_timer;
- ssl->f_set_timer = f_set_timer;
- ssl->f_get_timer = f_get_timer;
- /* Make sure we start with no timer running */
- ssl_set_timer( ssl, 0 );
- }
- #if defined(MBEDTLS_SSL_SRV_C)
- void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
- void *p_cache,
- int (*f_get_cache)(void *, mbedtls_ssl_session *),
- int (*f_set_cache)(void *, const mbedtls_ssl_session *) )
- {
- conf->p_cache = p_cache;
- conf->f_get_cache = f_get_cache;
- conf->f_set_cache = f_set_cache;
- }
- #endif /* MBEDTLS_SSL_SRV_C */
- #if defined(MBEDTLS_SSL_CLI_C)
- int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session )
- {
- int ret;
- if( ssl == NULL ||
- session == NULL ||
- ssl->session_negotiate == NULL ||
- ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
- {
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 )
- return( ret );
- ssl->handshake->resume = 1;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_CLI_C */
- void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
- const int *ciphersuites )
- {
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
- }
- void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
- const int *ciphersuites,
- int major, int minor )
- {
- if( major != MBEDTLS_SSL_MAJOR_VERSION_3 )
- return;
- if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 )
- return;
- conf->ciphersuite_list[minor] = ciphersuites;
- }
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
- const mbedtls_x509_crt_profile *profile )
- {
- conf->cert_profile = profile;
- }
- /* Append a new keycert entry to a (possibly empty) list */
- static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
- mbedtls_x509_crt *cert,
- mbedtls_pk_context *key )
- {
- mbedtls_ssl_key_cert *new;
- new = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) );
- if( new == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- new->cert = cert;
- new->key = key;
- new->next = NULL;
- /* Update head is the list was null, else add to the end */
- if( *head == NULL )
- {
- *head = new;
- }
- else
- {
- mbedtls_ssl_key_cert *cur = *head;
- while( cur->next != NULL )
- cur = cur->next;
- cur->next = new;
- }
- return( 0 );
- }
- int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
- mbedtls_x509_crt *own_cert,
- mbedtls_pk_context *pk_key )
- {
- return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) );
- }
- void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
- mbedtls_x509_crt *ca_chain,
- mbedtls_x509_crl *ca_crl )
- {
- conf->ca_chain = ca_chain;
- conf->ca_crl = ca_crl;
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
- mbedtls_x509_crt *own_cert,
- mbedtls_pk_context *pk_key )
- {
- return( ssl_append_key_cert( &ssl->handshake->sni_key_cert,
- own_cert, pk_key ) );
- }
- void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
- mbedtls_x509_crt *ca_chain,
- mbedtls_x509_crl *ca_crl )
- {
- ssl->handshake->sni_ca_chain = ca_chain;
- ssl->handshake->sni_ca_crl = ca_crl;
- }
- void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
- int authmode )
- {
- ssl->handshake->sni_authmode = authmode;
- }
- #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- /*
- * Set EC J-PAKE password for current handshake
- */
- int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
- const unsigned char *pw,
- size_t pw_len )
- {
- mbedtls_ecjpake_role role;
- if( ssl->handshake == NULL && ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- role = MBEDTLS_ECJPAKE_SERVER;
- else
- role = MBEDTLS_ECJPAKE_CLIENT;
- return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx,
- role,
- MBEDTLS_MD_SHA256,
- MBEDTLS_ECP_DP_SECP256R1,
- pw, pw_len ) );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
- const unsigned char *psk, size_t psk_len,
- const unsigned char *psk_identity, size_t psk_identity_len )
- {
- if( psk == NULL || psk_identity == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( psk_len > MBEDTLS_PSK_MAX_LEN )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /* Identity len will be encoded on two bytes */
- if( ( psk_identity_len >> 16 ) != 0 ||
- psk_identity_len > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- if( conf->psk != NULL || conf->psk_identity != NULL )
- {
- mbedtls_free( conf->psk );
- mbedtls_free( conf->psk_identity );
- conf->psk = NULL;
- conf->psk_identity = NULL;
- }
- if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
- ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL )
- {
- mbedtls_free( conf->psk );
- mbedtls_free( conf->psk_identity );
- conf->psk = NULL;
- conf->psk_identity = NULL;
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- conf->psk_len = psk_len;
- conf->psk_identity_len = psk_identity_len;
- memcpy( conf->psk, psk, conf->psk_len );
- memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
- return( 0 );
- }
- int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
- const unsigned char *psk, size_t psk_len )
- {
- if( psk == NULL || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( psk_len > MBEDTLS_PSK_MAX_LEN )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ssl->handshake->psk != NULL )
- mbedtls_free( ssl->handshake->psk );
- if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- ssl->handshake->psk_len = psk_len;
- memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
- return( 0 );
- }
- void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
- int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
- size_t),
- void *p_psk )
- {
- conf->f_psk = f_psk;
- conf->p_psk = p_psk;
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
- #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
- int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
- {
- int ret;
- if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
- ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
- {
- mbedtls_mpi_free( &conf->dhm_P );
- mbedtls_mpi_free( &conf->dhm_G );
- return( ret );
- }
- return( 0 );
- }
- int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
- {
- int ret;
- if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
- ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
- {
- mbedtls_mpi_free( &conf->dhm_P );
- mbedtls_mpi_free( &conf->dhm_G );
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */
- #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
- /*
- * Set the minimum length for Diffie-Hellman parameters
- */
- void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
- unsigned int bitlen )
- {
- conf->dhm_min_bitlen = bitlen;
- }
- #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
- #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- /*
- * Set allowed/preferred hashes for handshake signatures
- */
- void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
- const int *hashes )
- {
- conf->sig_hashes = hashes;
- }
- #endif
- #if defined(MBEDTLS_ECP_C)
- /*
- * Set the allowed elliptic curves
- */
- void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
- const mbedtls_ecp_group_id *curve_list )
- {
- conf->curve_list = curve_list;
- }
- #endif
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
- {
- size_t hostname_len;
- if( hostname == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- hostname_len = strlen( hostname );
- if( hostname_len + 1 == 0 )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 );
- if( ssl->hostname == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( ssl->hostname, hostname, hostname_len );
- ssl->hostname[hostname_len] = '\0';
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
- int (*f_sni)(void *, mbedtls_ssl_context *,
- const unsigned char *, size_t),
- void *p_sni )
- {
- conf->f_sni = f_sni;
- conf->p_sni = p_sni;
- }
- #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
- #if defined(MBEDTLS_SSL_ALPN)
- int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos )
- {
- size_t cur_len, tot_len;
- const char **p;
- /*
- * "Empty strings MUST NOT be included and byte strings MUST NOT be
- * truncated". Check lengths now rather than later.
- */
- tot_len = 0;
- for( p = protos; *p != NULL; p++ )
- {
- cur_len = strlen( *p );
- tot_len += cur_len;
- if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- conf->alpn_list = protos;
- return( 0 );
- }
- const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
- {
- return( ssl->alpn_chosen );
- }
- #endif /* MBEDTLS_SSL_ALPN */
- void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
- {
- conf->max_major_ver = major;
- conf->max_minor_ver = minor;
- }
- void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor )
- {
- conf->min_major_ver = major;
- conf->min_minor_ver = minor;
- }
- #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
- void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback )
- {
- conf->fallback = fallback;
- }
- #endif
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm )
- {
- conf->encrypt_then_mac = etm;
- }
- #endif
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems )
- {
- conf->extended_ms = ems;
- }
- #endif
- #if defined(MBEDTLS_ARC4_C)
- void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 )
- {
- conf->arc4_disabled = arc4;
- }
- #endif
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code )
- {
- if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
- mfl_code_to_length[mfl_code] > MBEDTLS_SSL_MAX_CONTENT_LEN )
- {
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- conf->mfl_code = mfl_code;
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
- {
- conf->trunc_hmac = truncate;
- }
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split )
- {
- conf->cbc_record_splitting = split;
- }
- #endif
- void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy )
- {
- conf->allow_legacy_renegotiation = allow_legacy;
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation )
- {
- conf->disable_renegotiation = renegotiation;
- }
- void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records )
- {
- conf->renego_max_records = max_records;
- }
- void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
- const unsigned char period[8] )
- {
- memcpy( conf->renego_period, period, 8 );
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- #if defined(MBEDTLS_SSL_CLI_C)
- void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets )
- {
- conf->session_tickets = use_tickets;
- }
- #endif
- #if defined(MBEDTLS_SSL_SRV_C)
- void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
- mbedtls_ssl_ticket_write_t *f_ticket_write,
- mbedtls_ssl_ticket_parse_t *f_ticket_parse,
- void *p_ticket )
- {
- conf->f_ticket_write = f_ticket_write;
- conf->f_ticket_parse = f_ticket_parse;
- conf->p_ticket = p_ticket;
- }
- #endif
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_SSL_EXPORT_KEYS)
- void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
- mbedtls_ssl_export_keys_t *f_export_keys,
- void *p_export_keys )
- {
- conf->f_export_keys = f_export_keys;
- conf->p_export_keys = p_export_keys;
- }
- #endif
- /*
- * SSL get accessors
- */
- size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
- {
- return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
- }
- uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
- {
- if( ssl->session != NULL )
- return( ssl->session->verify_result );
- if( ssl->session_negotiate != NULL )
- return( ssl->session_negotiate->verify_result );
- return( 0xFFFFFFFF );
- }
- const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl )
- {
- if( ssl == NULL || ssl->session == NULL )
- return( NULL );
- return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite );
- }
- const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- switch( ssl->minor_ver )
- {
- case MBEDTLS_SSL_MINOR_VERSION_2:
- return( "DTLSv1.0" );
- case MBEDTLS_SSL_MINOR_VERSION_3:
- return( "DTLSv1.2" );
- default:
- return( "unknown (DTLS)" );
- }
- }
- #endif
- switch( ssl->minor_ver )
- {
- case MBEDTLS_SSL_MINOR_VERSION_0:
- return( "SSLv3.0" );
- case MBEDTLS_SSL_MINOR_VERSION_1:
- return( "TLSv1.0" );
- case MBEDTLS_SSL_MINOR_VERSION_2:
- return( "TLSv1.1" );
- case MBEDTLS_SSL_MINOR_VERSION_3:
- return( "TLSv1.2" );
- default:
- return( "unknown" );
- }
- }
- int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
- {
- size_t transform_expansion;
- const mbedtls_ssl_transform *transform = ssl->transform_out;
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- #endif
- if( transform == NULL )
- return( (int) mbedtls_ssl_hdr_len( ssl ) );
- switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
- {
- case MBEDTLS_MODE_GCM:
- case MBEDTLS_MODE_CCM:
- case MBEDTLS_MODE_STREAM:
- transform_expansion = transform->minlen;
- break;
- case MBEDTLS_MODE_CBC:
- transform_expansion = transform->maclen
- + mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc );
- break;
- default:
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) );
- }
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
- {
- size_t max_len;
- /*
- * Assume mfl_code is correct since it was checked when set
- */
- max_len = mfl_code_to_length[ssl->conf->mfl_code];
- /*
- * Check if a smaller max length was negotiated
- */
- if( ssl->session_out != NULL &&
- mfl_code_to_length[ssl->session_out->mfl_code] < max_len )
- {
- max_len = mfl_code_to_length[ssl->session_out->mfl_code];
- }
- return max_len;
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl )
- {
- if( ssl == NULL || ssl->session == NULL )
- return( NULL );
- return( ssl->session->peer_cert );
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- #if defined(MBEDTLS_SSL_CLI_C)
- int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst )
- {
- if( ssl == NULL ||
- dst == NULL ||
- ssl->session == NULL ||
- ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
- {
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- return( ssl_session_copy( dst, ssl->session ) );
- }
- #endif /* MBEDTLS_SSL_CLI_C */
- /*
- * Perform a single step of the SSL handshake
- */
- int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- #if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- ret = mbedtls_ssl_handshake_client_step( ssl );
- #endif
- #if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- ret = mbedtls_ssl_handshake_server_step( ssl );
- #endif
- return( ret );
- }
- /*
- * Perform the SSL handshake
- */
- int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
- {
- int ret = 0;
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
- while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- ret = mbedtls_ssl_handshake_step( ssl );
- if( ret != 0 )
- break;
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) );
- return( ret );
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- #if defined(MBEDTLS_SSL_SRV_C)
- /*
- * Write HelloRequest to request renegotiation on server
- */
- static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
- ssl->out_msglen = 4;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST;
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
- return( 0 );
- }
- #endif /* MBEDTLS_SSL_SRV_C */
- /*
- * Actually renegotiate current connection, triggered by either:
- * - any side: calling mbedtls_ssl_renegotiate(),
- * - client: receiving a HelloRequest during mbedtls_ssl_read(),
- * - server: receiving any handshake message on server during mbedtls_ssl_read() after
- * the initial handshake is completed.
- * If the handshake doesn't complete due to waiting for I/O, it will continue
- * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
- */
- static int ssl_start_renegotiation( mbedtls_ssl_context *ssl )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
- if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
- return( ret );
- /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
- * the ServerHello will have message_seq = 1" */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- ssl->handshake->out_msg_seq = 1;
- else
- ssl->handshake->in_msg_seq = 1;
- }
- #endif
- ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
- ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
- if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) );
- return( 0 );
- }
- /*
- * Renegotiate current connection on client,
- * or request renegotiation on server
- */
- int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
- {
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- #if defined(MBEDTLS_SSL_SRV_C)
- /* On server, just send the request */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
- {
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
- /* Did we already try/start sending HelloRequest? */
- if( ssl->out_left != 0 )
- return( mbedtls_ssl_flush_output( ssl ) );
- return( ssl_write_hello_request( ssl ) );
- }
- #endif /* MBEDTLS_SSL_SRV_C */
- #if defined(MBEDTLS_SSL_CLI_C)
- /*
- * On client, either start the renegotiation process or,
- * if already in progress, continue the handshake
- */
- if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
- return( ret );
- }
- }
- else
- {
- if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
- }
- }
- #endif /* MBEDTLS_SSL_CLI_C */
- return( ret );
- }
- /*
- * Check record counters and renegotiate if they're above the limit.
- */
- static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
- {
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
- ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
- {
- return( 0 );
- }
- if( memcmp( ssl->in_ctr, ssl->conf->renego_period, 8 ) <= 0 &&
- memcmp( ssl->out_ctr, ssl->conf->renego_period, 8 ) <= 0 )
- {
- return( 0 );
- }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
- return( mbedtls_ssl_renegotiate( ssl ) );
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- /*
- * Receive application data decrypted from the SSL layer
- */
- int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
- {
- int ret, record_read = 0;
- size_t n;
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
- if( ssl->handshake != NULL &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- return( ret );
- }
- }
- #endif
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
- return( ret );
- }
- #endif
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- ret = mbedtls_ssl_handshake( ssl );
- if( ret == MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
- {
- record_read = 1;
- }
- else if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
- }
- }
- if( ssl->in_offt == NULL )
- {
- /* Start timer if not already running */
- if( ssl->f_get_timer != NULL &&
- ssl->f_get_timer( ssl->p_timer ) == -1 )
- {
- ssl_set_timer( ssl, ssl->conf->read_timeout );
- }
- if( ! record_read )
- {
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
- return( 0 );
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- }
- if( ssl->in_msglen == 0 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- /*
- * OpenSSL sends empty messages to randomize the IV
- */
- if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
- return( 0 );
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- }
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
- #if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
- ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
- /* With DTLS, drop the packet (probably from last handshake) */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- #endif
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
- /* With DTLS, drop the packet (probably from last handshake) */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- #endif
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- #endif
- if( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
- ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation ==
- MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /*
- * SSLv3 does not have a "no_renegotiation" alert
- */
- if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
- return( ret );
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_WARNING,
- MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
- {
- return( ret );
- }
- }
- else
- #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
- {
- /* DTLS clients need to know renego is server-initiated */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- {
- ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
- }
- #endif
- ret = ssl_start_renegotiation( ssl );
- if( ret == MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
- {
- record_read = 1;
- }
- else if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
- return( ret );
- }
- }
- /* If a non-handshake record was read during renego, fallthrough,
- * else tell the user they should call mbedtls_ssl_read() again */
- if( ! record_read )
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ssl->conf->renego_max_records >= 0 )
- {
- if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
- "but not honored by client" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- }
- }
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- ssl->in_offt = ssl->in_msg;
- /* We're going to return something now, cancel timer,
- * except if handshake (renegotiation) is in progress */
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- ssl_set_timer( ssl, 0 );
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* If we requested renego but received AppData, resend HelloRequest.
- * Do it now, after setting in_offt, to avoid taking this branch
- * again if ssl_write_hello_request() returns WANT_WRITE */
- #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
- return( ret );
- }
- }
- #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
- #endif
- }
- n = ( len < ssl->in_msglen )
- ? len : ssl->in_msglen;
- memcpy( buf, ssl->in_offt, n );
- ssl->in_msglen -= n;
- if( ssl->in_msglen == 0 )
- /* all bytes consumed */
- ssl->in_offt = NULL;
- else
- /* more data available */
- ssl->in_offt += n;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
- return( (int) n );
- }
- /*
- * Send application data to be encrypted by the SSL layer,
- * taking care of max fragment length and buffer size
- */
- static int ssl_write_real( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- int ret;
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- size_t max_len = mbedtls_ssl_get_max_frag_len( ssl );
- if( len > max_len )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
- "maximum fragment length: %d > %d",
- len, max_len ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- else
- #endif
- len = max_len;
- }
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- if( ssl->out_left != 0 )
- {
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
- return( ret );
- }
- }
- else
- {
- ssl->out_msglen = len;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
- memcpy( ssl->out_msg, buf, len );
- if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- }
- return( (int) len );
- }
- /*
- * Write application data, doing 1/n-1 splitting if necessary.
- *
- * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
- * then the caller will call us again with the same arguments, so
- * remember wether we already did the split or not.
- */
- #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- static int ssl_write_split( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
- {
- int ret;
- if( ssl->conf->cbc_record_splitting ==
- MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
- len <= 1 ||
- ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
- mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
- != MBEDTLS_MODE_CBC )
- {
- return( ssl_write_real( ssl, buf, len ) );
- }
- if( ssl->split_done == 0 )
- {
- if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
- return( ret );
- ssl->split_done = 1;
- }
- if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
- return( ret );
- ssl->split_done = 0;
- return( ret + 1 );
- }
- #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
- /*
- * Write application data (public-facing wrapper)
- */
- int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
- {
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
- return( ret );
- }
- #endif
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
- }
- }
- #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- ret = ssl_write_split( ssl, buf, len );
- #else
- ret = ssl_write_real( ssl, buf, len );
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
- return( ret );
- }
- /*
- * Notify the peer that the connection is being closed
- */
- int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
- {
- int ret;
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
- if( ssl->out_left != 0 )
- return( mbedtls_ssl_flush_output( ssl ) );
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_WARNING,
- MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
- return( ret );
- }
- }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
- return( 0 );
- }
- void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
- {
- if( transform == NULL )
- return;
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- deflateEnd( &transform->ctx_deflate );
- inflateEnd( &transform->ctx_inflate );
- #endif
- mbedtls_cipher_free( &transform->cipher_ctx_enc );
- mbedtls_cipher_free( &transform->cipher_ctx_dec );
- mbedtls_md_free( &transform->md_ctx_enc );
- mbedtls_md_free( &transform->md_ctx_dec );
- ssl_tls_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
- }
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
- {
- mbedtls_ssl_key_cert *cur = key_cert, *next;
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake )
- {
- if( handshake == NULL )
- return;
- #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_free( &handshake->fin_md5 );
- mbedtls_sha1_free( &handshake->fin_sha1 );
- #endif
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- #if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_free( &handshake->fin_sha256 );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_free( &handshake->fin_sha512 );
- #endif
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_DHM_C)
- mbedtls_dhm_free( &handshake->dhm_ctx );
- #endif
- #if defined(MBEDTLS_ECDH_C)
- mbedtls_ecdh_free( &handshake->ecdh_ctx );
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
- #if defined(MBEDTLS_SSL_CLI_C)
- mbedtls_free( handshake->ecjpake_cache );
- handshake->ecjpake_cache = NULL;
- handshake->ecjpake_cache_len = 0;
- #endif
- #endif
- #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
- /* explicit void pointer cast for buggy MS compiler */
- mbedtls_free( (void *) handshake->curves );
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- if( handshake->psk != NULL )
- {
- ssl_tls_zeroize( handshake->psk, handshake->psk_len );
- mbedtls_free( handshake->psk );
- }
- #endif
- #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
- defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- /*
- * Free only the linked list wrapper, not the keys themselves
- * since the belong to the SNI callback
- */
- if( handshake->sni_key_cert != NULL )
- {
- mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- mbedtls_free( handshake->verify_cookie );
- mbedtls_free( handshake->hs_msg );
- ssl_flight_free( handshake->flight );
- #endif
- ssl_tls_zeroize( handshake, sizeof( mbedtls_ssl_handshake_params ) );
- }
- void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
- {
- if( session == NULL )
- return;
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( session->peer_cert != NULL )
- {
- mbedtls_x509_crt_free( session->peer_cert );
- mbedtls_free( session->peer_cert );
- }
- #endif
- #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
- mbedtls_free( session->ticket );
- #endif
- ssl_tls_zeroize( session, sizeof( mbedtls_ssl_session ) );
- }
- /*
- * Free an SSL context
- */
- void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
- {
- if( ssl == NULL )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) );
- if( ssl->out_buf != NULL )
- {
- ssl_tls_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN );
- mbedtls_free( ssl->out_buf );
- }
- if( ssl->in_buf != NULL )
- {
- ssl_tls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN );
- mbedtls_free( ssl->in_buf );
- }
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->compress_buf != NULL )
- {
- ssl_tls_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN );
- mbedtls_free( ssl->compress_buf );
- }
- #endif
- if( ssl->transform )
- {
- mbedtls_ssl_transform_free( ssl->transform );
- mbedtls_free( ssl->transform );
- }
- if( ssl->handshake )
- {
- mbedtls_ssl_handshake_free( ssl->handshake );
- mbedtls_ssl_transform_free( ssl->transform_negotiate );
- mbedtls_ssl_session_free( ssl->session_negotiate );
- mbedtls_free( ssl->handshake );
- mbedtls_free( ssl->transform_negotiate );
- mbedtls_free( ssl->session_negotiate );
- }
- if( ssl->session )
- {
- mbedtls_ssl_session_free( ssl->session );
- mbedtls_free( ssl->session );
- }
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( ssl->hostname != NULL )
- {
- ssl_tls_zeroize( ssl->hostname, strlen( ssl->hostname ) );
- mbedtls_free( ssl->hostname );
- }
- #endif
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_finish != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) );
- mbedtls_ssl_hw_record_finish( ssl );
- }
- #endif
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
- mbedtls_free( ssl->cli_id );
- #endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
- /* Actually clear after last debug message */
- ssl_tls_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
- }
- /*
- * Initialze mbedtls_ssl_config
- */
- void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
- {
- memset( conf, 0, sizeof( mbedtls_ssl_config ) );
- }
- #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- static int ssl_preset_default_hashes[] = {
- #if defined(MBEDTLS_SHA512_C)
- MBEDTLS_MD_SHA512,
- MBEDTLS_MD_SHA384,
- #endif
- #if defined(MBEDTLS_SHA256_C)
- MBEDTLS_MD_SHA256,
- MBEDTLS_MD_SHA224,
- #endif
- #if defined(MBEDTLS_SHA1_C)
- MBEDTLS_MD_SHA1,
- #endif
- MBEDTLS_MD_NONE
- };
- #endif
- static int ssl_preset_suiteb_ciphersuites[] = {
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
- 0
- };
- #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- static int ssl_preset_suiteb_hashes[] = {
- MBEDTLS_MD_SHA256,
- MBEDTLS_MD_SHA384,
- MBEDTLS_MD_NONE
- };
- #endif
- #if defined(MBEDTLS_ECP_C)
- static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
- MBEDTLS_ECP_DP_SECP256R1,
- MBEDTLS_ECP_DP_SECP384R1,
- MBEDTLS_ECP_DP_NONE
- };
- #endif
- /*
- * Load default in mbedtls_ssl_config
- */
- int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
- int endpoint, int transport, int preset )
- {
- #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
- int ret;
- #endif
- /* Use the functions here so that they are covered in tests,
- * but otherwise access member directly for efficiency */
- mbedtls_ssl_conf_endpoint( conf, endpoint );
- mbedtls_ssl_conf_transport( conf, transport );
- /*
- * Things that are common to all presets
- */
- #if defined(MBEDTLS_SSL_CLI_C)
- if( endpoint == MBEDTLS_SSL_IS_CLIENT )
- {
- conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
- #endif
- }
- #endif
- #if defined(MBEDTLS_ARC4_C)
- conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
- #endif
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
- #endif
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
- #endif
- #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
- #endif
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
- conf->f_cookie_write = ssl_cookie_write_dummy;
- conf->f_cookie_check = ssl_cookie_check_dummy;
- #endif
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
- #endif
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
- conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
- #endif
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
- memset( conf->renego_period, 0xFF, 7 );
- conf->renego_period[7] = 0x00;
- #endif
- #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
- if( endpoint == MBEDTLS_SSL_IS_SERVER )
- {
- if( ( ret = mbedtls_ssl_conf_dh_param( conf,
- MBEDTLS_DHM_RFC5114_MODP_2048_P,
- MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 )
- {
- return( ret );
- }
- }
- #endif
- /*
- * Preset-specific defaults
- */
- switch( preset )
- {
- /*
- * NSA Suite B
- */
- case MBEDTLS_SSL_PRESET_SUITEB:
- conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
- conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
- conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
- conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
- ssl_preset_suiteb_ciphersuites;
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- conf->sig_hashes = ssl_preset_suiteb_hashes;
- #endif
- #if defined(MBEDTLS_ECP_C)
- conf->curve_list = ssl_preset_suiteb_curves;
- #endif
- break;
- /*
- * Default
- */
- default:
- conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
- conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */
- conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
- conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
- #endif
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
- conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
- mbedtls_ssl_list_ciphersuites();
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- conf->cert_profile = &mbedtls_x509_crt_profile_default;
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- conf->sig_hashes = ssl_preset_default_hashes;
- #endif
- #if defined(MBEDTLS_ECP_C)
- conf->curve_list = mbedtls_ecp_grp_id_list();
- #endif
- #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
- conf->dhm_min_bitlen = 1024;
- #endif
- }
- return( 0 );
- }
- /*
- * Free mbedtls_ssl_config
- */
- void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
- {
- #if defined(MBEDTLS_DHM_C)
- mbedtls_mpi_free( &conf->dhm_P );
- mbedtls_mpi_free( &conf->dhm_G );
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- if( conf->psk != NULL )
- {
- ssl_tls_zeroize( conf->psk, conf->psk_len );
- ssl_tls_zeroize( conf->psk_identity, conf->psk_identity_len );
- mbedtls_free( conf->psk );
- mbedtls_free( conf->psk_identity );
- conf->psk_len = 0;
- conf->psk_identity_len = 0;
- }
- #endif
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- ssl_key_cert_free( conf->key_cert );
- #endif
- ssl_tls_zeroize( conf, sizeof( mbedtls_ssl_config ) );
- }
- #if defined(MBEDTLS_PK_C) && \
- ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) )
- /*
- * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
- */
- unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk )
- {
- #if defined(MBEDTLS_RSA_C)
- if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) )
- return( MBEDTLS_SSL_SIG_RSA );
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) )
- return( MBEDTLS_SSL_SIG_ECDSA );
- #endif
- return( MBEDTLS_SSL_SIG_ANON );
- }
- mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
- {
- switch( sig )
- {
- #if defined(MBEDTLS_RSA_C)
- case MBEDTLS_SSL_SIG_RSA:
- return( MBEDTLS_PK_RSA );
- #endif
- #if defined(MBEDTLS_ECDSA_C)
- case MBEDTLS_SSL_SIG_ECDSA:
- return( MBEDTLS_PK_ECDSA );
- #endif
- default:
- return( MBEDTLS_PK_NONE );
- }
- }
- #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
- /*
- * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
- */
- mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash )
- {
- switch( hash )
- {
- #if defined(MBEDTLS_MD5_C)
- case MBEDTLS_SSL_HASH_MD5:
- return( MBEDTLS_MD_MD5 );
- #endif
- #if defined(MBEDTLS_SHA1_C)
- case MBEDTLS_SSL_HASH_SHA1:
- return( MBEDTLS_MD_SHA1 );
- #endif
- #if defined(MBEDTLS_SHA256_C)
- case MBEDTLS_SSL_HASH_SHA224:
- return( MBEDTLS_MD_SHA224 );
- case MBEDTLS_SSL_HASH_SHA256:
- return( MBEDTLS_MD_SHA256 );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- case MBEDTLS_SSL_HASH_SHA384:
- return( MBEDTLS_MD_SHA384 );
- case MBEDTLS_SSL_HASH_SHA512:
- return( MBEDTLS_MD_SHA512 );
- #endif
- default:
- return( MBEDTLS_MD_NONE );
- }
- }
- /*
- * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
- */
- unsigned char mbedtls_ssl_hash_from_md_alg( int md )
- {
- switch( md )
- {
- #if defined(MBEDTLS_MD5_C)
- case MBEDTLS_MD_MD5:
- return( MBEDTLS_SSL_HASH_MD5 );
- #endif
- #if defined(MBEDTLS_SHA1_C)
- case MBEDTLS_MD_SHA1:
- return( MBEDTLS_SSL_HASH_SHA1 );
- #endif
- #if defined(MBEDTLS_SHA256_C)
- case MBEDTLS_MD_SHA224:
- return( MBEDTLS_SSL_HASH_SHA224 );
- case MBEDTLS_MD_SHA256:
- return( MBEDTLS_SSL_HASH_SHA256 );
- #endif
- #if defined(MBEDTLS_SHA512_C)
- case MBEDTLS_MD_SHA384:
- return( MBEDTLS_SSL_HASH_SHA384 );
- case MBEDTLS_MD_SHA512:
- return( MBEDTLS_SSL_HASH_SHA512 );
- #endif
- default:
- return( MBEDTLS_SSL_HASH_NONE );
- }
- }
- #if defined(MBEDTLS_ECP_C)
- /*
- * Check if a curve proposed by the peer is in our list.
- * Return 0 if we're willing to use it, -1 otherwise.
- */
- int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
- {
- const mbedtls_ecp_group_id *gid;
- if( ssl->conf->curve_list == NULL )
- return( -1 );
- for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
- if( *gid == grp_id )
- return( 0 );
- return( -1 );
- }
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
- /*
- * Check if a hash proposed by the peer is in our list.
- * Return 0 if we're willing to use it, -1 otherwise.
- */
- int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
- mbedtls_md_type_t md )
- {
- const int *cur;
- if( ssl->conf->sig_hashes == NULL )
- return( -1 );
- for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
- if( *cur == (int) md )
- return( 0 );
- return( -1 );
- }
- #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
- const mbedtls_ssl_ciphersuite_t *ciphersuite,
- int cert_endpoint,
- uint32_t *flags )
- {
- int ret = 0;
- #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- int usage = 0;
- #endif
- #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
- const char *ext_oid;
- size_t ext_len;
- #endif
- #if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \
- !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
- ((void) cert);
- ((void) cert_endpoint);
- ((void) flags);
- #endif
- #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
- {
- /* Server part of the key exchange */
- switch( ciphersuite->key_exchange )
- {
- case MBEDTLS_KEY_EXCHANGE_RSA:
- case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
- usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
- break;
- case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
- usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
- break;
- case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
- case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
- usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
- break;
- /* Don't use default: we want warnings when adding new values */
- case MBEDTLS_KEY_EXCHANGE_NONE:
- case MBEDTLS_KEY_EXCHANGE_PSK:
- case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
- case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
- case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
- usage = 0;
- }
- }
- else
- {
- /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
- usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
- }
- if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 )
- {
- *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
- ret = -1;
- }
- #else
- ((void) ciphersuite);
- #endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
- #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
- if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
- {
- ext_oid = MBEDTLS_OID_SERVER_AUTH;
- ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
- }
- else
- {
- ext_oid = MBEDTLS_OID_CLIENT_AUTH;
- ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
- }
- if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
- {
- *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
- ret = -1;
- }
- #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
- return( ret );
- }
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- /*
- * Convert version numbers to/from wire format
- * and, for DTLS, to/from TLS equivalent.
- *
- * For TLS this is the identity.
- * For DTLS, use one complement (v -> 255 - v, and then map as follows:
- * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
- * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
- */
- void mbedtls_ssl_write_version( int major, int minor, int transport,
- unsigned char ver[2] )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
- --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
- ver[0] = (unsigned char)( 255 - ( major - 2 ) );
- ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
- }
- else
- #else
- ((void) transport);
- #endif
- {
- ver[0] = (unsigned char) major;
- ver[1] = (unsigned char) minor;
- }
- }
- void mbedtls_ssl_read_version( int *major, int *minor, int transport,
- const unsigned char ver[2] )
- {
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- *major = 255 - ver[0] + 2;
- *minor = 255 - ver[1] + 1;
- if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
- ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
- }
- else
- #else
- ((void) transport);
- #endif
- {
- *major = ver[0];
- *minor = ver[1];
- }
- }
- #endif /* MBEDTLS_SSL_TLS_C */
- /********* Start of file library/threading.c ************/
- /*
- * Threading abstraction layer
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_THREADING_C)
- #if defined(MBEDTLS_THREADING_PTHREAD)
- static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
- {
- if( mutex == NULL )
- return;
- mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
- }
- static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex )
- {
- if( mutex == NULL )
- return;
- (void) pthread_mutex_destroy( &mutex->mutex );
- }
- static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex )
- {
- if( mutex == NULL || ! mutex->is_valid )
- return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
- if( pthread_mutex_lock( &mutex->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- return( 0 );
- }
- static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex )
- {
- if( mutex == NULL || ! mutex->is_valid )
- return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
- if( pthread_mutex_unlock( &mutex->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- return( 0 );
- }
- void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread;
- void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread;
- int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread;
- int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread;
- /*
- * With phtreads we can statically initialize mutexes
- */
- #define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 }
- #endif /* MBEDTLS_THREADING_PTHREAD */
- #if defined(MBEDTLS_THREADING_ALT)
- static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex )
- {
- ((void) mutex );
- return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
- }
- static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex )
- {
- ((void) mutex );
- return;
- }
- void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
- void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
- int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
- int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
- /*
- * Set functions pointers and initialize global mutexes
- */
- void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
- void (*mutex_free)( mbedtls_threading_mutex_t * ),
- int (*mutex_lock)( mbedtls_threading_mutex_t * ),
- int (*mutex_unlock)( mbedtls_threading_mutex_t * ) )
- {
- mbedtls_mutex_init = mutex_init;
- mbedtls_mutex_free = mutex_free;
- mbedtls_mutex_lock = mutex_lock;
- mbedtls_mutex_unlock = mutex_unlock;
- mbedtls_mutex_init( &mbedtls_threading_readdir_mutex );
- mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex );
- }
- /*
- * Free global mutexes
- */
- void mbedtls_threading_free_alt( void )
- {
- mbedtls_mutex_free( &mbedtls_threading_readdir_mutex );
- mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex );
- }
- #endif /* MBEDTLS_THREADING_ALT */
- /*
- * Define global mutexes
- */
- #ifndef MUTEX_INIT
- #define MUTEX_INIT
- #endif
- mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
- mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
- #endif /* MBEDTLS_THREADING_C */
- /********* Start of file library/timing.c ************/
- /*
- * Portable interface to the CPU cycle counter
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif
- #if defined(MBEDTLS_TIMING_C)
- #if !defined(MBEDTLS_TIMING_ALT)
- #ifndef asm
- #define asm __asm
- #endif
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- #include <windows.h>
- #include <winbase.h>
- struct _hr_time
- {
- LARGE_INTEGER start;
- };
- #else
- #include <unistd.h>
- #include <sys/types.h>
- #if !VXWORKS
- #include <sys/time.h>
- #endif
- #include <signal.h>
- #include <time.h>
- struct _hr_time
- {
- struct timeval start;
- };
- #endif /* _WIN32 && !EFIX64 && !EFI32 */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long tsc;
- __asm rdtsc
- __asm mov [tsc], eax
- return( tsc );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
- /* some versions of mingw-64 have 32-bit longs even on x84_64 */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && ( defined(__i386__) || ( \
- ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long lo, hi;
- asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
- return( lo );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && __i386__ */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long lo, hi;
- asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
- return( lo | ( hi << 32 ) );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && ( __amd64__ || __x86_64__ ) */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long tbl, tbu0, tbu1;
- do
- {
- asm volatile( "mftbu %0" : "=r" (tbu0) );
- asm volatile( "mftb %0" : "=r" (tbl ) );
- asm volatile( "mftbu %0" : "=r" (tbu1) );
- }
- while( tbu0 != tbu1 );
- return( tbl );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && ( __powerpc__ || __ppc__ ) */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && defined(__sparc64__)
- #if defined(__OpenBSD__)
- #warning OpenBSD does not allow access to tick register using software version instead
- #else
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long tick;
- asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
- return( tick );
- }
- #endif /* __OpenBSD__ */
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && __sparc64__ */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long tick;
- asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
- asm volatile( "mov %%g1, %0" : "=r" (tick) );
- return( tick );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && __sparc__ && !__sparc64__ */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && defined(__alpha__)
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long cc;
- asm volatile( "rpcc %0" : "=r" (cc) );
- return( cc & 0xFFFFFFFF );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && __alpha__ */
- #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
- defined(__GNUC__) && defined(__ia64__)
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- unsigned long itc;
- asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
- return( itc );
- }
- #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
- __GNUC__ && __ia64__ */
- #if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
- !defined(EFIX64) && !defined(EFI32)
- #define HAVE_HARDCLOCK
- unsigned long mbedtls_timing_hardclock( void )
- {
- LARGE_INTEGER offset;
- QueryPerformanceCounter( &offset );
- return( (unsigned long)( offset.QuadPart ) );
- }
- #endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
- #if !defined(HAVE_HARDCLOCK)
- #define HAVE_HARDCLOCK
- static int hardclock_init = 0;
- static struct timeval tv_init;
- unsigned long mbedtls_timing_hardclock( void )
- {
- struct timeval tv_cur;
- if( hardclock_init == 0 )
- {
- gettimeofday( &tv_init, NULL );
- hardclock_init = 1;
- }
- gettimeofday( &tv_cur, NULL );
- return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
- + ( tv_cur.tv_usec - tv_init.tv_usec ) );
- }
- #endif /* !HAVE_HARDCLOCK */
- volatile int mbedtls_timing_alarmed = 0;
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
- {
- unsigned long delta;
- LARGE_INTEGER offset, hfreq;
- struct _hr_time *t = (struct _hr_time *) val;
- QueryPerformanceCounter( &offset );
- QueryPerformanceFrequency( &hfreq );
- delta = (unsigned long)( ( 1000 *
- ( offset.QuadPart - t->start.QuadPart ) ) /
- hfreq.QuadPart );
- if( reset )
- QueryPerformanceCounter( &t->start );
- return( delta );
- }
- /* It's OK to use a global because alarm() is supposed to be global anyway */
- static DWORD alarmMs;
- static DWORD WINAPI TimerProc( LPVOID TimerContext )
- {
- ((void) TimerContext);
- Sleep( alarmMs );
- mbedtls_timing_alarmed = 1;
- return( TRUE );
- }
- void mbedtls_set_alarm( int seconds )
- {
- DWORD ThreadId;
- mbedtls_timing_alarmed = 0;
- alarmMs = seconds * 1000;
- CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) );
- }
- #else /* _WIN32 && !EFIX64 && !EFI32 */
- unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
- {
- unsigned long delta;
- struct timeval offset;
- struct _hr_time *t = (struct _hr_time *) val;
- gettimeofday( &offset, NULL );
- if( reset )
- {
- t->start.tv_sec = offset.tv_sec;
- t->start.tv_usec = offset.tv_usec;
- return( 0 );
- }
- delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
- + ( offset.tv_usec - t->start.tv_usec ) / 1000;
- return( delta );
- }
- static void sighandler( int signum )
- {
- mbedtls_timing_alarmed = 1;
- signal( signum, sighandler );
- }
- void mbedtls_set_alarm( int seconds )
- {
- mbedtls_timing_alarmed = 0;
- signal( SIGALRM, sighandler );
- alarm( seconds );
- }
- #endif /* _WIN32 && !EFIX64 && !EFI32 */
- /*
- * Set delays to watch
- */
- void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
- {
- mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
- ctx->int_ms = int_ms;
- ctx->fin_ms = fin_ms;
- if( fin_ms != 0 )
- (void) mbedtls_timing_get_timer( &ctx->timer, 1 );
- }
- /*
- * Get number of delays expired
- */
- int mbedtls_timing_get_delay( void *data )
- {
- mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
- unsigned long elapsed_ms;
- if( ctx->fin_ms == 0 )
- return( -1 );
- elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 );
- if( elapsed_ms >= ctx->fin_ms )
- return( 2 );
- if( elapsed_ms >= ctx->int_ms )
- return( 1 );
- return( 0 );
- }
- #endif /* !MBEDTLS_TIMING_ALT */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Busy-waits for the given number of milliseconds.
- * Used for testing mbedtls_timing_hardclock.
- */
- static void busy_msleep( unsigned long msec )
- {
- struct mbedtls_timing_hr_time hires;
- unsigned long i = 0; /* for busy-waiting */
- volatile unsigned long j; /* to prevent optimisation */
- (void) mbedtls_timing_get_timer( &hires, 1 );
- while( mbedtls_timing_get_timer( &hires, 0 ) < msec )
- i++;
- j = i;
- (void) j;
- }
- #define FAIL do \
- { \
- if( verbose != 0 ) \
- mbedtls_printf( "failed\n" ); \
- \
- return( 1 ); \
- } while( 0 )
- /*
- * Checkup routine
- *
- * Warning: this is work in progress, some tests may not be reliable enough
- * yet! False positives may happen.
- */
- int mbedtls_timing_self_test( int verbose )
- {
- unsigned long cycles, ratio;
- unsigned long millisecs, secs;
- int hardfail;
- struct mbedtls_timing_hr_time hires;
- uint32_t a, b;
- mbedtls_timing_delay_context ctx;
- if( verbose != 0 )
- mbedtls_printf( " TIMING tests note: will take some time!\n" );
- if( verbose != 0 )
- mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " );
- for( secs = 1; secs <= 3; secs++ )
- {
- (void) mbedtls_timing_get_timer( &hires, 1 );
- mbedtls_set_alarm( (int) secs );
- while( !mbedtls_timing_alarmed )
- ;
- millisecs = mbedtls_timing_get_timer( &hires, 0 );
- /* For some reason on Windows it looks like alarm has an extra delay
- * (maybe related to creating a new thread). Allow some room here. */
- if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( 1 );
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " TIMING test #2 (set/get_delay ): " );
- for( a = 200; a <= 400; a += 200 )
- {
- for( b = 200; b <= 400; b += 200 )
- {
- mbedtls_timing_set_delay( &ctx, a, a + b );
- busy_msleep( a - a / 8 );
- if( mbedtls_timing_get_delay( &ctx ) != 0 )
- FAIL;
- busy_msleep( a / 4 );
- if( mbedtls_timing_get_delay( &ctx ) != 1 )
- FAIL;
- busy_msleep( b - a / 8 - b / 8 );
- if( mbedtls_timing_get_delay( &ctx ) != 1 )
- FAIL;
- busy_msleep( b / 4 );
- if( mbedtls_timing_get_delay( &ctx ) != 2 )
- FAIL;
- }
- }
- mbedtls_timing_set_delay( &ctx, 0, 0 );
- busy_msleep( 200 );
- if( mbedtls_timing_get_delay( &ctx ) != -1 )
- FAIL;
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- if( verbose != 0 )
- mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " );
- /*
- * Allow one failure for possible counter wrapping.
- * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
- * since the whole test is about 10ms, it shouldn't happen twice in a row.
- */
- hardfail = 0;
- hard_test:
- if( hardfail > 1 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (ignored)\n" );
- goto hard_test_done;
- }
- /* Get a reference ratio cycles/ms */
- millisecs = 1;
- cycles = mbedtls_timing_hardclock();
- busy_msleep( millisecs );
- cycles = mbedtls_timing_hardclock() - cycles;
- ratio = cycles / millisecs;
- /* Check that the ratio is mostly constant */
- for( millisecs = 2; millisecs <= 4; millisecs++ )
- {
- cycles = mbedtls_timing_hardclock();
- busy_msleep( millisecs );
- cycles = mbedtls_timing_hardclock() - cycles;
- /* Allow variation up to 20% */
- if( cycles / millisecs < ratio - ratio / 5 ||
- cycles / millisecs > ratio + ratio / 5 )
- {
- hardfail++;
- goto hard_test;
- }
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- hard_test_done:
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- return( 0 );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_TIMING_C */
- /********* Start of file library/version.c ************/
- /*
- * Version information
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_VERSION_C)
- #include <string.h>
- unsigned int mbedtls_version_get_number()
- {
- return( MBEDTLS_VERSION_NUMBER );
- }
- void mbedtls_version_get_string( char *string )
- {
- memcpy( string, MBEDTLS_VERSION_STRING,
- sizeof( MBEDTLS_VERSION_STRING ) );
- }
- void mbedtls_version_get_string_full( char *string )
- {
- memcpy( string, MBEDTLS_VERSION_STRING_FULL,
- sizeof( MBEDTLS_VERSION_STRING_FULL ) );
- }
- #endif /* MBEDTLS_VERSION_C */
- /********* Start of file library/version_features.c ************/
- /*
- * Version feature information
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_VERSION_C)
- #include <string.h>
- static const char *features[] = {
- #if defined(MBEDTLS_VERSION_FEATURES)
- #if defined(MBEDTLS_HAVE_ASM)
- "MBEDTLS_HAVE_ASM",
- #endif /* MBEDTLS_HAVE_ASM */
- #if defined(MBEDTLS_HAVE_SSE2)
- "MBEDTLS_HAVE_SSE2",
- #endif /* MBEDTLS_HAVE_SSE2 */
- #if defined(MBEDTLS_HAVE_TIME)
- "MBEDTLS_HAVE_TIME",
- #endif /* MBEDTLS_HAVE_TIME */
- #if defined(MBEDTLS_HAVE_TIME_DATE)
- "MBEDTLS_HAVE_TIME_DATE",
- #endif /* MBEDTLS_HAVE_TIME_DATE */
- #if defined(MBEDTLS_PLATFORM_MEMORY)
- "MBEDTLS_PLATFORM_MEMORY",
- #endif /* MBEDTLS_PLATFORM_MEMORY */
- #if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
- "MBEDTLS_PLATFORM_NO_STD_FUNCTIONS",
- #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
- #if defined(MBEDTLS_PLATFORM_EXIT_ALT)
- "MBEDTLS_PLATFORM_EXIT_ALT",
- #endif /* MBEDTLS_PLATFORM_EXIT_ALT */
- #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
- "MBEDTLS_PLATFORM_FPRINTF_ALT",
- #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
- #if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
- "MBEDTLS_PLATFORM_PRINTF_ALT",
- #endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
- #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
- "MBEDTLS_PLATFORM_SNPRINTF_ALT",
- #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
- #if defined(MBEDTLS_DEPRECATED_WARNING)
- "MBEDTLS_DEPRECATED_WARNING",
- #endif /* MBEDTLS_DEPRECATED_WARNING */
- #if defined(MBEDTLS_DEPRECATED_REMOVED)
- "MBEDTLS_DEPRECATED_REMOVED",
- #endif /* MBEDTLS_DEPRECATED_REMOVED */
- #if defined(MBEDTLS_TIMING_ALT)
- "MBEDTLS_TIMING_ALT",
- #endif /* MBEDTLS_TIMING_ALT */
- #if defined(MBEDTLS_AES_ALT)
- "MBEDTLS_AES_ALT",
- #endif /* MBEDTLS_AES_ALT */
- #if defined(MBEDTLS_ARC4_ALT)
- "MBEDTLS_ARC4_ALT",
- #endif /* MBEDTLS_ARC4_ALT */
- #if defined(MBEDTLS_BLOWFISH_ALT)
- "MBEDTLS_BLOWFISH_ALT",
- #endif /* MBEDTLS_BLOWFISH_ALT */
- #if defined(MBEDTLS_CAMELLIA_ALT)
- "MBEDTLS_CAMELLIA_ALT",
- #endif /* MBEDTLS_CAMELLIA_ALT */
- #if defined(MBEDTLS_DES_ALT)
- "MBEDTLS_DES_ALT",
- #endif /* MBEDTLS_DES_ALT */
- #if defined(MBEDTLS_XTEA_ALT)
- "MBEDTLS_XTEA_ALT",
- #endif /* MBEDTLS_XTEA_ALT */
- #if defined(MBEDTLS_MD2_ALT)
- "MBEDTLS_MD2_ALT",
- #endif /* MBEDTLS_MD2_ALT */
- #if defined(MBEDTLS_MD4_ALT)
- "MBEDTLS_MD4_ALT",
- #endif /* MBEDTLS_MD4_ALT */
- #if defined(MBEDTLS_MD5_ALT)
- "MBEDTLS_MD5_ALT",
- #endif /* MBEDTLS_MD5_ALT */
- #if defined(MBEDTLS_RIPEMD160_ALT)
- "MBEDTLS_RIPEMD160_ALT",
- #endif /* MBEDTLS_RIPEMD160_ALT */
- #if defined(MBEDTLS_SHA1_ALT)
- "MBEDTLS_SHA1_ALT",
- #endif /* MBEDTLS_SHA1_ALT */
- #if defined(MBEDTLS_SHA256_ALT)
- "MBEDTLS_SHA256_ALT",
- #endif /* MBEDTLS_SHA256_ALT */
- #if defined(MBEDTLS_SHA512_ALT)
- "MBEDTLS_SHA512_ALT",
- #endif /* MBEDTLS_SHA512_ALT */
- #if defined(MBEDTLS_MD2_PROCESS_ALT)
- "MBEDTLS_MD2_PROCESS_ALT",
- #endif /* MBEDTLS_MD2_PROCESS_ALT */
- #if defined(MBEDTLS_MD4_PROCESS_ALT)
- "MBEDTLS_MD4_PROCESS_ALT",
- #endif /* MBEDTLS_MD4_PROCESS_ALT */
- #if defined(MBEDTLS_MD5_PROCESS_ALT)
- "MBEDTLS_MD5_PROCESS_ALT",
- #endif /* MBEDTLS_MD5_PROCESS_ALT */
- #if defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
- "MBEDTLS_RIPEMD160_PROCESS_ALT",
- #endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */
- #if defined(MBEDTLS_SHA1_PROCESS_ALT)
- "MBEDTLS_SHA1_PROCESS_ALT",
- #endif /* MBEDTLS_SHA1_PROCESS_ALT */
- #if defined(MBEDTLS_SHA256_PROCESS_ALT)
- "MBEDTLS_SHA256_PROCESS_ALT",
- #endif /* MBEDTLS_SHA256_PROCESS_ALT */
- #if defined(MBEDTLS_SHA512_PROCESS_ALT)
- "MBEDTLS_SHA512_PROCESS_ALT",
- #endif /* MBEDTLS_SHA512_PROCESS_ALT */
- #if defined(MBEDTLS_DES_SETKEY_ALT)
- "MBEDTLS_DES_SETKEY_ALT",
- #endif /* MBEDTLS_DES_SETKEY_ALT */
- #if defined(MBEDTLS_DES_CRYPT_ECB_ALT)
- "MBEDTLS_DES_CRYPT_ECB_ALT",
- #endif /* MBEDTLS_DES_CRYPT_ECB_ALT */
- #if defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
- "MBEDTLS_DES3_CRYPT_ECB_ALT",
- #endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */
- #if defined(MBEDTLS_AES_SETKEY_ENC_ALT)
- "MBEDTLS_AES_SETKEY_ENC_ALT",
- #endif /* MBEDTLS_AES_SETKEY_ENC_ALT */
- #if defined(MBEDTLS_AES_SETKEY_DEC_ALT)
- "MBEDTLS_AES_SETKEY_DEC_ALT",
- #endif /* MBEDTLS_AES_SETKEY_DEC_ALT */
- #if defined(MBEDTLS_AES_ENCRYPT_ALT)
- "MBEDTLS_AES_ENCRYPT_ALT",
- #endif /* MBEDTLS_AES_ENCRYPT_ALT */
- #if defined(MBEDTLS_AES_DECRYPT_ALT)
- "MBEDTLS_AES_DECRYPT_ALT",
- #endif /* MBEDTLS_AES_DECRYPT_ALT */
- #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
- "MBEDTLS_ENTROPY_HARDWARE_ALT",
- #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
- #if defined(MBEDTLS_AES_ROM_TABLES)
- "MBEDTLS_AES_ROM_TABLES",
- #endif /* MBEDTLS_AES_ROM_TABLES */
- #if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
- "MBEDTLS_CAMELLIA_SMALL_MEMORY",
- #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- "MBEDTLS_CIPHER_MODE_CBC",
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #if defined(MBEDTLS_CIPHER_MODE_CFB)
- "MBEDTLS_CIPHER_MODE_CFB",
- #endif /* MBEDTLS_CIPHER_MODE_CFB */
- #if defined(MBEDTLS_CIPHER_MODE_CTR)
- "MBEDTLS_CIPHER_MODE_CTR",
- #endif /* MBEDTLS_CIPHER_MODE_CTR */
- #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- "MBEDTLS_CIPHER_NULL_CIPHER",
- #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
- #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- "MBEDTLS_CIPHER_PADDING_PKCS7",
- #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
- #if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
- "MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS",
- #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
- #if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
- "MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN",
- #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
- #if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
- "MBEDTLS_CIPHER_PADDING_ZEROS",
- #endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
- #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
- "MBEDTLS_ENABLE_WEAK_CIPHERSUITES",
- #endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */
- #if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES)
- "MBEDTLS_REMOVE_ARC4_CIPHERSUITES",
- #endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */
- #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
- "MBEDTLS_ECP_DP_SECP192R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
- "MBEDTLS_ECP_DP_SECP224R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- "MBEDTLS_ECP_DP_SECP256R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- "MBEDTLS_ECP_DP_SECP384R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- "MBEDTLS_ECP_DP_SECP521R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
- "MBEDTLS_ECP_DP_SECP192K1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
- "MBEDTLS_ECP_DP_SECP224K1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
- "MBEDTLS_ECP_DP_SECP256K1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
- "MBEDTLS_ECP_DP_BP256R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
- "MBEDTLS_ECP_DP_BP384R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
- "MBEDTLS_ECP_DP_BP512R1_ENABLED",
- #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
- #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- "MBEDTLS_ECP_DP_CURVE25519_ENABLED",
- #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
- #if defined(MBEDTLS_ECP_NIST_OPTIM)
- "MBEDTLS_ECP_NIST_OPTIM",
- #endif /* MBEDTLS_ECP_NIST_OPTIM */
- #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- "MBEDTLS_ECDSA_DETERMINISTIC",
- #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
- #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_PSK_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
- #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED",
- #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
- #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
- "MBEDTLS_PK_PARSE_EC_EXTENDED",
- #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
- #if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
- "MBEDTLS_ERROR_STRERROR_DUMMY",
- #endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
- #if defined(MBEDTLS_GENPRIME)
- "MBEDTLS_GENPRIME",
- #endif /* MBEDTLS_GENPRIME */
- #if defined(MBEDTLS_FS_IO)
- "MBEDTLS_FS_IO",
- #endif /* MBEDTLS_FS_IO */
- #if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
- "MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES",
- #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
- #if defined(MBEDTLS_NO_PLATFORM_ENTROPY)
- "MBEDTLS_NO_PLATFORM_ENTROPY",
- #endif /* MBEDTLS_NO_PLATFORM_ENTROPY */
- #if defined(MBEDTLS_ENTROPY_FORCE_SHA256)
- "MBEDTLS_ENTROPY_FORCE_SHA256",
- #endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */
- #if defined(MBEDTLS_MEMORY_DEBUG)
- "MBEDTLS_MEMORY_DEBUG",
- #endif /* MBEDTLS_MEMORY_DEBUG */
- #if defined(MBEDTLS_MEMORY_BACKTRACE)
- "MBEDTLS_MEMORY_BACKTRACE",
- #endif /* MBEDTLS_MEMORY_BACKTRACE */
- #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
- "MBEDTLS_PK_RSA_ALT_SUPPORT",
- #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
- #if defined(MBEDTLS_PKCS1_V15)
- "MBEDTLS_PKCS1_V15",
- #endif /* MBEDTLS_PKCS1_V15 */
- #if defined(MBEDTLS_PKCS1_V21)
- "MBEDTLS_PKCS1_V21",
- #endif /* MBEDTLS_PKCS1_V21 */
- #if defined(MBEDTLS_RSA_NO_CRT)
- "MBEDTLS_RSA_NO_CRT",
- #endif /* MBEDTLS_RSA_NO_CRT */
- #if defined(MBEDTLS_SELF_TEST)
- "MBEDTLS_SELF_TEST",
- #endif /* MBEDTLS_SELF_TEST */
- #if defined(MBEDTLS_SHA256_SMALLER)
- "MBEDTLS_SHA256_SMALLER",
- #endif /* MBEDTLS_SHA256_SMALLER */
- #if defined(MBEDTLS_SSL_AEAD_RANDOM_IV)
- "MBEDTLS_SSL_AEAD_RANDOM_IV",
- #endif /* MBEDTLS_SSL_AEAD_RANDOM_IV */
- #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- "MBEDTLS_SSL_ALL_ALERT_MESSAGES",
- #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
- #if defined(MBEDTLS_SSL_DEBUG_ALL)
- "MBEDTLS_SSL_DEBUG_ALL",
- #endif /* MBEDTLS_SSL_DEBUG_ALL */
- #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- "MBEDTLS_SSL_ENCRYPT_THEN_MAC",
- #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- "MBEDTLS_SSL_EXTENDED_MASTER_SECRET",
- #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
- #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
- "MBEDTLS_SSL_FALLBACK_SCSV",
- #endif /* MBEDTLS_SSL_FALLBACK_SCSV */
- #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- "MBEDTLS_SSL_HW_RECORD_ACCEL",
- #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- "MBEDTLS_SSL_CBC_RECORD_SPLITTING",
- #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
- #if defined(MBEDTLS_SSL_RENEGOTIATION)
- "MBEDTLS_SSL_RENEGOTIATION",
- #endif /* MBEDTLS_SSL_RENEGOTIATION */
- #if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
- "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO",
- #endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
- #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
- "MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE",
- #endif /* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE */
- #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH",
- #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
- #if defined(MBEDTLS_SSL_PROTO_SSL3)
- "MBEDTLS_SSL_PROTO_SSL3",
- #endif /* MBEDTLS_SSL_PROTO_SSL3 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1)
- "MBEDTLS_SSL_PROTO_TLS1",
- #endif /* MBEDTLS_SSL_PROTO_TLS1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_1)
- "MBEDTLS_SSL_PROTO_TLS1_1",
- #endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- "MBEDTLS_SSL_PROTO_TLS1_2",
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- #if defined(MBEDTLS_SSL_PROTO_DTLS)
- "MBEDTLS_SSL_PROTO_DTLS",
- #endif /* MBEDTLS_SSL_PROTO_DTLS */
- #if defined(MBEDTLS_SSL_ALPN)
- "MBEDTLS_SSL_ALPN",
- #endif /* MBEDTLS_SSL_ALPN */
- #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- "MBEDTLS_SSL_DTLS_ANTI_REPLAY",
- #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
- "MBEDTLS_SSL_DTLS_HELLO_VERIFY",
- #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
- "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE",
- #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */
- #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
- "MBEDTLS_SSL_DTLS_BADMAC_LIMIT",
- #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
- #if defined(MBEDTLS_SSL_SESSION_TICKETS)
- "MBEDTLS_SSL_SESSION_TICKETS",
- #endif /* MBEDTLS_SSL_SESSION_TICKETS */
- #if defined(MBEDTLS_SSL_EXPORT_KEYS)
- "MBEDTLS_SSL_EXPORT_KEYS",
- #endif /* MBEDTLS_SSL_EXPORT_KEYS */
- #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- "MBEDTLS_SSL_SERVER_NAME_INDICATION",
- #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
- #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- "MBEDTLS_SSL_TRUNCATED_HMAC",
- #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
- #if defined(MBEDTLS_THREADING_ALT)
- "MBEDTLS_THREADING_ALT",
- #endif /* MBEDTLS_THREADING_ALT */
- #if defined(MBEDTLS_THREADING_PTHREAD)
- "MBEDTLS_THREADING_PTHREAD",
- #endif /* MBEDTLS_THREADING_PTHREAD */
- #if defined(MBEDTLS_VERSION_FEATURES)
- "MBEDTLS_VERSION_FEATURES",
- #endif /* MBEDTLS_VERSION_FEATURES */
- #if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
- "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3",
- #endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */
- #if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
- "MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION",
- #endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */
- #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- "MBEDTLS_X509_CHECK_KEY_USAGE",
- #endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
- #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
- "MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE",
- #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- "MBEDTLS_X509_RSASSA_PSS_SUPPORT",
- #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
- #if defined(MBEDTLS_ZLIB_SUPPORT)
- "MBEDTLS_ZLIB_SUPPORT",
- #endif /* MBEDTLS_ZLIB_SUPPORT */
- #if defined(MBEDTLS_AESNI_C)
- "MBEDTLS_AESNI_C",
- #endif /* MBEDTLS_AESNI_C */
- #if defined(MBEDTLS_AES_C)
- "MBEDTLS_AES_C",
- #endif /* MBEDTLS_AES_C */
- #if defined(MBEDTLS_ARC4_C)
- "MBEDTLS_ARC4_C",
- #endif /* MBEDTLS_ARC4_C */
- #if defined(MBEDTLS_ASN1_PARSE_C)
- "MBEDTLS_ASN1_PARSE_C",
- #endif /* MBEDTLS_ASN1_PARSE_C */
- #if defined(MBEDTLS_ASN1_WRITE_C)
- "MBEDTLS_ASN1_WRITE_C",
- #endif /* MBEDTLS_ASN1_WRITE_C */
- #if defined(MBEDTLS_BASE64_C)
- "MBEDTLS_BASE64_C",
- #endif /* MBEDTLS_BASE64_C */
- #if defined(MBEDTLS_BIGNUM_C)
- "MBEDTLS_BIGNUM_C",
- #endif /* MBEDTLS_BIGNUM_C */
- #if defined(MBEDTLS_BLOWFISH_C)
- "MBEDTLS_BLOWFISH_C",
- #endif /* MBEDTLS_BLOWFISH_C */
- #if defined(MBEDTLS_CAMELLIA_C)
- "MBEDTLS_CAMELLIA_C",
- #endif /* MBEDTLS_CAMELLIA_C */
- #if defined(MBEDTLS_CCM_C)
- "MBEDTLS_CCM_C",
- #endif /* MBEDTLS_CCM_C */
- #if defined(MBEDTLS_CERTS_C)
- "MBEDTLS_CERTS_C",
- #endif /* MBEDTLS_CERTS_C */
- #if defined(MBEDTLS_CIPHER_C)
- "MBEDTLS_CIPHER_C",
- #endif /* MBEDTLS_CIPHER_C */
- #if defined(MBEDTLS_CTR_DRBG_C)
- "MBEDTLS_CTR_DRBG_C",
- #endif /* MBEDTLS_CTR_DRBG_C */
- #if defined(MBEDTLS_DEBUG_C)
- "MBEDTLS_DEBUG_C",
- #endif /* MBEDTLS_DEBUG_C */
- #if defined(MBEDTLS_DES_C)
- "MBEDTLS_DES_C",
- #endif /* MBEDTLS_DES_C */
- #if defined(MBEDTLS_DHM_C)
- "MBEDTLS_DHM_C",
- #endif /* MBEDTLS_DHM_C */
- #if defined(MBEDTLS_ECDH_C)
- "MBEDTLS_ECDH_C",
- #endif /* MBEDTLS_ECDH_C */
- #if defined(MBEDTLS_ECDSA_C)
- "MBEDTLS_ECDSA_C",
- #endif /* MBEDTLS_ECDSA_C */
- #if defined(MBEDTLS_ECJPAKE_C)
- "MBEDTLS_ECJPAKE_C",
- #endif /* MBEDTLS_ECJPAKE_C */
- #if defined(MBEDTLS_ECP_C)
- "MBEDTLS_ECP_C",
- #endif /* MBEDTLS_ECP_C */
- #if defined(MBEDTLS_ENTROPY_C)
- "MBEDTLS_ENTROPY_C",
- #endif /* MBEDTLS_ENTROPY_C */
- #if defined(MBEDTLS_ERROR_C)
- "MBEDTLS_ERROR_C",
- #endif /* MBEDTLS_ERROR_C */
- #if defined(MBEDTLS_GCM_C)
- "MBEDTLS_GCM_C",
- #endif /* MBEDTLS_GCM_C */
- #if defined(MBEDTLS_HAVEGE_C)
- "MBEDTLS_HAVEGE_C",
- #endif /* MBEDTLS_HAVEGE_C */
- #if defined(MBEDTLS_HMAC_DRBG_C)
- "MBEDTLS_HMAC_DRBG_C",
- #endif /* MBEDTLS_HMAC_DRBG_C */
- #if defined(MBEDTLS_MD_C)
- "MBEDTLS_MD_C",
- #endif /* MBEDTLS_MD_C */
- #if defined(MBEDTLS_MD2_C)
- "MBEDTLS_MD2_C",
- #endif /* MBEDTLS_MD2_C */
- #if defined(MBEDTLS_MD4_C)
- "MBEDTLS_MD4_C",
- #endif /* MBEDTLS_MD4_C */
- #if defined(MBEDTLS_MD5_C)
- "MBEDTLS_MD5_C",
- #endif /* MBEDTLS_MD5_C */
- #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
- "MBEDTLS_MEMORY_BUFFER_ALLOC_C",
- #endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
- #if defined(MBEDTLS_NET_C)
- "MBEDTLS_NET_C",
- #endif /* MBEDTLS_NET_C */
- #if defined(MBEDTLS_OID_C)
- "MBEDTLS_OID_C",
- #endif /* MBEDTLS_OID_C */
- #if defined(MBEDTLS_PADLOCK_C)
- "MBEDTLS_PADLOCK_C",
- #endif /* MBEDTLS_PADLOCK_C */
- #if defined(MBEDTLS_PEM_PARSE_C)
- "MBEDTLS_PEM_PARSE_C",
- #endif /* MBEDTLS_PEM_PARSE_C */
- #if defined(MBEDTLS_PEM_WRITE_C)
- "MBEDTLS_PEM_WRITE_C",
- #endif /* MBEDTLS_PEM_WRITE_C */
- #if defined(MBEDTLS_PK_C)
- "MBEDTLS_PK_C",
- #endif /* MBEDTLS_PK_C */
- #if defined(MBEDTLS_PK_PARSE_C)
- "MBEDTLS_PK_PARSE_C",
- #endif /* MBEDTLS_PK_PARSE_C */
- #if defined(MBEDTLS_PK_WRITE_C)
- "MBEDTLS_PK_WRITE_C",
- #endif /* MBEDTLS_PK_WRITE_C */
- #if defined(MBEDTLS_PKCS5_C)
- "MBEDTLS_PKCS5_C",
- #endif /* MBEDTLS_PKCS5_C */
- #if defined(MBEDTLS_PKCS11_C)
- "MBEDTLS_PKCS11_C",
- #endif /* MBEDTLS_PKCS11_C */
- #if defined(MBEDTLS_PKCS12_C)
- "MBEDTLS_PKCS12_C",
- #endif /* MBEDTLS_PKCS12_C */
- #if defined(MBEDTLS_PLATFORM_C)
- "MBEDTLS_PLATFORM_C",
- #endif /* MBEDTLS_PLATFORM_C */
- #if defined(MBEDTLS_RIPEMD160_C)
- "MBEDTLS_RIPEMD160_C",
- #endif /* MBEDTLS_RIPEMD160_C */
- #if defined(MBEDTLS_RSA_C)
- "MBEDTLS_RSA_C",
- #endif /* MBEDTLS_RSA_C */
- #if defined(MBEDTLS_SHA1_C)
- "MBEDTLS_SHA1_C",
- #endif /* MBEDTLS_SHA1_C */
- #if defined(MBEDTLS_SHA256_C)
- "MBEDTLS_SHA256_C",
- #endif /* MBEDTLS_SHA256_C */
- #if defined(MBEDTLS_SHA512_C)
- "MBEDTLS_SHA512_C",
- #endif /* MBEDTLS_SHA512_C */
- #if defined(MBEDTLS_SSL_CACHE_C)
- "MBEDTLS_SSL_CACHE_C",
- #endif /* MBEDTLS_SSL_CACHE_C */
- #if defined(MBEDTLS_SSL_COOKIE_C)
- "MBEDTLS_SSL_COOKIE_C",
- #endif /* MBEDTLS_SSL_COOKIE_C */
- #if defined(MBEDTLS_SSL_TICKET_C)
- "MBEDTLS_SSL_TICKET_C",
- #endif /* MBEDTLS_SSL_TICKET_C */
- #if defined(MBEDTLS_SSL_CLI_C)
- "MBEDTLS_SSL_CLI_C",
- #endif /* MBEDTLS_SSL_CLI_C */
- #if defined(MBEDTLS_SSL_SRV_C)
- "MBEDTLS_SSL_SRV_C",
- #endif /* MBEDTLS_SSL_SRV_C */
- #if defined(MBEDTLS_SSL_TLS_C)
- "MBEDTLS_SSL_TLS_C",
- #endif /* MBEDTLS_SSL_TLS_C */
- #if defined(MBEDTLS_THREADING_C)
- "MBEDTLS_THREADING_C",
- #endif /* MBEDTLS_THREADING_C */
- #if defined(MBEDTLS_TIMING_C)
- "MBEDTLS_TIMING_C",
- #endif /* MBEDTLS_TIMING_C */
- #if defined(MBEDTLS_VERSION_C)
- "MBEDTLS_VERSION_C",
- #endif /* MBEDTLS_VERSION_C */
- #if defined(MBEDTLS_X509_USE_C)
- "MBEDTLS_X509_USE_C",
- #endif /* MBEDTLS_X509_USE_C */
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- "MBEDTLS_X509_CRT_PARSE_C",
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- #if defined(MBEDTLS_X509_CRL_PARSE_C)
- "MBEDTLS_X509_CRL_PARSE_C",
- #endif /* MBEDTLS_X509_CRL_PARSE_C */
- #if defined(MBEDTLS_X509_CSR_PARSE_C)
- "MBEDTLS_X509_CSR_PARSE_C",
- #endif /* MBEDTLS_X509_CSR_PARSE_C */
- #if defined(MBEDTLS_X509_CREATE_C)
- "MBEDTLS_X509_CREATE_C",
- #endif /* MBEDTLS_X509_CREATE_C */
- #if defined(MBEDTLS_X509_CRT_WRITE_C)
- "MBEDTLS_X509_CRT_WRITE_C",
- #endif /* MBEDTLS_X509_CRT_WRITE_C */
- #if defined(MBEDTLS_X509_CSR_WRITE_C)
- "MBEDTLS_X509_CSR_WRITE_C",
- #endif /* MBEDTLS_X509_CSR_WRITE_C */
- #if defined(MBEDTLS_XTEA_C)
- "MBEDTLS_XTEA_C",
- #endif /* MBEDTLS_XTEA_C */
- #endif /* MBEDTLS_VERSION_FEATURES */
- NULL
- };
- int mbedtls_version_check_feature( const char *feature )
- {
- const char **idx = features;
- if( *idx == NULL )
- return( -2 );
- if( feature == NULL )
- return( -1 );
- while( *idx != NULL )
- {
- if( !strcmp( *idx, feature ) )
- return( 0 );
- idx++;
- }
- return( -1 );
- }
- #endif /* MBEDTLS_VERSION_C */
- /********* Start of file library/x509.c ************/
- /*
- * X.509 common functions for parsing and verification
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The ITU-T X.509 standard defines a certificate format for PKI.
- *
- * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
- * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
- * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
- *
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_USE_C)
- #include <stdio.h>
- #include <string.h>
- #if defined(MBEDTLS_PEM_PARSE_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #include <stdlib.h>
- #define mbedtls_free free
- #define mbedtls_calloc calloc
- #define mbedtls_printf printf
- #define mbedtls_snprintf snprintf
- #endif
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- #include <windows.h>
- #else
- #include <time.h>
- #endif
- #if defined(MBEDTLS_FS_IO)
- #include <stdio.h>
- #if !defined(_WIN32)
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #endif
- #endif
- #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
- /*
- * CertificateSerialNumber ::= INTEGER
- */
- int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
- mbedtls_x509_buf *serial )
- {
- int ret;
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
- **p != MBEDTLS_ASN1_INTEGER )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- serial->tag = *(*p)++;
- if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
- serial->p = *p;
- *p += serial->len;
- return( 0 );
- }
- /* Get an algorithm identifier without parameters (eg for signatures)
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- */
- int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
- mbedtls_x509_buf *alg )
- {
- int ret;
- if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- return( 0 );
- }
- /*
- * Parse an algorithm identifier with (optional) paramaters
- */
- int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
- mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
- {
- int ret;
- if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- return( 0 );
- }
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- /*
- * HashAlgorithm ::= AlgorithmIdentifier
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- *
- * For HashAlgorithm, parameters MUST be NULL or absent.
- */
- static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
- {
- int ret;
- unsigned char *p;
- const unsigned char *end;
- mbedtls_x509_buf md_oid;
- size_t len;
- /* Make sure we got a SEQUENCE and setup bounds */
- if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- p = (unsigned char *) alg->p;
- end = p + alg->len;
- if( p >= end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- /* Parse md_oid */
- md_oid.tag = *p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- md_oid.p = p;
- p += md_oid.len;
- /* Get md_alg from md_oid */
- if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- /* Make sure params is absent of NULL */
- if( p == end )
- return( 0 );
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p != end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * RSASSA-PSS-params ::= SEQUENCE {
- * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
- * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
- * saltLength [2] INTEGER DEFAULT 20,
- * trailerField [3] INTEGER DEFAULT 1 }
- * -- Note that the tags in this Sequence are explicit.
- *
- * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
- * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
- * option. Enfore this at parsing time.
- */
- int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
- mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
- int *salt_len )
- {
- int ret;
- unsigned char *p;
- const unsigned char *end, *end2;
- size_t len;
- mbedtls_x509_buf alg_id, alg_params;
- /* First set everything to defaults */
- *md_alg = MBEDTLS_MD_SHA1;
- *mgf_md = MBEDTLS_MD_SHA1;
- *salt_len = 20;
- /* Make sure params is a SEQUENCE and setup bounds */
- if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- p = (unsigned char *) params->p;
- end = p + params->len;
- if( p == end )
- return( 0 );
- /*
- * HashAlgorithm
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
- {
- end2 = p + len;
- /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
- if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p == end )
- return( 0 );
- /*
- * MaskGenAlgorithm
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
- {
- end2 = p + len;
- /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
- if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
- return( ret );
- /* Only MFG1 is recognised for now */
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
- MBEDTLS_ERR_OID_NOT_FOUND );
- /* Parse HashAlgorithm */
- if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
- return( ret );
- if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p == end )
- return( 0 );
- /*
- * salt_len
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 )
- {
- end2 = p + len;
- if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p == end )
- return( 0 );
- /*
- * trailer_field (if present, must be 1)
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 )
- {
- int trailer_field;
- end2 = p + len;
- if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- if( trailer_field != 1 )
- return( MBEDTLS_ERR_X509_INVALID_ALG );
- }
- else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
- if( p != end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
- /*
- * AttributeTypeAndValue ::= SEQUENCE {
- * type AttributeType,
- * value AttributeValue }
- *
- * AttributeType ::= OBJECT IDENTIFIER
- *
- * AttributeValue ::= ANY DEFINED BY AttributeType
- */
- static int x509_get_attr_type_value( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_name *cur )
- {
- int ret;
- size_t len;
- mbedtls_x509_buf *oid;
- mbedtls_x509_buf *val;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- oid = &cur->oid;
- oid->tag = **p;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
- oid->p = *p;
- *p += oid->len;
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
- **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
- **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
- **p != MBEDTLS_ASN1_BIT_STRING )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- val = &cur->val;
- val->tag = *(*p)++;
- if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
- val->p = *p;
- *p += val->len;
- cur->next = NULL;
- return( 0 );
- }
- /*
- * Name ::= CHOICE { -- only one possibility for now --
- * rdnSequence RDNSequence }
- *
- * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- *
- * RelativeDistinguishedName ::=
- * SET OF AttributeTypeAndValue
- *
- * AttributeTypeAndValue ::= SEQUENCE {
- * type AttributeType,
- * value AttributeValue }
- *
- * AttributeType ::= OBJECT IDENTIFIER
- *
- * AttributeValue ::= ANY DEFINED BY AttributeType
- *
- * The data structure is optimized for the common case where each RDN has only
- * one element, which is represented as a list of AttributeTypeAndValue.
- * For the general case we still use a flat list, but we mark elements of the
- * same set so that they are "merged" together in the functions that consume
- * this list, eg mbedtls_x509_dn_gets().
- */
- int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
- mbedtls_x509_name *cur )
- {
- int ret;
- size_t set_len;
- const unsigned char *end_set;
- /* don't use recursion, we'd risk stack overflow if not optimized */
- while( 1 )
- {
- /*
- * parse SET
- */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
- end_set = *p + set_len;
- while( 1 )
- {
- if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
- return( ret );
- if( *p == end_set )
- break;
- /* Mark this item as being no the only one in a set */
- cur->next_merged = 1;
- cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
- if( cur->next == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- cur = cur->next;
- }
- /*
- * continue until end of SEQUENCE is reached
- */
- if( *p == end )
- return( 0 );
- cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
- if( cur->next == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- cur = cur->next;
- }
- }
- static int x509_parse_int(unsigned char **p, unsigned n, int *res){
- *res = 0;
- for( ; n > 0; --n ){
- if( ( **p < '0') || ( **p > '9' ) ) return MBEDTLS_ERR_X509_INVALID_DATE;
- *res *= 10;
- *res += (*(*p)++ - '0');
- }
- return 0;
- }
- /*
- * Time ::= CHOICE {
- * utcTime UTCTime,
- * generalTime GeneralizedTime }
- */
- int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
- mbedtls_x509_time *time )
- {
- int ret;
- size_t len;
- unsigned char tag;
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- tag = **p;
- if( tag == MBEDTLS_ASN1_UTC_TIME )
- {
- (*p)++;
- ret = mbedtls_asn1_get_len( p, end, &len );
- if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
- CHECK( x509_parse_int( p, 2, &time->year ) );
- CHECK( x509_parse_int( p, 2, &time->mon ) );
- CHECK( x509_parse_int( p, 2, &time->day ) );
- CHECK( x509_parse_int( p, 2, &time->hour ) );
- CHECK( x509_parse_int( p, 2, &time->min ) );
- if( len > 10 )
- CHECK( x509_parse_int( p, 2, &time->sec ) );
- if( len > 12 && *(*p)++ != 'Z' )
- return( MBEDTLS_ERR_X509_INVALID_DATE );
- time->year += 100 * ( time->year < 50 );
- time->year += 1900;
- return( 0 );
- }
- else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
- {
- (*p)++;
- ret = mbedtls_asn1_get_len( p, end, &len );
- if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
- CHECK( x509_parse_int( p, 4, &time->year ) );
- CHECK( x509_parse_int( p, 2, &time->mon ) );
- CHECK( x509_parse_int( p, 2, &time->day ) );
- CHECK( x509_parse_int( p, 2, &time->hour ) );
- CHECK( x509_parse_int( p, 2, &time->min ) );
- if( len > 12 )
- CHECK( x509_parse_int( p, 2, &time->sec ) );
- if( len > 14 && *(*p)++ != 'Z' )
- return( MBEDTLS_ERR_X509_INVALID_DATE );
- return( 0 );
- }
- else
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- }
- int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
- {
- int ret;
- size_t len;
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- sig->tag = **p;
- if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
- sig->len = len;
- sig->p = *p;
- *p += len;
- return( 0 );
- }
- /*
- * Get signature algorithm from alg OID and optional parameters
- */
- int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
- mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
- void **sig_opts )
- {
- int ret;
- if( *sig_opts != NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
- {
- mbedtls_pk_rsassa_pss_options *pss_opts;
- pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) );
- if( pss_opts == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- ret = mbedtls_x509_get_rsassa_pss_params( sig_params,
- md_alg,
- &pss_opts->mgf1_hash_id,
- &pss_opts->expected_salt_len );
- if( ret != 0 )
- {
- mbedtls_free( pss_opts );
- return( ret );
- }
- *sig_opts = (void *) pss_opts;
- }
- else
- #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
- {
- /* Make sure parameters are absent or NULL */
- if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
- sig_params->len != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG );
- }
- return( 0 );
- }
- /*
- * X.509 Extensions (No parsing of extensions, pointer should
- * be either manually updated or extensions should be parsed!
- */
- int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
- mbedtls_x509_buf *ext, int tag )
- {
- int ret;
- size_t len;
- if( *p == end )
- return( 0 );
- ext->tag = **p;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 )
- return( ret );
- ext->p = *p;
- end = *p + ext->len;
- /*
- * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
- *
- * Extension ::= SEQUENCE {
- * extnID OBJECT IDENTIFIER,
- * critical BOOLEAN DEFAULT FALSE,
- * extnValue OCTET STRING }
- */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( end != *p + len )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * Store the name in printable form into buf; no more
- * than size characters will be written
- */
- int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
- {
- int ret;
- size_t i, n;
- unsigned char c, merge = 0;
- const mbedtls_x509_name *name;
- const char *short_name = NULL;
- char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
- memset( s, 0, sizeof( s ) );
- name = dn;
- p = buf;
- n = size;
- while( name != NULL )
- {
- if( !name->oid.p )
- {
- name = name->next;
- continue;
- }
- if( name != dn )
- {
- ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );
- if( ret == 0 )
- ret = mbedtls_snprintf( p, n, "%s=", short_name );
- else
- ret = mbedtls_snprintf( p, n, "\?\?=" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- for( i = 0; i < name->val.len; i++ )
- {
- if( i >= sizeof( s ) - 1 )
- break;
- c = name->val.p[i];
- if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
- s[i] = '?';
- else s[i] = c;
- }
- s[i] = '\0';
- ret = mbedtls_snprintf( p, n, "%s", s );
- MBEDTLS_X509_SAFE_SNPRINTF;
- merge = name->next_merged;
- name = name->next;
- }
- return( (int) ( size - n ) );
- }
- /*
- * Store the serial in printable form into buf; no more
- * than size characters will be written
- */
- int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
- {
- int ret;
- size_t i, n, nr;
- char *p;
- p = buf;
- n = size;
- nr = ( serial->len <= 32 )
- ? serial->len : 28;
- for( i = 0; i < nr; i++ )
- {
- if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
- continue;
- ret = mbedtls_snprintf( p, n, "%02X%s",
- serial->p[i], ( i < nr - 1 ) ? ":" : "" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- if( nr != serial->len )
- {
- ret = mbedtls_snprintf( p, n, "...." );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- return( (int) ( size - n ) );
- }
- /*
- * Helper for writing signature algorithms
- */
- int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
- mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
- const void *sig_opts )
- {
- int ret;
- char *p = buf;
- size_t n = size;
- const char *desc = NULL;
- ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
- if( ret != 0 )
- ret = mbedtls_snprintf( p, n, "???" );
- else
- ret = mbedtls_snprintf( p, n, "%s", desc );
- MBEDTLS_X509_SAFE_SNPRINTF;
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
- {
- const mbedtls_pk_rsassa_pss_options *pss_opts;
- const mbedtls_md_info_t *md_info, *mgf_md_info;
- pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
- md_info = mbedtls_md_info_from_type( md_alg );
- mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
- ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
- md_info ? mbedtls_md_get_name( md_info ) : "???",
- mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
- pss_opts->expected_salt_len );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- #else
- ((void) pk_alg);
- ((void) md_alg);
- ((void) sig_opts);
- #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
- return( (int)( size - n ) );
- }
- /*
- * Helper for writing "RSA key size", "EC key size", etc
- */
- int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
- {
- char *p = buf;
- size_t n = buf_size;
- int ret;
- ret = mbedtls_snprintf( p, n, "%s key size", name );
- MBEDTLS_X509_SAFE_SNPRINTF;
- return( 0 );
- }
- #if defined(MBEDTLS_HAVE_TIME_DATE)
- /*
- * Set the time structure to the current time.
- * Return 0 on success, non-zero on failure.
- */
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- static int x509_get_current_time( mbedtls_x509_time *now )
- {
- SYSTEMTIME st;
- GetSystemTime( &st );
- now->year = st.wYear;
- now->mon = st.wMonth;
- now->day = st.wDay;
- now->hour = st.wHour;
- now->min = st.wMinute;
- now->sec = st.wSecond;
- return( 0 );
- }
- #else
- static int x509_get_current_time( mbedtls_x509_time *now )
- {
- struct tm *lt;
- time_t tt;
- int ret = 0;
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- tt = time( NULL );
- lt = gmtime( &tt );
- if( lt == NULL )
- ret = -1;
- else
- {
- now->year = lt->tm_year + 1900;
- now->mon = lt->tm_mon + 1;
- now->day = lt->tm_mday;
- now->hour = lt->tm_hour;
- now->min = lt->tm_min;
- now->sec = lt->tm_sec;
- }
- #if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
- #endif
- return( ret );
- }
- #endif /* _WIN32 && !EFIX64 && !EFI32 */
- /*
- * Return 0 if before <= after, 1 otherwise
- */
- static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after )
- {
- if( before->year > after->year )
- return( 1 );
- if( before->year == after->year &&
- before->mon > after->mon )
- return( 1 );
- if( before->year == after->year &&
- before->mon == after->mon &&
- before->day > after->day )
- return( 1 );
- if( before->year == after->year &&
- before->mon == after->mon &&
- before->day == after->day &&
- before->hour > after->hour )
- return( 1 );
- if( before->year == after->year &&
- before->mon == after->mon &&
- before->day == after->day &&
- before->hour == after->hour &&
- before->min > after->min )
- return( 1 );
- if( before->year == after->year &&
- before->mon == after->mon &&
- before->day == after->day &&
- before->hour == after->hour &&
- before->min == after->min &&
- before->sec > after->sec )
- return( 1 );
- return( 0 );
- }
- int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
- {
- mbedtls_x509_time now;
- if( x509_get_current_time( &now ) != 0 )
- return( 1 );
- return( x509_check_time( &now, to ) );
- }
- int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
- {
- mbedtls_x509_time now;
- if( x509_get_current_time( &now ) != 0 )
- return( 1 );
- return( x509_check_time( from, &now ) );
- }
- #else /* MBEDTLS_HAVE_TIME_DATE */
- int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
- {
- ((void) to);
- return( 0 );
- }
- int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
- {
- ((void) from);
- return( 0 );
- }
- #endif /* MBEDTLS_HAVE_TIME_DATE */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * Checkup routine
- */
- int mbedtls_x509_self_test( int verbose )
- {
- #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA1_C)
- int ret;
- uint32_t flags;
- mbedtls_x509_crt cacert;
- mbedtls_x509_crt clicert;
- if( verbose != 0 )
- mbedtls_printf( " X.509 certificate load: " );
- mbedtls_x509_crt_init( &clicert );
- ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
- mbedtls_test_cli_crt_len );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( ret );
- }
- mbedtls_x509_crt_init( &cacert );
- ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
- mbedtls_test_ca_crt_len );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( ret );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n X.509 signature verify: ");
- ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- return( ret );
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n\n");
- mbedtls_x509_crt_free( &cacert );
- mbedtls_x509_crt_free( &clicert );
- return( 0 );
- #else
- ((void) verbose);
- return( 0 );
- #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
- }
- #endif /* MBEDTLS_SELF_TEST */
- /* Amalgamated Release Mappings */
- #undef SAFE_SNPRINTF
- #endif /* MBEDTLS_X509_USE_C */
- /********* Start of file library/x509_create.c ************/
- /*
- * X.509 base functions for creating certificates / CSRs
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_CREATE_C)
- #include <string.h>
- typedef struct {
- const char *name;
- size_t name_len;
- const char*oid;
- } x509_attr_descriptor_t;
- #define ADD_STRLEN( s ) s, sizeof( s ) - 1
- static const x509_attr_descriptor_t x509_attrs[] =
- {
- { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN },
- { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN },
- { ADD_STRLEN( "C" ), MBEDTLS_OID_AT_COUNTRY },
- { ADD_STRLEN( "countryName" ), MBEDTLS_OID_AT_COUNTRY },
- { ADD_STRLEN( "O" ), MBEDTLS_OID_AT_ORGANIZATION },
- { ADD_STRLEN( "organizationName" ), MBEDTLS_OID_AT_ORGANIZATION },
- { ADD_STRLEN( "L" ), MBEDTLS_OID_AT_LOCALITY },
- { ADD_STRLEN( "locality" ), MBEDTLS_OID_AT_LOCALITY },
- { ADD_STRLEN( "R" ), MBEDTLS_OID_PKCS9_EMAIL },
- { ADD_STRLEN( "OU" ), MBEDTLS_OID_AT_ORG_UNIT },
- { ADD_STRLEN( "organizationalUnitName" ), MBEDTLS_OID_AT_ORG_UNIT },
- { ADD_STRLEN( "ST" ), MBEDTLS_OID_AT_STATE },
- { ADD_STRLEN( "stateOrProvinceName" ), MBEDTLS_OID_AT_STATE },
- { ADD_STRLEN( "emailAddress" ), MBEDTLS_OID_PKCS9_EMAIL },
- { ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER },
- { ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS },
- { ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE },
- { ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER },
- { ADD_STRLEN( "title" ), MBEDTLS_OID_AT_TITLE },
- { ADD_STRLEN( "surName" ), MBEDTLS_OID_AT_SUR_NAME },
- { ADD_STRLEN( "SN" ), MBEDTLS_OID_AT_SUR_NAME },
- { ADD_STRLEN( "givenName" ), MBEDTLS_OID_AT_GIVEN_NAME },
- { ADD_STRLEN( "GN" ), MBEDTLS_OID_AT_GIVEN_NAME },
- { ADD_STRLEN( "initials" ), MBEDTLS_OID_AT_INITIALS },
- { ADD_STRLEN( "pseudonym" ), MBEDTLS_OID_AT_PSEUDONYM },
- { ADD_STRLEN( "generationQualifier" ), MBEDTLS_OID_AT_GENERATION_QUALIFIER },
- { ADD_STRLEN( "domainComponent" ), MBEDTLS_OID_DOMAIN_COMPONENT },
- { ADD_STRLEN( "DC" ), MBEDTLS_OID_DOMAIN_COMPONENT },
- { NULL, 0, NULL }
- };
- static const char *x509_at_oid_from_name( const char *name, size_t name_len )
- {
- const x509_attr_descriptor_t *cur;
- for( cur = x509_attrs; cur->name != NULL; cur++ )
- if( cur->name_len == name_len &&
- strncmp( cur->name, name, name_len ) == 0 )
- break;
- return( cur->oid );
- }
- int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
- {
- int ret = 0;
- const char *s = name, *c = s;
- const char *end = s + strlen( s );
- const char *oid = NULL;
- int in_tag = 1;
- char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
- char *d = data;
- /* Clear existing chain if present */
- mbedtls_asn1_free_named_data_list( head );
- while( c <= end )
- {
- if( in_tag && *c == '=' )
- {
- if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL )
- {
- ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
- goto exit;
- }
- s = c + 1;
- in_tag = 0;
- d = data;
- }
- if( !in_tag && *c == '\\' && c != end )
- {
- c++;
- /* Check for valid escaped characters */
- if( c == end || *c != ',' )
- {
- ret = MBEDTLS_ERR_X509_INVALID_NAME;
- goto exit;
- }
- }
- else if( !in_tag && ( *c == ',' || c == end ) )
- {
- if( mbedtls_asn1_store_named_data( head, oid, strlen( oid ),
- (unsigned char *) data,
- d - data ) == NULL )
- {
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- }
- while( c < end && *(c + 1) == ' ' )
- c++;
- s = c + 1;
- in_tag = 1;
- }
- if( !in_tag && s != c + 1 )
- {
- *(d++) = *c;
- if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE )
- {
- ret = MBEDTLS_ERR_X509_INVALID_NAME;
- goto exit;
- }
- }
- c++;
- }
- exit:
- return( ret );
- }
- /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
- * to store the critical boolean for us
- */
- int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
- int critical, const unsigned char *val, size_t val_len )
- {
- mbedtls_asn1_named_data *cur;
- if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len,
- NULL, val_len + 1 ) ) == NULL )
- {
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- }
- cur->val.p[0] = critical;
- memcpy( cur->val.p + 1, val, val_len );
- return( 0 );
- }
- /*
- * RelativeDistinguishedName ::=
- * SET OF AttributeTypeAndValue
- *
- * AttributeTypeAndValue ::= SEQUENCE {
- * type AttributeType,
- * value AttributeValue }
- *
- * AttributeType ::= OBJECT IDENTIFIER
- *
- * AttributeValue ::= ANY DEFINED BY AttributeType
- */
- static int x509_write_name( unsigned char **p, unsigned char *start,
- const char *oid, size_t oid_len,
- const unsigned char *name, size_t name_len )
- {
- int ret;
- size_t len = 0;
- // Write PrintableString for all except MBEDTLS_OID_PKCS9_EMAIL
- //
- if( MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_EMAIL ) == oid_len &&
- memcmp( oid, MBEDTLS_OID_PKCS9_EMAIL, oid_len ) == 0 )
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_ia5_string( p, start,
- (const char *) name,
- name_len ) );
- }
- else
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_printable_string( p, start,
- (const char *) name,
- name_len ) );
- }
- // Write OID
- //
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SET ) );
- return( (int) len );
- }
- int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
- mbedtls_asn1_named_data *first )
- {
- int ret;
- size_t len = 0;
- mbedtls_asn1_named_data *cur = first;
- while( cur != NULL )
- {
- MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
- cur->oid.len,
- cur->val.p, cur->val.len ) );
- cur = cur->next;
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
- const char *oid, size_t oid_len,
- unsigned char *sig, size_t size )
- {
- int ret;
- size_t len = 0;
- if( *p < start || (size_t)( *p - start ) < size )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- len = size;
- (*p) -= len;
- memcpy( *p, sig, len );
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = 0;
- len += 1;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
- // Write OID
- //
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid,
- oid_len, 0 ) );
- return( (int) len );
- }
- static int x509_write_extension( unsigned char **p, unsigned char *start,
- mbedtls_asn1_named_data *ext )
- {
- int ret;
- size_t len = 0;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
- ext->val.len - 1 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
- if( ext->val.p[0] != 0 )
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) );
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p,
- ext->oid.len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- /*
- * Extension ::= SEQUENCE {
- * extnID OBJECT IDENTIFIER,
- * critical BOOLEAN DEFAULT FALSE,
- * extnValue OCTET STRING
- * -- contains the DER encoding of an ASN.1 value
- * -- corresponding to the extension type identified
- * -- by extnID
- * }
- */
- int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
- mbedtls_asn1_named_data *first )
- {
- int ret;
- size_t len = 0;
- mbedtls_asn1_named_data *cur_ext = first;
- while( cur_ext != NULL )
- {
- MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
- cur_ext = cur_ext->next;
- }
- return( (int) len );
- }
- #endif /* MBEDTLS_X509_CREATE_C */
- /********* Start of file library/x509_crl.c ************/
- /*
- * X.509 Certidicate Revocation List (CRL) parsing
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The ITU-T X.509 standard defines a certificate format for PKI.
- *
- * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
- * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
- * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
- *
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_CRL_PARSE_C)
- #include <string.h>
- #if defined(MBEDTLS_PEM_PARSE_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #include <stdio.h>
- #define mbedtls_free free
- #define mbedtls_calloc calloc
- #define mbedtls_snprintf snprintf
- #endif
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- #include <windows.h>
- #else
- #include <time.h>
- #endif
- #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
- #include <stdio.h>
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void x509_crl_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Version ::= INTEGER { v1(0), v2(1) }
- */
- static int x509_crl_get_version( unsigned char **p,
- const unsigned char *end,
- int *ver )
- {
- int ret;
- if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- {
- *ver = 0;
- return( 0 );
- }
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
- }
- return( 0 );
- }
- /*
- * X.509 CRL v2 extensions (no extensions parsed yet.)
- */
- static int x509_get_crl_ext( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_buf *ext )
- {
- int ret;
- size_t len = 0;
- /* Get explicit tag */
- if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( 0 );
- return( ret );
- }
- while( *p < end )
- {
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- *p += len;
- }
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * X.509 CRL v2 entry extensions (no extensions parsed yet.)
- */
- static int x509_get_crl_entry_ext( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_buf *ext )
- {
- int ret;
- size_t len = 0;
- /* OPTIONAL */
- if( end <= *p )
- return( 0 );
- ext->tag = **p;
- ext->p = *p;
- /*
- * Get CRL-entry extension sequence header
- * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
- */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- {
- ext->p = NULL;
- return( 0 );
- }
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- }
- end = *p + ext->len;
- if( end != *p + ext->len )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- while( *p < end )
- {
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- *p += len;
- }
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * X.509 CRL Entries
- */
- static int x509_get_entries( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_crl_entry *entry )
- {
- int ret;
- size_t entry_len;
- mbedtls_x509_crl_entry *cur_entry = entry;
- if( *p == end )
- return( 0 );
- if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len,
- MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( 0 );
- return( ret );
- }
- end = *p + entry_len;
- while( *p < end )
- {
- size_t len2;
- const unsigned char *end2;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len2,
- MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
- {
- return( ret );
- }
- cur_entry->raw.tag = **p;
- cur_entry->raw.p = *p;
- cur_entry->raw.len = len2;
- end2 = *p + len2;
- if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_x509_get_time( p, end2,
- &cur_entry->revocation_date ) ) != 0 )
- return( ret );
- if( ( ret = x509_get_crl_entry_ext( p, end2,
- &cur_entry->entry_ext ) ) != 0 )
- return( ret );
- if( *p < end )
- {
- cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) );
- if( cur_entry->next == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- cur_entry = cur_entry->next;
- }
- }
- return( 0 );
- }
- /*
- * Parse one CRLs in DER format and append it to the chained list
- */
- int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
- const unsigned char *buf, size_t buflen )
- {
- int ret;
- size_t len;
- unsigned char *p, *end;
- mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
- mbedtls_x509_crl *crl = chain;
- /*
- * Check for valid input
- */
- if( crl == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
- memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
- memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
- /*
- * Add new CRL on the end of the chain if needed.
- */
- while( crl->version != 0 && crl->next != NULL )
- crl = crl->next;
- if( crl->version != 0 && crl->next == NULL )
- {
- crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) );
- if( crl->next == NULL )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- }
- mbedtls_x509_crl_init( crl->next );
- crl = crl->next;
- }
- /*
- * Copy raw DER-encoded CRL
- */
- if( ( p = mbedtls_calloc( 1, buflen ) ) == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- memcpy( p, buf, buflen );
- crl->raw.p = p;
- crl->raw.len = buflen;
- end = p + buflen;
- /*
- * CertificateList ::= SEQUENCE {
- * tbsCertList TBSCertList,
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT );
- }
- if( len != (size_t) ( end - p ) )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- /*
- * TBSCertList ::= SEQUENCE {
- */
- crl->tbs.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- end = p + len;
- crl->tbs.len = end - crl->tbs.p;
- /*
- * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
- * -- if present, MUST be v2
- *
- * signature AlgorithmIdentifier
- */
- if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
- ( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- crl->version++;
- if( crl->version > 2 )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
- }
- if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1,
- &crl->sig_md, &crl->sig_pk,
- &crl->sig_opts ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
- }
- /*
- * issuer Name
- */
- crl->issuer_raw.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- crl->issuer_raw.len = p - crl->issuer_raw.p;
- /*
- * thisUpdate Time
- * nextUpdate Time OPTIONAL
- */
- if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 )
- {
- if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) &&
- ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA ) )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- }
- /*
- * revokedCertificates SEQUENCE OF SEQUENCE {
- * userCertificate CertificateSerialNumber,
- * revocationDate Time,
- * crlEntryExtensions Extensions OPTIONAL
- * -- if present, MUST be v2
- * } OPTIONAL
- */
- if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- /*
- * crlExtensions EXPLICIT Extensions OPTIONAL
- * -- if present, MUST be v2
- */
- if( crl->version == 2 )
- {
- ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
- if( ret != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- }
- if( p != end )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- end = crl->raw.p + crl->raw.len;
- /*
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING
- */
- if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- if( crl->sig_oid.len != sig_oid2.len ||
- memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
- sig_params1.len != sig_params2.len ||
- ( sig_params1.len != 0 &&
- memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_SIG_MISMATCH );
- }
- if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 )
- {
- mbedtls_x509_crl_free( crl );
- return( ret );
- }
- if( p != end )
- {
- mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- return( 0 );
- }
- /*
- * Parse one or more CRLs and add them to the chained list
- */
- int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen )
- {
- #if defined(MBEDTLS_PEM_PARSE_C)
- int ret;
- size_t use_len;
- mbedtls_pem_context pem;
- int is_pem = 0;
- if( chain == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- do
- {
- mbedtls_pem_init( &pem );
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( buflen == 0 || buf[buflen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN X509 CRL-----",
- "-----END X509 CRL-----",
- buf, NULL, 0, &use_len );
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- is_pem = 1;
- buflen -= use_len;
- buf += use_len;
- if( ( ret = mbedtls_x509_crl_parse_der( chain,
- pem.buf, pem.buflen ) ) != 0 )
- {
- return( ret );
- }
- mbedtls_pem_free( &pem );
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- {
- mbedtls_pem_free( &pem );
- return( ret );
- }
- }
- /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
- * And a valid CRL cannot be less than 1 byte anyway. */
- while( is_pem && buflen > 1 );
- if( is_pem )
- return( 0 );
- else
- #endif /* MBEDTLS_PEM_PARSE_C */
- return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) );
- }
- #if defined(MBEDTLS_FS_IO)
- /*
- * Load one or more CRLs and add them to the chained list
- */
- int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
- {
- int ret;
- size_t n;
- unsigned char *buf;
- if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
- return( ret );
- ret = mbedtls_x509_crl_parse( chain, buf, n );
- x509_crl_zeroize( buf, n );
- mbedtls_free( buf );
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- /*
- * Return an informational string about the certificate.
- */
- #define BEFORE_COLON 14
- #define BC "14"
- /*
- * Return an informational string about the CRL.
- */
- int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
- const mbedtls_x509_crl *crl )
- {
- int ret;
- size_t n;
- char *p;
- const mbedtls_x509_crl_entry *entry;
- p = buf;
- n = size;
- ret = mbedtls_snprintf( p, n, "%sCRL version : %d",
- prefix, crl->version );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_dn_gets( p, n, &crl->issuer );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%sthis update : " \
- "%04d-%02d-%02d %02d:%02d:%02d", prefix,
- crl->this_update.year, crl->this_update.mon,
- crl->this_update.day, crl->this_update.hour,
- crl->this_update.min, crl->this_update.sec );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%snext update : " \
- "%04d-%02d-%02d %02d:%02d:%02d", prefix,
- crl->next_update.year, crl->next_update.mon,
- crl->next_update.day, crl->next_update.hour,
- crl->next_update.min, crl->next_update.sec );
- MBEDTLS_X509_SAFE_SNPRINTF;
- entry = &crl->entry;
- ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:",
- prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- while( entry != NULL && entry->raw.len != 0 )
- {
- ret = mbedtls_snprintf( p, n, "\n%sserial number: ",
- prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_serial_gets( p, n, &entry->serial );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, " revocation date: " \
- "%04d-%02d-%02d %02d:%02d:%02d",
- entry->revocation_date.year, entry->revocation_date.mon,
- entry->revocation_date.day, entry->revocation_date.hour,
- entry->revocation_date.min, entry->revocation_date.sec );
- MBEDTLS_X509_SAFE_SNPRINTF;
- entry = entry->next;
- }
- ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
- crl->sig_opts );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- return( (int) ( size - n ) );
- }
- /*
- * Initialize a CRL chain
- */
- void mbedtls_x509_crl_init( mbedtls_x509_crl *crl )
- {
- memset( crl, 0, sizeof(mbedtls_x509_crl) );
- }
- /*
- * Unallocate all CRL data
- */
- void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
- {
- mbedtls_x509_crl *crl_cur = crl;
- mbedtls_x509_crl *crl_prv;
- mbedtls_x509_name *name_cur;
- mbedtls_x509_name *name_prv;
- mbedtls_x509_crl_entry *entry_cur;
- mbedtls_x509_crl_entry *entry_prv;
- if( crl == NULL )
- return;
- do
- {
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- mbedtls_free( crl_cur->sig_opts );
- #endif
- name_cur = crl_cur->issuer.next;
- while( name_cur != NULL )
- {
- name_prv = name_cur;
- name_cur = name_cur->next;
- x509_crl_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
- mbedtls_free( name_prv );
- }
- entry_cur = crl_cur->entry.next;
- while( entry_cur != NULL )
- {
- entry_prv = entry_cur;
- entry_cur = entry_cur->next;
- x509_crl_zeroize( entry_prv, sizeof( mbedtls_x509_crl_entry ) );
- mbedtls_free( entry_prv );
- }
- if( crl_cur->raw.p != NULL )
- {
- x509_crl_zeroize( crl_cur->raw.p, crl_cur->raw.len );
- mbedtls_free( crl_cur->raw.p );
- }
- crl_cur = crl_cur->next;
- }
- while( crl_cur != NULL );
- crl_cur = crl;
- do
- {
- crl_prv = crl_cur;
- crl_cur = crl_cur->next;
- x509_crl_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
- if( crl_prv != crl )
- mbedtls_free( crl_prv );
- }
- while( crl_cur != NULL );
- }
- /* Amalgamated Release Mappings */
- #undef SAFE_SNPRINTF
- #undef BEFORE_COLON
- #undef BC
- #endif /* MBEDTLS_X509_CRL_PARSE_C */
- /********* Start of file library/x509_crt.c ************/
- /*
- * X.509 certificate parsing and verification
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The ITU-T X.509 standard defines a certificate format for PKI.
- *
- * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
- * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
- * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
- *
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_CRT_PARSE_C)
- #include <stdio.h>
- #include <string.h>
- #if defined(MBEDTLS_PEM_PARSE_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #define mbedtls_free free
- #define mbedtls_calloc calloc
- #define mbedtls_snprintf snprintf
- #endif
- #if defined(MBEDTLS_THREADING_C)
- #endif
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- #include <windows.h>
- #else
- #include <time.h>
- #endif
- #if defined(MBEDTLS_FS_IO)
- #include <stdio.h>
- #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #endif /* !_WIN32 || EFIX64 || EFI32 */
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void x509_crt_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Default profile
- */
- const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
- {
- /* Hashes from SHA-1 and above */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
- 0xFFFFFFF, /* Any PK alg */
- 0xFFFFFFF, /* Any curve */
- 2048,
- };
- /*
- * Next-default profile
- */
- const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
- {
- /* Hashes from SHA-256 and above */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
- 0xFFFFFFF, /* Any PK alg */
- #if defined(MBEDTLS_ECP_C)
- /* Curves at or above 128-bit security level */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
- #else
- 0,
- #endif
- 2048,
- };
- /*
- * NSA Suite B Profile
- */
- const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
- {
- /* Only SHA-256 and 384 */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
- /* Only ECDSA */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ),
- #if defined(MBEDTLS_ECP_C)
- /* Only NIST P-256 and P-384 */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
- MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
- #else
- 0,
- #endif
- 0,
- };
- /*
- * Check md_alg against profile
- * Return 0 if md_alg acceptable for this profile, -1 otherwise
- */
- static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
- mbedtls_md_type_t md_alg )
- {
- if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
- return( 0 );
- return( -1 );
- }
- /*
- * Check pk_alg against profile
- * Return 0 if pk_alg acceptable for this profile, -1 otherwise
- */
- static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
- mbedtls_pk_type_t pk_alg )
- {
- if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
- return( 0 );
- return( -1 );
- }
- /*
- * Check key against profile
- * Return 0 if pk_alg acceptable for this profile, -1 otherwise
- */
- static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
- mbedtls_pk_type_t pk_alg,
- const mbedtls_pk_context *pk )
- {
- #if defined(MBEDTLS_RSA_C)
- if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
- {
- if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
- return( 0 );
- return( -1 );
- }
- #endif
- #if defined(MBEDTLS_ECP_C)
- if( pk_alg == MBEDTLS_PK_ECDSA ||
- pk_alg == MBEDTLS_PK_ECKEY ||
- pk_alg == MBEDTLS_PK_ECKEY_DH )
- {
- mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
- if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
- return( 0 );
- return( -1 );
- }
- #endif
- return( -1 );
- }
- /*
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- */
- static int x509_get_version( unsigned char **p,
- const unsigned char *end,
- int *ver )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- {
- *ver = 0;
- return( 0 );
- }
- return( ret );
- }
- end = *p + len;
- if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_VERSION +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- */
- static int x509_get_dates( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_time *from,
- mbedtls_x509_time *to )
- {
- int ret;
- size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
- end = *p + len;
- if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
- return( ret );
- if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
- return( ret );
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * X.509 v2/v3 unique identifier (not parsed)
- */
- static int x509_get_uid( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_buf *uid, int n )
- {
- int ret;
- if( *p == end )
- return( 0 );
- uid->tag = **p;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( 0 );
- return( ret );
- }
- uid->p = *p;
- *p += uid->len;
- return( 0 );
- }
- static int x509_get_basic_constraints( unsigned char **p,
- const unsigned char *end,
- int *ca_istrue,
- int *max_pathlen )
- {
- int ret;
- size_t len;
- /*
- * BasicConstraints ::= SEQUENCE {
- * cA BOOLEAN DEFAULT FALSE,
- * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
- */
- *ca_istrue = 0; /* DEFAULT FALSE */
- *max_pathlen = 0; /* endless */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( *p == end )
- return( 0 );
- if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- ret = mbedtls_asn1_get_int( p, end, ca_istrue );
- if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( *ca_istrue != 0 )
- *ca_istrue = 1;
- }
- if( *p == end )
- return( 0 );
- if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- (*max_pathlen)++;
- return( 0 );
- }
- static int x509_get_ns_cert_type( unsigned char **p,
- const unsigned char *end,
- unsigned char *ns_cert_type)
- {
- int ret;
- mbedtls_x509_bitstring bs = { 0, 0, NULL };
- if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( bs.len != 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- /* Get actual bitstring */
- *ns_cert_type = *bs.p;
- return( 0 );
- }
- static int x509_get_key_usage( unsigned char **p,
- const unsigned char *end,
- unsigned int *key_usage)
- {
- int ret;
- size_t i;
- mbedtls_x509_bitstring bs = { 0, 0, NULL };
- if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( bs.len < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- /* Get actual bitstring */
- *key_usage = 0;
- for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
- {
- *key_usage |= (unsigned int) bs.p[i] << (8*i);
- }
- return( 0 );
- }
- /*
- * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
- *
- * KeyPurposeId ::= OBJECT IDENTIFIER
- */
- static int x509_get_ext_key_usage( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_sequence *ext_key_usage)
- {
- int ret;
- if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- /* Sequence length must be >= 1 */
- if( ext_key_usage->buf.p == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- return( 0 );
- }
- /*
- * SubjectAltName ::= GeneralNames
- *
- * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
- *
- * GeneralName ::= CHOICE {
- * otherName [0] OtherName,
- * rfc822Name [1] IA5String,
- * dNSName [2] IA5String,
- * x400Address [3] ORAddress,
- * directoryName [4] Name,
- * ediPartyName [5] EDIPartyName,
- * uniformResourceIdentifier [6] IA5String,
- * iPAddress [7] OCTET STRING,
- * registeredID [8] OBJECT IDENTIFIER }
- *
- * OtherName ::= SEQUENCE {
- * type-id OBJECT IDENTIFIER,
- * value [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * EDIPartyName ::= SEQUENCE {
- * nameAssigner [0] DirectoryString OPTIONAL,
- * partyName [1] DirectoryString }
- *
- * NOTE: we only parse and use dNSName at this point.
- */
- static int x509_get_subject_alt_name( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_sequence *subject_alt_name )
- {
- int ret;
- size_t len, tag_len;
- mbedtls_asn1_buf *buf;
- unsigned char tag;
- mbedtls_asn1_sequence *cur = subject_alt_name;
- /* Get main sequence tag */
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( *p + len != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- while( *p < end )
- {
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- tag = **p;
- (*p)++;
- if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- /* Skip everything but DNS name */
- if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
- {
- *p += tag_len;
- continue;
- }
- /* Allocate and assign next pointer */
- if( cur->buf.p != NULL )
- {
- if( cur->next != NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
- cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
- if( cur->next == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_ALLOC_FAILED );
- cur = cur->next;
- }
- buf = &(cur->buf);
- buf->tag = tag;
- buf->p = *p;
- buf->len = tag_len;
- *p += buf->len;
- }
- /* Set final sequence entry's next pointer to NULL */
- cur->next = NULL;
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * X.509 v3 extensions
- *
- * TODO: Perform all of the basic constraints tests required by the RFC
- * TODO: Set values for undetected extensions to a sane default?
- *
- */
- static int x509_get_crt_ext( unsigned char **p,
- const unsigned char *end,
- mbedtls_x509_crt *crt )
- {
- int ret;
- size_t len;
- unsigned char *end_ext_data, *end_ext_octet;
- if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( 0 );
- return( ret );
- }
- while( *p < end )
- {
- /*
- * Extension ::= SEQUENCE {
- * extnID OBJECT IDENTIFIER,
- * critical BOOLEAN DEFAULT FALSE,
- * extnValue OCTET STRING }
- */
- mbedtls_x509_buf extn_oid = {0, 0, NULL};
- int is_critical = 0; /* DEFAULT FALSE */
- int ext_type = 0;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- end_ext_data = *p + len;
- /* Get extension ID */
- extn_oid.tag = **p;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- extn_oid.p = *p;
- *p += extn_oid.len;
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
- /* Get optional critical */
- if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
- ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- /* Data should be octet string type */
- if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
- MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
- end_ext_octet = *p + len;
- if( end_ext_octet != end_ext_data )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- /*
- * Detect supported extensions
- */
- ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
- if( ret != 0 )
- {
- /* No parser found, skip extension */
- *p = end_ext_octet;
- #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
- if( is_critical )
- {
- /* Data is marked as critical: fail */
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- }
- #endif
- continue;
- }
- /* Forbid repeated extensions */
- if( ( crt->ext_types & ext_type ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
- crt->ext_types |= ext_type;
- switch( ext_type )
- {
- case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
- /* Parse basic constraints */
- if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
- &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
- return( ret );
- break;
- case MBEDTLS_X509_EXT_KEY_USAGE:
- /* Parse key usage */
- if( ( ret = x509_get_key_usage( p, end_ext_octet,
- &crt->key_usage ) ) != 0 )
- return( ret );
- break;
- case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
- /* Parse extended key usage */
- if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
- &crt->ext_key_usage ) ) != 0 )
- return( ret );
- break;
- case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
- /* Parse subject alt name */
- if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
- &crt->subject_alt_names ) ) != 0 )
- return( ret );
- break;
- case MBEDTLS_X509_EXT_NS_CERT_TYPE:
- /* Parse netscape certificate type */
- if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
- &crt->ns_cert_type ) ) != 0 )
- return( ret );
- break;
- default:
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
- }
- }
- if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- return( 0 );
- }
- /*
- * Parse and fill a single X.509 certificate in DER format
- */
- static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
- size_t buflen )
- {
- int ret;
- size_t len;
- unsigned char *p, *end, *crt_end;
- mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
- memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
- memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
- memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
- /*
- * Check for valid input
- */
- if( crt == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- p = mbedtls_calloc( 1, len = buflen );
- if( p == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- memcpy( p, buf, buflen );
- crt->raw.p = p;
- crt->raw.len = len;
- end = p + len;
- /*
- * Certificate ::= SEQUENCE {
- * tbsCertificate TBSCertificate,
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT );
- }
- if( len > (size_t) ( end - p ) )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- crt_end = p + len;
- /*
- * TBSCertificate ::= SEQUENCE {
- */
- crt->tbs.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- end = p + len;
- crt->tbs.len = end - crt->tbs.p;
- /*
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- *
- * CertificateSerialNumber ::= INTEGER
- *
- * signature AlgorithmIdentifier
- */
- if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
- ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
- ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid,
- &sig_params1 ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- crt->version++;
- if( crt->version > 3 )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
- }
- if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
- &crt->sig_md, &crt->sig_pk,
- &crt->sig_opts ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- /*
- * issuer Name
- */
- crt->issuer_raw.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- crt->issuer_raw.len = p - crt->issuer_raw.p;
- /*
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- *
- */
- if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
- &crt->valid_to ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- /*
- * subject Name
- */
- crt->subject_raw.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- crt->subject_raw.len = p - crt->subject_raw.p;
- /*
- * SubjectPublicKeyInfo
- */
- if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- /*
- * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- * -- If present, version shall be v2 or v3
- * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- * -- If present, version shall be v2 or v3
- * extensions [3] EXPLICIT Extensions OPTIONAL
- * -- If present, version shall be v3
- */
- if( crt->version == 2 || crt->version == 3 )
- {
- ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
- if( ret != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- }
- if( crt->version == 2 || crt->version == 3 )
- {
- ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
- if( ret != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- }
- #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
- if( crt->version == 3 )
- #endif
- {
- ret = x509_get_crt_ext( &p, end, crt );
- if( ret != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- }
- if( p != end )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- end = crt_end;
- /*
- * }
- * -- end of TBSCertificate
- *
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING
- */
- if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- if( crt->sig_oid.len != sig_oid2.len ||
- memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
- sig_params1.len != sig_params2.len ||
- ( sig_params1.len != 0 &&
- memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_SIG_MISMATCH );
- }
- if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
- {
- mbedtls_x509_crt_free( crt );
- return( ret );
- }
- if( p != end )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- return( 0 );
- }
- /*
- * Parse one X.509 certificate in DER format from a buffer and add them to a
- * chained list
- */
- int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
- size_t buflen )
- {
- int ret;
- mbedtls_x509_crt *crt = chain, *prev = NULL;
- /*
- * Check for valid input
- */
- if( crt == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- while( crt->version != 0 && crt->next != NULL )
- {
- prev = crt;
- crt = crt->next;
- }
- /*
- * Add new certificate on the end of the chain if needed.
- */
- if( crt->version != 0 && crt->next == NULL )
- {
- crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
- if( crt->next == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- prev = crt;
- mbedtls_x509_crt_init( crt->next );
- crt = crt->next;
- }
- if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
- {
- if( prev )
- prev->next = NULL;
- if( crt != chain )
- mbedtls_free( crt );
- return( ret );
- }
- return( 0 );
- }
- /*
- * Parse one or more PEM certificates from a buffer and add them to the chained
- * list
- */
- int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
- {
- int success = 0, first_error = 0, total_failed = 0;
- int buf_format = MBEDTLS_X509_FORMAT_DER;
- /*
- * Check for valid input
- */
- if( chain == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- /*
- * Determine buffer content. Buffer contains either one DER certificate or
- * one or more PEM certificates.
- */
- #if defined(MBEDTLS_PEM_PARSE_C)
- if( buflen != 0 && buf[buflen - 1] == '\0' &&
- strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
- {
- buf_format = MBEDTLS_X509_FORMAT_PEM;
- }
- #endif
- if( buf_format == MBEDTLS_X509_FORMAT_DER )
- return mbedtls_x509_crt_parse_der( chain, buf, buflen );
- #if defined(MBEDTLS_PEM_PARSE_C)
- if( buf_format == MBEDTLS_X509_FORMAT_PEM )
- {
- int ret;
- mbedtls_pem_context pem;
- /* 1 rather than 0 since the terminating NULL byte is counted in */
- while( buflen > 1 )
- {
- size_t use_len;
- mbedtls_pem_init( &pem );
- /* If we get there, we know the string is null-terminated */
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN CERTIFICATE-----",
- "-----END CERTIFICATE-----",
- buf, NULL, 0, &use_len );
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- buflen -= use_len;
- buf += use_len;
- }
- else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
- {
- return( ret );
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- {
- mbedtls_pem_free( &pem );
- /*
- * PEM header and footer were found
- */
- buflen -= use_len;
- buf += use_len;
- if( first_error == 0 )
- first_error = ret;
- total_failed++;
- continue;
- }
- else
- break;
- ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
- mbedtls_pem_free( &pem );
- if( ret != 0 )
- {
- /*
- * Quit parsing on a memory error
- */
- if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
- return( ret );
- if( first_error == 0 )
- first_error = ret;
- total_failed++;
- continue;
- }
- success = 1;
- }
- }
- #endif /* MBEDTLS_PEM_PARSE_C */
- if( success )
- return( total_failed );
- else if( first_error )
- return( first_error );
- else
- return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
- }
- #if defined(MBEDTLS_FS_IO)
- /*
- * Load one or more certificates and add them to the chained list
- */
- int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
- {
- int ret;
- size_t n;
- unsigned char *buf;
- if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
- return( ret );
- ret = mbedtls_x509_crt_parse( chain, buf, n );
- x509_crt_zeroize( buf, n );
- mbedtls_free( buf );
- return( ret );
- }
- int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
- {
- int ret = 0;
- #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- int w_ret;
- WCHAR szDir[MAX_PATH];
- char filename[MAX_PATH];
- char *p;
- size_t len = strlen( path );
- WIN32_FIND_DATAW file_data;
- HANDLE hFind;
- if( len > MAX_PATH - 3 )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- memset( szDir, 0, sizeof(szDir) );
- memset( filename, 0, MAX_PATH );
- memcpy( filename, path, len );
- filename[len++] = '\\';
- p = filename + len;
- filename[len++] = '*';
- w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
- MAX_PATH - 3 );
- if( w_ret == 0 )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- hFind = FindFirstFileW( szDir, &file_data );
- if( hFind == INVALID_HANDLE_VALUE )
- return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
- len = MAX_PATH - len;
- do
- {
- memset( p, 0, len );
- if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
- continue;
- w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
- lstrlenW( file_data.cFileName ),
- p, (int) len - 1,
- NULL, NULL );
- if( w_ret == 0 )
- return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
- w_ret = mbedtls_x509_crt_parse_file( chain, filename );
- if( w_ret < 0 )
- ret++;
- else
- ret += w_ret;
- }
- while( FindNextFileW( hFind, &file_data ) != 0 );
- if( GetLastError() != ERROR_NO_MORE_FILES )
- ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
- FindClose( hFind );
- #else /* _WIN32 */
- int t_ret;
- struct stat sb;
- struct dirent *entry;
- char entry_name[255];
- DIR *dir = opendir( path );
- if( dir == NULL )
- return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
- #if defined(MBEDTLS_THREADING_PTHREAD)
- if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
- {
- closedir( dir );
- return( ret );
- }
- #endif
- while( ( entry = readdir( dir ) ) != NULL )
- {
- mbedtls_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name );
- if( stat( entry_name, &sb ) == -1 )
- {
- closedir( dir );
- ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
- goto cleanup;
- }
- if( !S_ISREG( sb.st_mode ) )
- continue;
- // Ignore parse errors
- //
- t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
- if( t_ret < 0 )
- ret++;
- else
- ret += t_ret;
- }
- closedir( dir );
- cleanup:
- #if defined(MBEDTLS_THREADING_PTHREAD)
- if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
- ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
- #endif
- #endif /* _WIN32 */
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- static int x509_info_subject_alt_name( char **buf, size_t *size,
- const mbedtls_x509_sequence *subject_alt_name )
- {
- size_t i;
- size_t n = *size;
- char *p = *buf;
- const mbedtls_x509_sequence *cur = subject_alt_name;
- const char *sep = "";
- size_t sep_len = 0;
- while( cur != NULL )
- {
- if( cur->buf.len + sep_len >= n )
- {
- *p = '\0';
- return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
- }
- n -= cur->buf.len + sep_len;
- for( i = 0; i < sep_len; i++ )
- *p++ = sep[i];
- for( i = 0; i < cur->buf.len; i++ )
- *p++ = cur->buf.p[i];
- sep = ", ";
- sep_len = 2;
- cur = cur->next;
- }
- *p = '\0';
- *size = n;
- *buf = p;
- return( 0 );
- }
- #define PRINT_ITEM(i) \
- { \
- ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
- MBEDTLS_X509_SAFE_SNPRINTF; \
- sep = ", "; \
- }
- #define CERT_TYPE(type,name) \
- if( ns_cert_type & type ) \
- PRINT_ITEM( name );
- static int x509_info_cert_type( char **buf, size_t *size,
- unsigned char ns_cert_type )
- {
- int ret;
- size_t n = *size;
- char *p = *buf;
- const char *sep = "";
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" );
- CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" );
- *size = n;
- *buf = p;
- return( 0 );
- }
- #define KEY_USAGE(code,name) \
- if( key_usage & code ) \
- PRINT_ITEM( name );
- static int x509_info_key_usage( char **buf, size_t *size,
- unsigned int key_usage )
- {
- int ret;
- size_t n = *size;
- char *p = *buf;
- const char *sep = "";
- KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" );
- KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" );
- KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" );
- KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" );
- KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" );
- KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" );
- KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" );
- KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" );
- KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" );
- *size = n;
- *buf = p;
- return( 0 );
- }
- static int x509_info_ext_key_usage( char **buf, size_t *size,
- const mbedtls_x509_sequence *extended_key_usage )
- {
- int ret;
- const char *desc;
- size_t n = *size;
- char *p = *buf;
- const mbedtls_x509_sequence *cur = extended_key_usage;
- const char *sep = "";
- while( cur != NULL )
- {
- if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
- desc = "???";
- ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
- MBEDTLS_X509_SAFE_SNPRINTF;
- sep = ", ";
- cur = cur->next;
- }
- *size = n;
- *buf = p;
- return( 0 );
- }
- /*
- * Return an informational string about the certificate.
- */
- #define BEFORE_COLON 18
- #define BC "18"
- int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
- const mbedtls_x509_crt *crt )
- {
- int ret;
- size_t n;
- char *p;
- char key_size_str[BEFORE_COLON];
- p = buf;
- n = size;
- ret = mbedtls_snprintf( p, n, "%scert. version : %d\n",
- prefix, crt->version );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "%sserial number : ",
- prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_dn_gets( p, n, &crt->issuer );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%sissued on : " \
- "%04d-%02d-%02d %02d:%02d:%02d", prefix,
- crt->valid_from.year, crt->valid_from.mon,
- crt->valid_from.day, crt->valid_from.hour,
- crt->valid_from.min, crt->valid_from.sec );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \
- "%04d-%02d-%02d %02d:%02d:%02d", prefix,
- crt->valid_to.year, crt->valid_to.mon,
- crt->valid_to.day, crt->valid_to.hour,
- crt->valid_to.min, crt->valid_to.sec );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
- crt->sig_md, crt->sig_opts );
- MBEDTLS_X509_SAFE_SNPRINTF;
- /* Key size */
- if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
- mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
- {
- return( ret );
- }
- ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
- (int) mbedtls_pk_get_bitlen( &crt->pk ) );
- MBEDTLS_X509_SAFE_SNPRINTF;
- /*
- * Optional extensions
- */
- if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
- {
- ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
- crt->ca_istrue ? "true" : "false" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- if( crt->max_pathlen > 0 )
- {
- ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- }
- if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
- {
- ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- if( ( ret = x509_info_subject_alt_name( &p, &n,
- &crt->subject_alt_names ) ) != 0 )
- return( ret );
- }
- if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
- {
- ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
- return( ret );
- }
- if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
- {
- ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
- return( ret );
- }
- if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
- {
- ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- if( ( ret = x509_info_ext_key_usage( &p, &n,
- &crt->ext_key_usage ) ) != 0 )
- return( ret );
- }
- ret = mbedtls_snprintf( p, n, "\n" );
- MBEDTLS_X509_SAFE_SNPRINTF;
- return( (int) ( size - n ) );
- }
- struct x509_crt_verify_string {
- int code;
- const char *string;
- };
- static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
- { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" },
- { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" },
- { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" },
- { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" },
- { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" },
- { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" },
- { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" },
- { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" },
- { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" },
- { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" },
- { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" },
- { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" },
- { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
- { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" },
- { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." },
- { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
- { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
- { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." },
- { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
- { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
- { 0, NULL }
- };
- int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
- uint32_t flags )
- {
- int ret;
- const struct x509_crt_verify_string *cur;
- char *p = buf;
- size_t n = size;
- for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
- {
- if( ( flags & cur->code ) == 0 )
- continue;
- ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
- MBEDTLS_X509_SAFE_SNPRINTF;
- flags ^= cur->code;
- }
- if( flags != 0 )
- {
- ret = mbedtls_snprintf( p, n, "%sUnknown reason "
- "(this should not happen)\n", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- }
- return( (int) ( size - n ) );
- }
- #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
- unsigned int usage )
- {
- unsigned int usage_must, usage_may;
- unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
- | MBEDTLS_X509_KU_DECIPHER_ONLY;
- if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
- return( 0 );
- usage_must = usage & ~may_mask;
- if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- usage_may = usage & may_mask;
- if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- return( 0 );
- }
- #endif
- #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
- int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
- const char *usage_oid,
- size_t usage_len )
- {
- const mbedtls_x509_sequence *cur;
- /* Extension is not mandatory, absent means no restriction */
- if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
- return( 0 );
- /*
- * Look for the requested usage (or wildcard ANY) in our list
- */
- for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
- {
- const mbedtls_x509_buf *cur_oid = &cur->buf;
- if( cur_oid->len == usage_len &&
- memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
- {
- return( 0 );
- }
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
- return( 0 );
- }
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- }
- #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
- #if defined(MBEDTLS_X509_CRL_PARSE_C)
- /*
- * Return 1 if the certificate is revoked, or 0 otherwise.
- */
- int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
- {
- const mbedtls_x509_crl_entry *cur = &crl->entry;
- while( cur != NULL && cur->serial.len != 0 )
- {
- if( crt->serial.len == cur->serial.len &&
- memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
- {
- if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
- return( 1 );
- }
- cur = cur->next;
- }
- return( 0 );
- }
- /*
- * Check that the given certificate is valid according to the CRL.
- */
- static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
- mbedtls_x509_crl *crl_list,
- const mbedtls_x509_crt_profile *profile )
- {
- int flags = 0;
- unsigned char hash[MBEDTLS_MD_MAX_SIZE];
- const mbedtls_md_info_t *md_info;
- if( ca == NULL )
- return( flags );
- /*
- * TODO: What happens if no CRL is present?
- * Suggestion: Revocation state should be unknown if no CRL is present.
- * For backwards compatibility this is not yet implemented.
- */
- while( crl_list != NULL )
- {
- if( crl_list->version == 0 ||
- crl_list->issuer_raw.len != ca->subject_raw.len ||
- memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
- crl_list->issuer_raw.len ) != 0 )
- {
- crl_list = crl_list->next;
- continue;
- }
- /*
- * Check if the CA is configured to sign CRLs
- */
- #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
- {
- flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
- break;
- }
- #endif
- /*
- * Check if CRL is correctly signed by the trusted CA
- */
- if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
- flags |= MBEDTLS_X509_BADCRL_BAD_MD;
- if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
- flags |= MBEDTLS_X509_BADCRL_BAD_PK;
- md_info = mbedtls_md_info_from_type( crl_list->sig_md );
- if( md_info == NULL )
- {
- /*
- * Cannot check 'unknown' hash
- */
- flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
- break;
- }
- mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
- if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
- flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
- if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
- crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
- crl_list->sig.p, crl_list->sig.len ) != 0 )
- {
- flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
- break;
- }
- /*
- * Check for validity of CRL (Do not drop out)
- */
- if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
- flags |= MBEDTLS_X509_BADCRL_EXPIRED;
- if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
- flags |= MBEDTLS_X509_BADCRL_FUTURE;
- /*
- * Check if certificate is revoked
- */
- if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
- {
- flags |= MBEDTLS_X509_BADCERT_REVOKED;
- break;
- }
- crl_list = crl_list->next;
- }
- return( flags );
- }
- #endif /* MBEDTLS_X509_CRL_PARSE_C */
- /*
- * Like memcmp, but case-insensitive and always returns -1 if different
- */
- static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
- {
- size_t i;
- unsigned char diff;
- const unsigned char *n1 = s1, *n2 = s2;
- for( i = 0; i < len; i++ )
- {
- diff = n1[i] ^ n2[i];
- if( diff == 0 )
- continue;
- if( diff == 32 &&
- ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
- ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
- {
- continue;
- }
- return( -1 );
- }
- return( 0 );
- }
- /*
- * Return 0 if name matches wildcard, -1 otherwise
- */
- static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
- {
- size_t i;
- size_t cn_idx = 0, cn_len = strlen( cn );
- if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
- return( 0 );
- for( i = 0; i < cn_len; ++i )
- {
- if( cn[i] == '.' )
- {
- cn_idx = i;
- break;
- }
- }
- if( cn_idx == 0 )
- return( -1 );
- if( cn_len - cn_idx == name->len - 1 &&
- x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
- {
- return( 0 );
- }
- return( -1 );
- }
- /*
- * Compare two X.509 strings, case-insensitive, and allowing for some encoding
- * variations (but not all).
- *
- * Return 0 if equal, -1 otherwise.
- */
- static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
- {
- if( a->tag == b->tag &&
- a->len == b->len &&
- memcmp( a->p, b->p, b->len ) == 0 )
- {
- return( 0 );
- }
- if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
- ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
- a->len == b->len &&
- x509_memcasecmp( a->p, b->p, b->len ) == 0 )
- {
- return( 0 );
- }
- return( -1 );
- }
- /*
- * Compare two X.509 Names (aka rdnSequence).
- *
- * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
- * we sometimes return unequal when the full algorithm would return equal,
- * but never the other way. (In particular, we don't do Unicode normalisation
- * or space folding.)
- *
- * Return 0 if equal, -1 otherwise.
- */
- static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
- {
- /* Avoid recursion, it might not be optimised by the compiler */
- while( a != NULL || b != NULL )
- {
- if( a == NULL || b == NULL )
- return( -1 );
- /* type */
- if( a->oid.tag != b->oid.tag ||
- a->oid.len != b->oid.len ||
- memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
- {
- return( -1 );
- }
- /* value */
- if( x509_string_cmp( &a->val, &b->val ) != 0 )
- return( -1 );
- /* structure of the list of sets */
- if( a->next_merged != b->next_merged )
- return( -1 );
- a = a->next;
- b = b->next;
- }
- /* a == NULL == b */
- return( 0 );
- }
- /*
- * Check if 'parent' is a suitable parent (signing CA) for 'child'.
- * Return 0 if yes, -1 if not.
- *
- * top means parent is a locally-trusted certificate
- * bottom means child is the end entity cert
- */
- static int x509_crt_check_parent( const mbedtls_x509_crt *child,
- const mbedtls_x509_crt *parent,
- int top, int bottom )
- {
- int need_ca_bit;
- /* Parent must be the issuer */
- if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
- return( -1 );
- /* Parent must have the basicConstraints CA bit set as a general rule */
- need_ca_bit = 1;
- /* Exception: v1/v2 certificates that are locally trusted. */
- if( top && parent->version < 3 )
- need_ca_bit = 0;
- /* Exception: self-signed end-entity certs that are locally trusted. */
- if( top && bottom &&
- child->raw.len == parent->raw.len &&
- memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 )
- {
- need_ca_bit = 0;
- }
- if( need_ca_bit && ! parent->ca_istrue )
- return( -1 );
- #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
- if( need_ca_bit &&
- mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
- {
- return( -1 );
- }
- #endif
- return( 0 );
- }
- static int x509_crt_verify_top(
- mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const mbedtls_x509_crt_profile *profile,
- int path_cnt, int self_cnt, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
- {
- int ret;
- uint32_t ca_flags = 0;
- int check_path_cnt;
- unsigned char hash[MBEDTLS_MD_MAX_SIZE];
- const mbedtls_md_info_t *md_info;
- if( mbedtls_x509_time_is_past( &child->valid_to ) )
- *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
- if( mbedtls_x509_time_is_future( &child->valid_from ) )
- *flags |= MBEDTLS_X509_BADCERT_FUTURE;
- if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
- if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
- /*
- * Child is the top of the chain. Check against the trust_ca list.
- */
- *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
- md_info = mbedtls_md_info_from_type( child->sig_md );
- if( md_info == NULL )
- {
- /*
- * Cannot check 'unknown', no need to try any CA
- */
- trust_ca = NULL;
- }
- else
- mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
- for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
- {
- if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
- continue;
- check_path_cnt = path_cnt + 1;
- /*
- * Reduce check_path_cnt to check against if top of the chain is
- * the same as the trusted CA
- */
- if( child->subject_raw.len == trust_ca->subject_raw.len &&
- memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
- child->issuer_raw.len ) == 0 )
- {
- check_path_cnt--;
- }
- /* Self signed certificates do not count towards the limit */
- if( trust_ca->max_pathlen > 0 &&
- trust_ca->max_pathlen < check_path_cnt - self_cnt )
- {
- continue;
- }
- if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
- child->sig_md, hash, mbedtls_md_get_size( md_info ),
- child->sig.p, child->sig.len ) != 0 )
- {
- continue;
- }
- /*
- * Top of chain is signed by a trusted CA
- */
- *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
- if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
- break;
- }
- /*
- * If top of chain is not the same as the trusted CA send a verify request
- * to the callback for any issues with validity and CRL presence for the
- * trusted CA certificate.
- */
- if( trust_ca != NULL &&
- ( child->subject_raw.len != trust_ca->subject_raw.len ||
- memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
- child->issuer_raw.len ) != 0 ) )
- {
- #if defined(MBEDTLS_X509_CRL_PARSE_C)
- /* Check trusted CA's CRL for the chain's top crt */
- *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile );
- #else
- ((void) ca_crl);
- #endif
- if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
- ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED;
- if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
- ca_flags |= MBEDTLS_X509_BADCERT_FUTURE;
- if( NULL != f_vrfy )
- {
- if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
- &ca_flags ) ) != 0 )
- {
- return( ret );
- }
- }
- }
- /* Call callback on top cert */
- if( NULL != f_vrfy )
- {
- if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
- return( ret );
- }
- *flags |= ca_flags;
- return( 0 );
- }
- static int x509_crt_verify_child(
- mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
- mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
- const mbedtls_x509_crt_profile *profile,
- int path_cnt, int self_cnt, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
- {
- int ret;
- uint32_t parent_flags = 0;
- unsigned char hash[MBEDTLS_MD_MAX_SIZE];
- mbedtls_x509_crt *grandparent;
- const mbedtls_md_info_t *md_info;
- /* Counting intermediate self signed certificates */
- if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 )
- self_cnt++;
- /* path_cnt is 0 for the first intermediate CA */
- if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
- {
- *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
- return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
- }
- if( mbedtls_x509_time_is_past( &child->valid_to ) )
- *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
- if( mbedtls_x509_time_is_future( &child->valid_from ) )
- *flags |= MBEDTLS_X509_BADCERT_FUTURE;
- if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
- if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
- md_info = mbedtls_md_info_from_type( child->sig_md );
- if( md_info == NULL )
- {
- /*
- * Cannot check 'unknown' hash
- */
- *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
- }
- else
- {
- mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
- if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
- if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
- child->sig_md, hash, mbedtls_md_get_size( md_info ),
- child->sig.p, child->sig.len ) != 0 )
- {
- *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
- }
- }
- #if defined(MBEDTLS_X509_CRL_PARSE_C)
- /* Check trusted CA's CRL for the given crt */
- *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile );
- #endif
- /* Look for a grandparent in trusted CAs */
- for( grandparent = trust_ca;
- grandparent != NULL;
- grandparent = grandparent->next )
- {
- if( x509_crt_check_parent( parent, grandparent,
- 0, path_cnt == 0 ) == 0 )
- break;
- }
- if( grandparent != NULL )
- {
- ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
- path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy );
- if( ret != 0 )
- return( ret );
- }
- else
- {
- /* Look for a grandparent upwards the chain */
- for( grandparent = parent->next;
- grandparent != NULL;
- grandparent = grandparent->next )
- {
- /* +2 because the current step is not yet accounted for
- * and because max_pathlen is one higher than it should be.
- * Also self signed certificates do not count to the limit. */
- if( grandparent->max_pathlen > 0 &&
- grandparent->max_pathlen < 2 + path_cnt - self_cnt )
- {
- continue;
- }
- if( x509_crt_check_parent( parent, grandparent,
- 0, path_cnt == 0 ) == 0 )
- break;
- }
- /* Is our parent part of the chain or at the top? */
- if( grandparent != NULL )
- {
- ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
- profile, path_cnt + 1, self_cnt, &parent_flags,
- f_vrfy, p_vrfy );
- if( ret != 0 )
- return( ret );
- }
- else
- {
- ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
- path_cnt + 1, self_cnt, &parent_flags,
- f_vrfy, p_vrfy );
- if( ret != 0 )
- return( ret );
- }
- }
- /* child is verified to be a child of the parent, call verify callback */
- if( NULL != f_vrfy )
- if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
- return( ret );
- *flags |= parent_flags;
- return( 0 );
- }
- /*
- * Verify the certificate validity
- */
- int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
- mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const char *cn, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
- {
- return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl,
- &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) );
- }
- /*
- * Verify the certificate validity, with profile
- */
- int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
- mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const mbedtls_x509_crt_profile *profile,
- const char *cn, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
- {
- size_t cn_len;
- int ret;
- int pathlen = 0, selfsigned = 0;
- mbedtls_x509_crt *parent;
- mbedtls_x509_name *name;
- mbedtls_x509_sequence *cur = NULL;
- mbedtls_pk_type_t pk_type;
- if( profile == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- *flags = 0;
- if( cn != NULL )
- {
- name = &crt->subject;
- cn_len = strlen( cn );
- if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
- {
- cur = &crt->subject_alt_names;
- while( cur != NULL )
- {
- if( cur->buf.len == cn_len &&
- x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
- break;
- if( cur->buf.len > 2 &&
- memcmp( cur->buf.p, "*.", 2 ) == 0 &&
- x509_check_wildcard( cn, &cur->buf ) == 0 )
- {
- break;
- }
- cur = cur->next;
- }
- if( cur == NULL )
- *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
- }
- else
- {
- while( name != NULL )
- {
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 )
- {
- if( name->val.len == cn_len &&
- x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
- break;
- if( name->val.len > 2 &&
- memcmp( name->val.p, "*.", 2 ) == 0 &&
- x509_check_wildcard( cn, &name->val ) == 0 )
- break;
- }
- name = name->next;
- }
- if( name == NULL )
- *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
- }
- }
- /* Check the type and size of the key */
- pk_type = mbedtls_pk_get_type( &crt->pk );
- if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
- if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
- *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
- /* Look for a parent in trusted CAs */
- for( parent = trust_ca; parent != NULL; parent = parent->next )
- {
- if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
- break;
- }
- if( parent != NULL )
- {
- ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
- pathlen, selfsigned, flags, f_vrfy, p_vrfy );
- if( ret != 0 )
- return( ret );
- }
- else
- {
- /* Look for a parent upwards the chain */
- for( parent = crt->next; parent != NULL; parent = parent->next )
- if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
- break;
- /* Are we part of the chain or at the top? */
- if( parent != NULL )
- {
- ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
- pathlen, selfsigned, flags, f_vrfy, p_vrfy );
- if( ret != 0 )
- return( ret );
- }
- else
- {
- ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
- pathlen, selfsigned, flags, f_vrfy, p_vrfy );
- if( ret != 0 )
- return( ret );
- }
- }
- if( *flags != 0 )
- return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
- return( 0 );
- }
- /*
- * Initialize a certificate chain
- */
- void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
- {
- memset( crt, 0, sizeof(mbedtls_x509_crt) );
- }
- /*
- * Unallocate all certificate data
- */
- void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
- {
- mbedtls_x509_crt *cert_cur = crt;
- mbedtls_x509_crt *cert_prv;
- mbedtls_x509_name *name_cur;
- mbedtls_x509_name *name_prv;
- mbedtls_x509_sequence *seq_cur;
- mbedtls_x509_sequence *seq_prv;
- if( crt == NULL )
- return;
- do
- {
- mbedtls_pk_free( &cert_cur->pk );
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- mbedtls_free( cert_cur->sig_opts );
- #endif
- name_cur = cert_cur->issuer.next;
- while( name_cur != NULL )
- {
- name_prv = name_cur;
- name_cur = name_cur->next;
- x509_crt_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
- mbedtls_free( name_prv );
- }
- name_cur = cert_cur->subject.next;
- while( name_cur != NULL )
- {
- name_prv = name_cur;
- name_cur = name_cur->next;
- x509_crt_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
- mbedtls_free( name_prv );
- }
- seq_cur = cert_cur->ext_key_usage.next;
- while( seq_cur != NULL )
- {
- seq_prv = seq_cur;
- seq_cur = seq_cur->next;
- x509_crt_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
- mbedtls_free( seq_prv );
- }
- seq_cur = cert_cur->subject_alt_names.next;
- while( seq_cur != NULL )
- {
- seq_prv = seq_cur;
- seq_cur = seq_cur->next;
- x509_crt_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
- mbedtls_free( seq_prv );
- }
- if( cert_cur->raw.p != NULL )
- {
- x509_crt_zeroize( cert_cur->raw.p, cert_cur->raw.len );
- mbedtls_free( cert_cur->raw.p );
- }
- cert_cur = cert_cur->next;
- }
- while( cert_cur != NULL );
- cert_cur = crt;
- do
- {
- cert_prv = cert_cur;
- cert_cur = cert_cur->next;
- x509_crt_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
- if( cert_prv != crt )
- mbedtls_free( cert_prv );
- }
- while( cert_cur != NULL );
- }
- /* Amalgamated Release Mappings */
- #undef SAFE_SNPRINTF
- #undef BEFORE_COLON
- #undef BC
- #endif /* MBEDTLS_X509_CRT_PARSE_C */
- /********* Start of file library/x509_csr.c ************/
- /*
- * X.509 Certificate Signing Request (CSR) parsing
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * The ITU-T X.509 standard defines a certificate format for PKI.
- *
- * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
- * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
- * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
- *
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
- * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_CSR_PARSE_C)
- #include <string.h>
- #if defined(MBEDTLS_PEM_PARSE_C)
- #endif
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdlib.h>
- #include <stdio.h>
- #define mbedtls_free free
- #define mbedtls_calloc calloc
- #define mbedtls_snprintf snprintf
- #endif
- #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
- #include <stdio.h>
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void x509_csr_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * Version ::= INTEGER { v1(0) }
- */
- static int x509_csr_get_version( unsigned char **p,
- const unsigned char *end,
- int *ver )
- {
- int ret;
- if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- {
- *ver = 0;
- return( 0 );
- }
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
- }
- return( 0 );
- }
- /*
- * Parse a CSR in DER format
- */
- int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
- const unsigned char *buf, size_t buflen )
- {
- int ret;
- size_t len;
- unsigned char *p, *end;
- mbedtls_x509_buf sig_params;
- memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
- /*
- * Check for valid input
- */
- if( csr == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- mbedtls_x509_csr_init( csr );
- /*
- * first copy the raw DER data
- */
- p = mbedtls_calloc( 1, len = buflen );
- if( p == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- memcpy( p, buf, buflen );
- csr->raw.p = p;
- csr->raw.len = len;
- end = p + len;
- /*
- * CertificationRequest ::= SEQUENCE {
- * certificationRequestInfo CertificationRequestInfo,
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING
- * }
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT );
- }
- if( len != (size_t) ( end - p ) )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- /*
- * CertificationRequestInfo ::= SEQUENCE {
- */
- csr->cri.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- end = p + len;
- csr->cri.len = end - csr->cri.p;
- /*
- * Version ::= INTEGER { v1(0) }
- */
- if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( ret );
- }
- csr->version++;
- if( csr->version != 1 )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
- }
- /*
- * subject Name
- */
- csr->subject_raw.p = p;
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( ret );
- }
- csr->subject_raw.len = p - csr->subject_raw.p;
- /*
- * subjectPKInfo SubjectPublicKeyInfo
- */
- if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( ret );
- }
- /*
- * attributes [0] Attributes
- */
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
- }
- // TODO Parse Attributes / extension requests
- p += len;
- end = csr->raw.p + csr->raw.len;
- /*
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING
- */
- if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( ret );
- }
- if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
- &csr->sig_md, &csr->sig_pk,
- &csr->sig_opts ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
- }
- if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
- {
- mbedtls_x509_csr_free( csr );
- return( ret );
- }
- if( p != end )
- {
- mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- return( 0 );
- }
- /*
- * Parse a CSR, allowing for PEM or raw DER encoding
- */
- int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
- {
- int ret;
- #if defined(MBEDTLS_PEM_PARSE_C)
- size_t use_len;
- mbedtls_pem_context pem;
- #endif
- /*
- * Check for valid input
- */
- if( csr == NULL || buf == NULL )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- #if defined(MBEDTLS_PEM_PARSE_C)
- mbedtls_pem_init( &pem );
- /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
- if( buflen == 0 || buf[buflen - 1] != '\0' )
- ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
- else
- ret = mbedtls_pem_read_buffer( &pem,
- "-----BEGIN CERTIFICATE REQUEST-----",
- "-----END CERTIFICATE REQUEST-----",
- buf, NULL, 0, &use_len );
- if( ret == 0 )
- {
- /*
- * Was PEM encoded, parse the result
- */
- if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 )
- return( ret );
- mbedtls_pem_free( &pem );
- return( 0 );
- }
- else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- {
- mbedtls_pem_free( &pem );
- return( ret );
- }
- else
- #endif /* MBEDTLS_PEM_PARSE_C */
- return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
- }
- #if defined(MBEDTLS_FS_IO)
- /*
- * Load a CSR into the structure
- */
- int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
- {
- int ret;
- size_t n;
- unsigned char *buf;
- if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
- return( ret );
- ret = mbedtls_x509_csr_parse( csr, buf, n );
- x509_csr_zeroize( buf, n );
- mbedtls_free( buf );
- return( ret );
- }
- #endif /* MBEDTLS_FS_IO */
- #define BEFORE_COLON 14
- #define BC "14"
- /*
- * Return an informational string about the CSR.
- */
- int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
- const mbedtls_x509_csr *csr )
- {
- int ret;
- size_t n;
- char *p;
- char key_size_str[BEFORE_COLON];
- p = buf;
- n = size;
- ret = mbedtls_snprintf( p, n, "%sCSR version : %d",
- prefix, csr->version );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
- MBEDTLS_X509_SAFE_SNPRINTF;
- ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
- csr->sig_opts );
- MBEDTLS_X509_SAFE_SNPRINTF;
- if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
- mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
- {
- return( ret );
- }
- ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
- (int) mbedtls_pk_get_bitlen( &csr->pk ) );
- MBEDTLS_X509_SAFE_SNPRINTF;
- return( (int) ( size - n ) );
- }
- /*
- * Initialize a CSR
- */
- void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
- {
- memset( csr, 0, sizeof(mbedtls_x509_csr) );
- }
- /*
- * Unallocate all CSR data
- */
- void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
- {
- mbedtls_x509_name *name_cur;
- mbedtls_x509_name *name_prv;
- if( csr == NULL )
- return;
- mbedtls_pk_free( &csr->pk );
- #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
- mbedtls_free( csr->sig_opts );
- #endif
- name_cur = csr->subject.next;
- while( name_cur != NULL )
- {
- name_prv = name_cur;
- name_cur = name_cur->next;
- x509_csr_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
- mbedtls_free( name_prv );
- }
- if( csr->raw.p != NULL )
- {
- x509_csr_zeroize( csr->raw.p, csr->raw.len );
- mbedtls_free( csr->raw.p );
- }
- x509_csr_zeroize( csr, sizeof( mbedtls_x509_csr ) );
- }
- /* Amalgamated Release Mappings */
- #undef SAFE_SNPRINTF
- #undef BEFORE_COLON
- #undef BC
- #endif /* MBEDTLS_X509_CSR_PARSE_C */
- /********* Start of file library/x509write_crt.c ************/
- /*
- * X.509 certificate writing
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * References:
- * - certificates: RFC 5280, updated by RFC 6818
- * - CSRs: PKCS#10 v1.7 aka RFC 2986
- * - attributes: PKCS#9 v2.0 aka RFC 2985
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_CRT_WRITE_C)
- #include <string.h>
- #if defined(MBEDTLS_PEM_WRITE_C)
- #endif /* MBEDTLS_PEM_WRITE_C */
- /* Implementation that should never be optimized out by the compiler */
- static void x509_write_crt_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
- {
- memset( ctx, 0, sizeof(mbedtls_x509write_cert) );
- mbedtls_mpi_init( &ctx->serial );
- ctx->version = MBEDTLS_X509_CRT_VERSION_3;
- }
- void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx )
- {
- mbedtls_mpi_free( &ctx->serial );
- mbedtls_asn1_free_named_data_list( &ctx->subject );
- mbedtls_asn1_free_named_data_list( &ctx->issuer );
- mbedtls_asn1_free_named_data_list( &ctx->extensions );
- x509_write_crt_zeroize( ctx, sizeof(mbedtls_x509write_cert) );
- }
- void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version )
- {
- ctx->version = version;
- }
- void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg )
- {
- ctx->md_alg = md_alg;
- }
- void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
- {
- ctx->subject_key = key;
- }
- void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
- {
- ctx->issuer_key = key;
- }
- int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
- const char *subject_name )
- {
- return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
- }
- int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
- const char *issuer_name )
- {
- return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name );
- }
- int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial )
- {
- int ret;
- if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 )
- return( ret );
- return( 0 );
- }
- int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before,
- const char *not_after )
- {
- if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ||
- strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 )
- {
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- }
- strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
- strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
- ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
- ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
- return( 0 );
- }
- int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
- const char *oid, size_t oid_len,
- int critical,
- const unsigned char *val, size_t val_len )
- {
- return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
- critical, val, val_len );
- }
- int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
- int is_ca, int max_pathlen )
- {
- int ret;
- unsigned char buf[9];
- unsigned char *c = buf + sizeof(buf);
- size_t len = 0;
- memset( buf, 0, sizeof(buf) );
- if( is_ca && max_pathlen > 127 )
- return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- if( is_ca )
- {
- if( max_pathlen >= 0 )
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) );
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
- 0, buf + sizeof(buf) - len, len );
- }
- #if defined(MBEDTLS_SHA1_C)
- int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx )
- {
- int ret;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
- unsigned char *c = buf + sizeof(buf);
- size_t len = 0;
- memset( buf, 0, sizeof(buf) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
- mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
- c = buf + sizeof(buf) - 20;
- len = 20;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) );
- return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ),
- 0, buf + sizeof(buf) - len, len );
- }
- int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
- {
- int ret;
- unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
- unsigned char *c = buf + sizeof(buf);
- size_t len = 0;
- memset( buf, 0, sizeof(buf) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
- mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
- c = buf + sizeof(buf) - 20;
- len = 20;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
- 0, buf + sizeof(buf) - len, len );
- }
- #endif /* MBEDTLS_SHA1_C */
- int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
- unsigned int key_usage )
- {
- unsigned char buf[4], ku;
- unsigned char *c;
- int ret;
- /* We currently only support 7 bits, from 0x80 to 0x02 */
- if( ( key_usage & ~0xfe ) != 0 )
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
- c = buf + 4;
- ku = (unsigned char) key_usage;
- if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 7 ) ) != 4 )
- return( ret );
- ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
- 1, buf, 4 );
- if( ret != 0 )
- return( ret );
- return( 0 );
- }
- int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
- unsigned char ns_cert_type )
- {
- unsigned char buf[4];
- unsigned char *c;
- int ret;
- c = buf + 4;
- if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
- return( ret );
- ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
- 0, buf, 4 );
- if( ret != 0 )
- return( ret );
- return( 0 );
- }
- static int x509_write_time( unsigned char **p, unsigned char *start,
- const char *time, size_t size )
- {
- int ret;
- size_t len = 0;
- /*
- * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
- */
- if( time[0] == '2' && time[1] == '0' && time [2] < '5' )
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
- (const unsigned char *) time + 2,
- size - 2 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) );
- }
- else
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
- (const unsigned char *) time,
- size ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) );
- }
- return( (int) len );
- }
- int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- const char *sig_oid;
- size_t sig_oid_len = 0;
- unsigned char *c, *c2;
- unsigned char hash[64];
- unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
- unsigned char tmp_buf[2048];
- size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
- size_t len = 0;
- mbedtls_pk_type_t pk_alg;
- /*
- * Prepare data to be signed in tmp_buf
- */
- c = tmp_buf + sizeof( tmp_buf );
- /* Signature algorithm needed in TBS, and later for actual signature */
- pk_alg = mbedtls_pk_get_type( ctx->issuer_key );
- if( pk_alg == MBEDTLS_PK_ECKEY )
- pk_alg = MBEDTLS_PK_ECDSA;
- if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
- &sig_oid, &sig_oid_len ) ) != 0 )
- {
- return( ret );
- }
- /*
- * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
- /*
- * SubjectPublicKeyInfo
- */
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key,
- tmp_buf, c - tmp_buf ) );
- c -= pub_len;
- len += pub_len;
- /*
- * Subject ::= Name
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
- /*
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- */
- sub_len = 0;
- MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
- MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
- MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
- MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
- len += sub_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- /*
- * Issuer ::= Name
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) );
- /*
- * Signature ::= AlgorithmIdentifier
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf,
- sig_oid, strlen( sig_oid ), 0 ) );
- /*
- * Serial ::= INTEGER
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
- /*
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- */
- sub_len = 0;
- MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) );
- len += sub_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- /*
- * Make signature
- */
- mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
- if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
- f_rng, p_rng ) ) != 0 )
- {
- return( ret );
- }
- /*
- * Write data to output buffer
- */
- c2 = buf + size;
- MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
- sig_oid, sig_oid_len, sig, sig_len ) );
- c2 -= len;
- memcpy( c2, c, len );
- len += sig_and_oid_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
- #define PEM_END_CRT "-----END CERTIFICATE-----\n"
- #if defined(MBEDTLS_PEM_WRITE_C)
- int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- unsigned char output_buf[4096];
- size_t olen = 0;
- if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf),
- f_rng, p_rng ) ) < 0 )
- {
- return( ret );
- }
- if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
- output_buf + sizeof(output_buf) - ret,
- ret, buf, size, &olen ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_PEM_WRITE_C */
- #endif /* MBEDTLS_X509_CRT_WRITE_C */
- /********* Start of file library/x509write_csr.c ************/
- /*
- * X.509 Certificate Signing Request writing
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- /*
- * References:
- * - CSRs: PKCS#10 v1.7 aka RFC 2986
- * - attributes: PKCS#9 v2.0 aka RFC 2985
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_X509_CSR_WRITE_C)
- #include <string.h>
- #include <stdlib.h>
- #if defined(MBEDTLS_PEM_WRITE_C)
- #endif
- /* Implementation that should never be optimized out by the compiler */
- static void x509_write_csr_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
- {
- memset( ctx, 0, sizeof(mbedtls_x509write_csr) );
- }
- void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
- {
- mbedtls_asn1_free_named_data_list( &ctx->subject );
- mbedtls_asn1_free_named_data_list( &ctx->extensions );
- x509_write_csr_zeroize( ctx, sizeof(mbedtls_x509write_csr) );
- }
- void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
- {
- ctx->md_alg = md_alg;
- }
- void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
- {
- ctx->key = key;
- }
- int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
- const char *subject_name )
- {
- return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
- }
- int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
- const char *oid, size_t oid_len,
- const unsigned char *val, size_t val_len )
- {
- return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
- 0, val, val_len );
- }
- int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
- {
- unsigned char buf[4];
- unsigned char *c;
- int ret;
- c = buf + 4;
- if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
- return( ret );
- ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
- buf, 4 );
- if( ret != 0 )
- return( ret );
- return( 0 );
- }
- int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
- unsigned char ns_cert_type )
- {
- unsigned char buf[4];
- unsigned char *c;
- int ret;
- c = buf + 4;
- if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
- return( ret );
- ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
- buf, 4 );
- if( ret != 0 )
- return( ret );
- return( 0 );
- }
- int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- const char *sig_oid;
- size_t sig_oid_len = 0;
- unsigned char *c, *c2;
- unsigned char hash[64];
- unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
- unsigned char tmp_buf[2048];
- size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
- size_t len = 0;
- mbedtls_pk_type_t pk_alg;
- /*
- * Prepare data to be signed in tmp_buf
- */
- c = tmp_buf + sizeof( tmp_buf );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
- if( len )
- {
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SET ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- }
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
- tmp_buf, c - tmp_buf ) );
- c -= pub_len;
- len += pub_len;
- /*
- * Subject ::= Name
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
- /*
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- /*
- * Prepare signature
- */
- mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
- pk_alg = mbedtls_pk_get_type( ctx->key );
- if( pk_alg == MBEDTLS_PK_ECKEY )
- pk_alg = MBEDTLS_PK_ECDSA;
- if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
- f_rng, p_rng ) ) != 0 ||
- ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
- &sig_oid, &sig_oid_len ) ) != 0 )
- {
- return( ret );
- }
- /*
- * Write data to output buffer
- */
- c2 = buf + size;
- MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
- sig_oid, sig_oid_len, sig, sig_len ) );
- c2 -= len;
- memcpy( c2, c, len );
- len += sig_and_oid_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- return( (int) len );
- }
- #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
- #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
- #if defined(MBEDTLS_PEM_WRITE_C)
- int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
- {
- int ret;
- unsigned char output_buf[4096];
- size_t olen = 0;
- if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
- f_rng, p_rng ) ) < 0 )
- {
- return( ret );
- }
- if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
- output_buf + sizeof(output_buf) - ret,
- ret, buf, size, &olen ) ) != 0 )
- {
- return( ret );
- }
- return( 0 );
- }
- #endif /* MBEDTLS_PEM_WRITE_C */
- #endif /* MBEDTLS_X509_CSR_WRITE_C */
- /********* Start of file library/xtea.c ************/
- /*
- * An 32-bit implementation of the XTEA algorithm
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
- #if !defined(MBEDTLS_CONFIG_FILE)
- #else
- #endif
- #if defined(MBEDTLS_XTEA_C)
- #include <string.h>
- #if defined(MBEDTLS_SELF_TEST)
- #if defined(MBEDTLS_PLATFORM_C)
- #else
- #include <stdio.h>
- #define mbedtls_printf printf
- #endif /* MBEDTLS_PLATFORM_C */
- #endif /* MBEDTLS_SELF_TEST */
- #if !defined(MBEDTLS_XTEA_ALT)
- /* Implementation that should never be optimized out by the compiler */
- static void xtea_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
- }
- /*
- * 32-bit integer manipulation macros (big endian)
- */
- #ifndef GET_UINT32_BE
- #define GET_UINT32_BE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
- }
- #endif
- #ifndef PUT_UINT32_BE
- #define PUT_UINT32_BE(n,b,i) \
- { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
- }
- #endif
- void mbedtls_xtea_init( mbedtls_xtea_context *ctx )
- {
- memset( ctx, 0, sizeof( mbedtls_xtea_context ) );
- }
- void mbedtls_xtea_free( mbedtls_xtea_context *ctx )
- {
- if( ctx == NULL )
- return;
- xtea_zeroize( ctx, sizeof( mbedtls_xtea_context ) );
- }
- /*
- * XTEA key schedule
- */
- void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] )
- {
- int i;
- memset( ctx, 0, sizeof(mbedtls_xtea_context) );
- for( i = 0; i < 4; i++ )
- {
- GET_UINT32_BE( ctx->k[i], key, i << 2 );
- }
- }
- /*
- * XTEA encrypt function
- */
- int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
- const unsigned char input[8], unsigned char output[8])
- {
- uint32_t *k, v0, v1, i;
- k = ctx->k;
- GET_UINT32_BE( v0, input, 0 );
- GET_UINT32_BE( v1, input, 4 );
- if( mode == MBEDTLS_XTEA_ENCRYPT )
- {
- uint32_t sum = 0, delta = 0x9E3779B9;
- for( i = 0; i < 32; i++ )
- {
- v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
- sum += delta;
- v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
- }
- }
- else /* MBEDTLS_XTEA_DECRYPT */
- {
- uint32_t delta = 0x9E3779B9, sum = delta * 32;
- for( i = 0; i < 32; i++ )
- {
- v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
- sum -= delta;
- v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
- }
- }
- PUT_UINT32_BE( v0, output, 0 );
- PUT_UINT32_BE( v1, output, 4 );
- return( 0 );
- }
- #if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * XTEA-CBC buffer encryption/decryption
- */
- int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length,
- unsigned char iv[8], const unsigned char *input,
- unsigned char *output)
- {
- int i;
- unsigned char temp[8];
- if( length % 8 )
- return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH );
- if( mode == MBEDTLS_XTEA_DECRYPT )
- {
- while( length > 0 )
- {
- memcpy( temp, input, 8 );
- mbedtls_xtea_crypt_ecb( ctx, mode, input, output );
- for( i = 0; i < 8; i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
- memcpy( iv, temp, 8 );
- input += 8;
- output += 8;
- length -= 8;
- }
- }
- else
- {
- while( length > 0 )
- {
- for( i = 0; i < 8; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
- mbedtls_xtea_crypt_ecb( ctx, mode, output, output );
- memcpy( iv, output, 8 );
- input += 8;
- output += 8;
- length -= 8;
- }
- }
- return( 0 );
- }
- #endif /* MBEDTLS_CIPHER_MODE_CBC */
- #endif /* !MBEDTLS_XTEA_ALT */
- #if defined(MBEDTLS_SELF_TEST)
- /*
- * XTEA tests vectors (non-official)
- */
- static const unsigned char xtea_test_key[6][16] =
- {
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x0e, 0x0f },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x0e, 0x0f },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x0e, 0x0f },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 }
- };
- static const unsigned char xtea_test_pt[6][8] =
- {
- { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
- { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
- { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
- { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
- { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
- { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
- };
- static const unsigned char xtea_test_ct[6][8] =
- {
- { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
- { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
- { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
- { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
- { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
- { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
- };
- /*
- * Checkup routine
- */
- int mbedtls_xtea_self_test( int verbose )
- {
- int i, ret = 0;
- unsigned char buf[8];
- mbedtls_xtea_context ctx;
- mbedtls_xtea_init( &ctx );
- for( i = 0; i < 6; i++ )
- {
- if( verbose != 0 )
- mbedtls_printf( " XTEA test #%d: ", i + 1 );
- memcpy( buf, xtea_test_pt[i], 8 );
- mbedtls_xtea_setup( &ctx, xtea_test_key[i] );
- mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf );
- if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- ret = 1;
- goto exit;
- }
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- if( verbose != 0 )
- mbedtls_printf( "\n" );
- exit:
- mbedtls_xtea_free( &ctx );
- return( ret );
- }
- #endif /* MBEDTLS_SELF_TEST */
- #endif /* MBEDTLS_XTEA_C */
- #endif /* ME_COM_MBEDTLS */
|