23 Star 19 Fork 75

src-openEuler / openjdk-1.8.0

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
kae-phase2.patch 307.98 KB
一键复制 编辑 原始数据 按行查看 历史
Autistic_boyya 提交于 2024-04-19 11:49 . I9I0M2:update to 8u412
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992
commit 0944cd842edf5706035155405514ee4d06a6d71c
Author: Noah <hedongbo@huawei.com>
Date: Mon May 17 19:28:24 2021 +0800
I27MB8: add kae phase2
diff --git a/jdk/make/mapfiles/libj2kae/mapfile-vers b/jdk/make/mapfiles/libj2kae/mapfile-vers
index 6ed331b2..128d1e32 100644
--- a/jdk/make/mapfiles/libj2kae/mapfile-vers
+++ b/jdk/make/mapfiles/libj2kae/mapfile-vers
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, Huawei Technologies Co., Ltd. All rights reserved.
+# Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -32,14 +32,18 @@ SUNWprivate_1.1 {
Java_org_openeuler_security_openssl_KAEDigest_nativeDigest;
Java_org_openeuler_security_openssl_KAEDigest_nativeClone;
Java_org_openeuler_security_openssl_KAEDigest_nativeFree;
- Java_org_openeuler_security_openssl_KAEAESCipher_nativeInit;
- Java_org_openeuler_security_openssl_KAEAESCipher_nativeUpdate;
- Java_org_openeuler_security_openssl_KAEAESCipher_nativeFinal;
- Java_org_openeuler_security_openssl_KAEAESCipher_nativeFree;
- Java_org_openeuler_security_openssl_KAEMac_nativeInit;
- Java_org_openeuler_security_openssl_KAEMac_nativeUpdate;
- Java_org_openeuler_security_openssl_KAEMac_nativeFinal;
- Java_org_openeuler_security_openssl_KAEMac_nativeFree;
+ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit;
+ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeUpdate;
+ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFinal;
+ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFinalGcm;
+ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFree;
+ Java_org_openeuler_security_openssl_KAEECKeyPairGenerator_nativeGenerateParam;
+ Java_org_openeuler_security_openssl_KAEECKeyPairGenerator_nativeGenerateKeyPair;
+ Java_org_openeuler_security_openssl_KAEECDHKeyAgreement_nativeGenerateSecret;
+ Java_org_openeuler_security_openssl_KAEHMac_nativeInit;
+ Java_org_openeuler_security_openssl_KAEHMac_nativeUpdate;
+ Java_org_openeuler_security_openssl_KAEHMac_nativeFinal;
+ Java_org_openeuler_security_openssl_KAEHMac_nativeFree;
Java_org_openeuler_security_openssl_KAERSAKeyPairGenerator_nativeGenerateKeyPair;
Java_org_openeuler_security_openssl_KAERSACipher_nativeCreateRSAPrivateCrtKey;
Java_org_openeuler_security_openssl_KAERSACipher_nativeCreateRSAPrivateKey;
@@ -51,6 +55,12 @@ SUNWprivate_1.1 {
Java_org_openeuler_security_openssl_KAERSACipher_nativeRSAEncryptOAEPPadding;
Java_org_openeuler_security_openssl_KAERSACipher_nativeRSADecryptOAEPPadding;
Java_org_openeuler_security_openssl_KAERSACipher_nativeFreeKey;
+ Java_org_openeuler_security_openssl_KAEDHKeyPairGenerator_nativeGenerateKeyPair;
+ Java_org_openeuler_security_openssl_KAEDHKeyAgreement_nativeComputeKey;
+ Java_org_openeuler_security_openssl_KAERSASignatureNative_rsaSign;
+ Java_org_openeuler_security_openssl_KAERSASignatureNative_rsaVerify;
+ Java_org_openeuler_security_openssl_KAERSASignatureNative_pssSign;
+ Java_org_openeuler_security_openssl_KAERSASignatureNative_pssVerify;
local:
*;
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEAESCipher.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEAESCipher.java
index 2dd5bf4a..6ef3620b 100644
--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEAESCipher.java
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEAESCipher.java
@@ -26,30 +26,24 @@
package org.openeuler.security.openssl;
-import sun.security.jca.JCAUtil;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.ReferenceQueue;
-import java.security.*;
-import java.security.spec.*;
-import java.util.Arrays;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Key;
import java.util.Locale;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-import javax.crypto.*;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
+import javax.crypto.NoSuchPaddingException;
/*
- * Cipher wrapper class utilizing openssl APIs. This class currently supports
+ * This class currently supports:
* - AES/ECB/NOPADDING
* - AES/ECB/PKCS5PADDING
* - AES/CBC/NOPADDING
* - AES/CBC/PKCS5PADDING
* - AES/CTR/NOPADDING
+ * - AES/GCM/NOPADDING
*/
-abstract class KAEAESCipher extends CipherSpi {
+abstract class KAEAESCipher extends KAESymmetricCipherBase {
public static class Aes extends KAEAESCipher {
public Aes(Mode mode, Padding padding) {
@@ -71,6 +65,7 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
public static class Ecb extends Aes {
public Ecb(Padding padding) {
super(Mode.ECB, padding);
@@ -97,12 +92,24 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
+ public static class Gcm extends Aes {
+ public Gcm(Padding padding) {
+ super(Mode.GCM, padding);
+ }
+ public static class NoPadding extends Gcm {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ }
}
public static class Aes_128 extends KAEAESCipher {
public Aes_128(Mode mode, Padding padding) {
super(mode, padding, 16);
}
+
public static class Cbc extends Aes_128 {
public Cbc(Padding padding) {
super(Mode.CBC, padding);
@@ -118,6 +125,7 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
public static class Ecb extends Aes_128 {
public Ecb(Padding padding) {
super(Mode.ECB, padding);
@@ -144,12 +152,24 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
+ public static class Gcm extends Aes_128 {
+ public Gcm(Padding padding) {
+ super(Mode.GCM, padding);
+ }
+ public static class NoPadding extends Gcm {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ }
}
public static class Aes_192 extends KAEAESCipher {
public Aes_192(Mode mode, Padding padding) {
super(mode, padding, 24);
}
+
public static class Cbc extends Aes_192 {
public Cbc(Padding padding) {
super(Mode.CBC, padding);
@@ -165,6 +185,7 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
public static class Ecb extends Aes_192 {
public Ecb(Padding padding) {
super(Mode.ECB, padding);
@@ -191,12 +212,24 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
+ public static class Gcm extends Aes_192 {
+ public Gcm(Padding padding) {
+ super(Mode.GCM, padding);
+ }
+ public static class NoPadding extends Gcm {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ }
}
public static class Aes_256 extends KAEAESCipher {
public Aes_256(Mode mode, Padding padding) {
super(mode, padding, 32);
}
+
public static class Cbc extends Aes_256 {
public Cbc(Padding padding) {
super(Mode.CBC, padding);
@@ -212,6 +245,7 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
+
public static class Ecb extends Aes_256 {
public Ecb(Padding padding) {
super(Mode.ECB, padding);
@@ -238,145 +272,46 @@ abstract class KAEAESCipher extends CipherSpi {
}
}
}
- }
-
- enum Padding {
- NOPADDING,
- PKCS5PADDING
- }
-
- enum Mode {
- ECB,
- CBC,
- CTR,
- }
-
- private final String keyAlgo = "AES";
- private final int blockSize = 16;
- private Mode mode;
- private Padding padding;
- private int fixedKeySize;
-
- private CipherContextRef pCtx = null;
- private byte[] keyValue;
- protected byte[] iv;
- private boolean initialized = false;
- private boolean encrypt = false;
- private int bytesBuffered = 0;
-
- private boolean calledUpdate;
- private String cipherName;
-
- private static final PublicKey constructPublicKey(byte[] encodedKey, String encodedKeyAlgorithm) throws NoSuchAlgorithmException, InvalidKeyException {
- PublicKey key;
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
- X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
- key = keyFactory.generatePublic(keySpec);
- } catch (NoSuchAlgorithmException e) {
- throw new NoSuchAlgorithmException("No provider found for " + encodedKeyAlgorithm + " KeyFactory");
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException("Cannot construct public key", e);
- }
- return key;
- }
-
- private static final PrivateKey constructPrivateKey(byte[] encodedKey,
- String encodedKeyAlgorithm) throws InvalidKeyException, NoSuchAlgorithmException {
- PrivateKey key = null;
- try {
- KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
- key = keyFactory.generatePrivate(keySpec);
- } catch (NoSuchAlgorithmException e) {
- throw new NoSuchAlgorithmException("No provider found for " + encodedKeyAlgorithm + " KeyFactory");
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException("Cannot construct private key", e);
- }
- return key;
- }
-
- private static final SecretKey constructSecretKey(byte[] encodedKey, String encodedKeyAlgorithm) {
- return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
- }
- static final Key constructKey(int keyType, byte[] encodedKey,
- String encodedKeyAlgorithm) throws NoSuchAlgorithmException, InvalidKeyException {
- Key res = null;
- switch (keyType) {
- case Cipher.SECRET_KEY:
- res = constructSecretKey(encodedKey, encodedKeyAlgorithm);
- break;
- case Cipher.PRIVATE_KEY:
- res = constructPrivateKey(encodedKey, encodedKeyAlgorithm);
- break;
- case Cipher.PUBLIC_KEY:
- res = constructPublicKey(encodedKey, encodedKeyAlgorithm);
- break;
- default:
- throw new InvalidKeyException("Unknown keytype " + keyType);
+ public static class Gcm extends Aes_256 {
+ public Gcm(Padding padding) {
+ super(Mode.GCM, padding);
+ }
+ public static class NoPadding extends Gcm {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
}
- return res;
}
KAEAESCipher(Mode mode, Padding padding, int fixedKeySize) {
- this.mode = mode;
- this.padding = padding;
- this.fixedKeySize = fixedKeySize;
+ super(mode, padding, fixedKeySize, "AES");
}
- private static class CipherContextRef extends PhantomReference<KAEAESCipher> implements Comparable<CipherContextRef> {
-
- private static ReferenceQueue<KAEAESCipher> refQueue = new ReferenceQueue<>();
- private static Set<CipherContextRef> refList = new ConcurrentSkipListSet<>();
- private static boolean disableKaeDispose = Boolean.getBoolean("kae.disableKaeDispose");
-
- final long ctxAddress;
-
- private static void drainRefQueueBounded() {
- while (true) {
- CipherContextRef next = (CipherContextRef) refQueue.poll();
- if (next == null) {
- break;
- }
- next.dispose(true);
- }
- }
-
- CipherContextRef(KAEAESCipher kaeCipher, long ctxAddress) {
- super(kaeCipher, refQueue);
- this.ctxAddress = ctxAddress;
- if (!disableKaeDispose) {
- refList.add(this);
- drainRefQueueBounded();
- }
- }
-
- @Override
- public int compareTo(CipherContextRef o) {
- if (this.ctxAddress == o.ctxAddress) {
- return 0;
- } else {
- return (this.ctxAddress < o.ctxAddress) ? -1 : 1;
+ protected void checkKey(Key key) throws InvalidKeyException {
+ if (key == null || key.getEncoded() == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ } else {
+ if (!keyAlgo.equalsIgnoreCase(key.getAlgorithm())) {
+ throw new InvalidKeyException("Key algorithm must be " + keyAlgo);
}
- }
-
- void dispose(boolean needFree) {
- if (!disableKaeDispose) {
- refList.remove(this);
- try {
- if (needFree) {
- nativeFree(ctxAddress);
- }
- } finally {
- this.clear();
+ int keyLen = key.getEncoded().length;
+ if (fixedKeySize == -1) {
+ if (keyLen != 16 && keyLen != 24 & keyLen != 32) {
+ throw new InvalidKeyException("Key size is not valid. Got key length of: " + keyLen);
}
} else {
- nativeFree(ctxAddress);
+ if (keyLen != fixedKeySize) {
+ throw new InvalidKeyException("Only " + fixedKeySize + "-byte keys are accepted. Got: " + keyLen);
+ }
}
}
}
+ protected String getCipherName(int keyLength, Mode mode) {
+ return "aes-" + keyLength + "-" + mode.toString().toLowerCase(Locale.US);
+ }
@Override
protected void engineSetMode(String modeStr) throws NoSuchAlgorithmException {
@@ -390,10 +325,11 @@ abstract class KAEAESCipher extends CipherSpi {
mode = Mode.CBC;
} else if (modeStr.equalsIgnoreCase("CTR")) {
mode = Mode.CTR;
+ } else if (modeStr.equalsIgnoreCase("GCM")) {
+ mode = Mode.GCM;
} else {
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
}
-
}
@Override
@@ -401,8 +337,14 @@ abstract class KAEAESCipher extends CipherSpi {
if (paddingStr == null) {
throw new NoSuchPaddingException("null padding");
}
+ if (paddingStr.equalsIgnoreCase("PKCS7PADDING")) {
+ paddingStr = "PKCS5Padding";
+ }
- if (paddingStr.equalsIgnoreCase("NOPADDING")) {
+ // GCM has no Padding, pkcs5-> nopadding in sunjce
+ if (mode == Mode.GCM) {
+ this.padding = Padding.NOPADDING;
+ } else if (paddingStr.equalsIgnoreCase("NOPADDING")) {
this.padding = Padding.NOPADDING;
} else if(paddingStr.equalsIgnoreCase("PKCS5PADDING")) {
if (mode == Mode.CTR) {
@@ -410,315 +352,13 @@ abstract class KAEAESCipher extends CipherSpi {
}
this.padding = Padding.PKCS5PADDING;
} else {
- throw new NoSuchPaddingException("Unsupported padding "+padding);
- }
- }
-
-
- @Override
- protected int engineGetBlockSize() {
- return blockSize;
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- return getOutputSizeByOperation(inputLen, true);
- }
-
- @Override
- protected byte[] engineGetIV() {
- return iv == null ? null : iv.clone();
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- if (iv == null) {
- return null;
- }
- IvParameterSpec ivSpec = new IvParameterSpec(iv.clone());
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance(keyAlgo);
- params.init(ivSpec);
- return params;
- } catch (GeneralSecurityException e) {
- throw new RuntimeException("Could not encode parameters", e);
- }
- }
-
- @Override
- protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- try {
- engineInit(opmode, key, (AlgorithmParameterSpec) null, random);
- } catch (InvalidAlgorithmParameterException e) {
- throw new InvalidKeyException("init() failed", e);
+ throw new NoSuchPaddingException("Unsupported padding " + paddingStr);
}
}
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- AlgorithmParameterSpec ivSpec = null;
- if (params != null) {
- try {
- ivSpec = params.getParameterSpec(IvParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- throw new InvalidAlgorithmParameterException("Could not decode IV", e);
- }
- }
- engineInit(opmode, key, ivSpec, random);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- checkKey(key);
- boolean doEncrypt = (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE);
-
- byte[] ivBytes = null;
-
- if (params != null) {
- if (!(params instanceof IvParameterSpec)) {
- throw new InvalidKeyException("IvParameterSpec required. Received: " + params.getClass().getName());
- } else {
- ivBytes = ((IvParameterSpec) params).getIV();
- if (ivBytes.length != blockSize) {
- throw new InvalidAlgorithmParameterException("Wrong IV length: must be " + blockSize +
- " bytes long. Received length:" + ivBytes.length);
- }
- }
- }
- if (mode == Mode.ECB) {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("No Parameters for ECB mode");
- }
- } else if (ivBytes == null) {
- if (doEncrypt) {
- ivBytes = new byte[blockSize];
- if (random == null) {
- random = JCAUtil.getSecureRandom();
- }
- random.nextBytes(ivBytes);
- } else {
- throw new InvalidAlgorithmParameterException("Parameters required for decryption");
- }
- }
- implInit(doEncrypt, key.getEncoded(), ivBytes);
- }
-
- private void implInit(boolean encrypt, byte[] keyVal, byte[] ivVal) {
-
- reset(true);
- this.encrypt = encrypt;
- this.keyValue = keyVal;
- this.iv = ivVal;
- this.cipherName = "aes-" + (keyVal.length * 8) + "-" + mode.toString().toLowerCase(Locale.US);
-
- // OpenSSL only supports PKCS5 Padding
- long pCtxVal;
- try {
- pCtxVal = nativeInit(cipherName, encrypt, keyValue, iv, padding == Padding.PKCS5PADDING);
- } catch (RuntimeException e) {
- throw new ProviderException("Invoke nativeInit failed for " + cipherName, e);
- }
-
- initialized = (pCtxVal != 0L);
- if (initialized) {
- pCtx = new CipherContextRef(this, pCtxVal);
- } else {
- throw new NullPointerException("pCtxVal == 0");
- }
- calledUpdate = false;
- }
-
- final int checkKey(Key key) throws InvalidKeyException {
- if (key == null || key.getEncoded() == null) {
- throw new InvalidKeyException("Key cannot be null");
- } else {
- if (!keyAlgo.equalsIgnoreCase(key.getAlgorithm())) {
- throw new InvalidKeyException("Key algorithm must be " + keyAlgo);
- }
- int keyLen = key.getEncoded().length;
- if (fixedKeySize == -1) {
- if (keyLen != 16 && keyLen != 24 & keyLen != 32) {
- throw new InvalidKeyException("Key size is not valid. Got key length of: " + keyLen);
- }
- } else {
- if (keyLen != fixedKeySize) {
- throw new InvalidKeyException("Only " + fixedKeySize + "-byte keys are accepted. Got: " + keyLen);
- }
- }
- return keyLen;
- }
- }
-
- @Override
- protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- byte[] out = new byte[getOutputSizeByOperation(inputLen, false)];
- int n = implUpdate(input, inputOffset, inputLen, out, 0);
- if (n == 0) {
- return new byte[0];
- } else if (out.length != n) {
- out = Arrays.copyOf(out, n);
- }
- return out;
- }
-
- @Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- int min = getOutputSizeByOperation(inputLen, false);
- if (output.length - outputOffset < min) {
- throw new ShortBufferException("min" + min + "-byte buffer needed");
- }
- return implUpdate(input, inputOffset, inputLen, output, outputOffset);
- }
-
- private int implUpdate(byte[] in, int inOfs, int inLen, byte[] output, int outOfs) {
- ensureInitialized();
- if (inLen <= 0) {
- return 0;
- }
- int k;
- try {
- k = nativeUpdate(pCtx.ctxAddress, in, inOfs, inLen, output, outOfs);
- } catch (ArrayIndexOutOfBoundsException e) {
- reset(true);
- throw new ProviderException("Invoke nativeUpdate failed for " + cipherName, e);
- }
- bytesBuffered += (inLen - k);
-
- calledUpdate = true;
- return k;
- }
-
- protected int getOutputSizeByOperation(int inLen, boolean isDoFinal) {
- if (inLen <= 0) {
- inLen = 0;
- }
- if (!isDoFinal && inLen == 0) {
- return 0;
- }
- if (padding == Padding.NOPADDING) {
- return inLen + bytesBuffered;
- } else {
- int len = inLen + bytesBuffered;
-
- /*
- * The amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1) for encrypt.
- * Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EVP_CipherUpdate.html} for details.
- */
- len += (len % blockSize != 0 || encrypt) ? blockSize : 0;
- return len - (len % blockSize);
- }
- }
-
- @Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset,
- int inputLen) throws IllegalBlockSizeException, BadPaddingException {
- byte[] out = new byte[getOutputSizeByOperation(inputLen, true)];
- try {
- int outLen = engineDoFinal(input, inputOffset, inputLen, out, 0);
- if (out.length != outLen) {
- out = Arrays.copyOf(out, outLen);
- }
- return out;
- } catch (ShortBufferException e) {
- throw new ProviderException(e);
- }
- }
-
- @Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
- int outLen = 0;
- int min = getOutputSizeByOperation(inputLen, true);
- if (output.length - outputOffset < min) {
- throw new ShortBufferException("min" + min + "-byte buffer needed");
- }
- if (inputLen > 0) {
- outLen = implUpdate(input, inputOffset, inputLen, output, outputOffset);
- outputOffset += outLen;
- }
- outLen += implDoFinal(output, outputOffset);
- return outLen;
- }
-
- @Override
- protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
- byte[] res = null;
- try {
- byte[] encodedKey = key.getEncoded();
- if (encodedKey == null || encodedKey.length == 0) {
- throw new InvalidKeyException("Cannot get an encoding of the key to be wrapped");
- }
- res = engineDoFinal(encodedKey, 0, encodedKey.length);
- } catch (BadPaddingException e) {
- // Should never happen
- }
- return res;
- }
-
- @Override
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
- int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
- byte[] encodedKey;
- try {
- encodedKey = engineDoFinal(wrappedKey, 0, wrappedKey.length);
- } catch (IllegalBlockSizeException | BadPaddingException e) {
- throw (InvalidKeyException) (new InvalidKeyException()).initCause(e);
- }
- return constructKey(wrappedKeyType, encodedKey, wrappedKeyAlgorithm);
- }
-
- private int implDoFinal(byte[] out, int outOfs) {
-
- if (!encrypt && !calledUpdate) {
- return 0;
- }
- ensureInitialized();
-
- int outLen;
- try {
- outLen = nativeFinal(pCtx.ctxAddress, out, outOfs);
- } catch (ArrayIndexOutOfBoundsException | BadPaddingException e) {
- throw new ProviderException("Invoke nativeFinal failed for " + cipherName, e);
- } finally {
- reset(true);
- }
-
- return outLen;
- }
-
- protected void reset(boolean doCancel) {
- initialized = false;
- bytesBuffered = 0;
- calledUpdate = false;
- if (pCtx != null) {
- pCtx.dispose(doCancel);
- pCtx = null;
- }
- }
-
- protected native static long nativeInit(String cipherType, boolean encrypt, byte[] key, byte[] iv, boolean padding) throws RuntimeException;
-
- protected native static int nativeUpdate(long pContext, byte[] in, int inOfs, int inLen, byte[] out,
- int outOfs) throws ArrayIndexOutOfBoundsException;
-
- protected native static int nativeFinal(long pContext, byte[] out,
- int outOfs) throws ArrayIndexOutOfBoundsException, BadPaddingException;
-
- protected native static void nativeFree(long pContext);
-
- protected void ensureInitialized() {
- if (!initialized) {
- reset(true);
- long pCtxVal = nativeInit(cipherName, encrypt, keyValue, iv, padding == Padding.PKCS5PADDING);
- initialized = (pCtxVal != 0L);
- if (initialized) {
- pCtx = new CipherContextRef(this, pCtxVal);
- } else {
- throw new RuntimeException("Cannot initialize Cipher");
- }
+ protected void checkIvBytes(byte[] ivBytes) throws InvalidAlgorithmParameterException {
+ if ((ivBytes == null) || (ivBytes.length != blockSize)) {
+ throw new InvalidAlgorithmParameterException("Wrong IV length: must be " + blockSize + " bytes long.");
}
}
}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEDHKeyAgreement.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEDHKeyAgreement.java
new file mode 100644
index 00000000..6986d254
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEDHKeyAgreement.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import sun.security.util.KeyUtil;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.InvalidKeyException;
+import java.security.SecureRandom;
+import java.security.Key;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.AlgorithmParameterGeneratorSpi;
+import java.security.AccessController;
+import java.security.ProviderException;
+import java.security.PrivilegedAction;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.DESKeySpec;
+
+public class KAEDHKeyAgreement extends KeyAgreementSpi {
+ private boolean generateSecret = false;
+ private BigInteger p;
+ private BigInteger g;
+ private BigInteger x;
+ private BigInteger y;
+ static final int[] AES_KEYSIZES = {16, 24, 32};
+ static final int BLOWFISH_MAX_KEYSIZE = 56;
+
+ private static class AllowKDF {
+ private static final boolean VALUE = getValue();
+
+ private static boolean getValue() {
+ return AccessController.doPrivileged(
+ (PrivilegedAction<Boolean>)
+ () -> Boolean.getBoolean("jdk.crypto.KeyAgreement.legacyKDF"));
+ }
+ }
+
+ public KAEDHKeyAgreement() {
+ }
+
+ @Override
+ protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+ try {
+ engineInit(key, null, random);
+ } catch (InvalidAlgorithmParameterException e) {
+ // never happens, because we did not pass any parameters
+ }
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params,
+ SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+
+ // ignore "random" parameter, because our implementation does not
+ // require any source of randomness
+ generateSecret = false;
+ p = null;
+ g = null;
+
+ if ((params != null) && !(params instanceof DHParameterSpec)) {
+ throw new InvalidAlgorithmParameterException("Diffie-Hellman parameters expected");
+ }
+
+ if (!(key instanceof DHPrivateKey)) {
+ throw new InvalidKeyException("Diffie-Hellman private key expected");
+ }
+
+ DHPrivateKey privateKey = (DHPrivateKey) key;
+
+ // check if private key parameters are compatible with
+ // initialized ones
+ if (params != null) {
+ p = ((DHParameterSpec) params).getP();
+ g = ((DHParameterSpec) params).getG();
+ }
+
+ BigInteger priv_p = privateKey.getParams().getP();
+ BigInteger priv_g = privateKey.getParams().getG();
+ if (p != null && priv_p != null && !(p.equals(priv_p))) {
+ throw new InvalidKeyException("Incompatible parameters");
+ }
+ if (g != null && priv_g != null && !(g.equals(priv_g))) {
+ throw new InvalidKeyException("Incompatible parameters");
+ }
+ if ((p == null && priv_p == null) ||
+ (g == null) && priv_g == null) {
+ throw new InvalidKeyException("Missing parameters");
+ }
+ p = priv_p;
+ g = priv_g;
+
+ // store the x value
+ x = privateKey.getX();
+ }
+
+ @Override
+ protected Key engineDoPhase(Key key, boolean lastPhase)
+ throws InvalidKeyException, IllegalStateException {
+ if (!(key instanceof DHPublicKey)) {
+ throw new InvalidKeyException("Diffie-Hellman public "
+ + "expected");
+ }
+ DHPublicKey publicKey = (DHPublicKey) key;
+ if (p == null || g == null) {
+ throw new IllegalStateException("Not initialized");
+ }
+ BigInteger pub_p = publicKey.getParams().getP();
+ BigInteger pub_g = publicKey.getParams().getG();
+ if (pub_p != null && !(p.equals(pub_p))) {
+ throw new InvalidKeyException("Incompatible parameters");
+ }
+ if (pub_g != null && !(g.equals(pub_g))) {
+ throw new InvalidKeyException("Incompatible parameters");
+ }
+ KeyUtil.validate(publicKey);
+ y = publicKey.getY();
+ generateSecret = true;
+ if (lastPhase == false) {
+ byte[] intermediate = engineGenerateSecret();
+ try {
+ KeyFactory fk = KeyFactory.getInstance("DH");
+ DHPublicKey newPublicKey = (DHPublicKey) fk.generatePublic(
+ new DHPublicKeySpec(new BigInteger(1, intermediate), p, g));
+ return newPublicKey;
+ } catch (NoSuchAlgorithmException noalg) {
+ throw new ProviderException(noalg);
+ } catch (InvalidKeySpecException ikse) {
+ throw new ProviderException(ikse);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ protected byte[] engineGenerateSecret()
+ throws IllegalStateException {
+ int expectedLen = (p.bitLength() + 7) >>> 3;
+ byte[] result = new byte[expectedLen];
+ try {
+ engineGenerateSecret(result, 0);
+ } catch (ShortBufferException shortBufferException) {
+ // should never happen since length are identical
+ }
+ return result;
+ }
+
+ @Override
+ protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException {
+ if (!generateSecret) {
+ throw new IllegalStateException("Key agreement has not bee complated yet");
+ }
+ if (sharedSecret == null) {
+ throw new ShortBufferException("No buffer provided for shared secret");
+ }
+ BigInteger modulus = p;
+ int expectedLen = (modulus.bitLength() + 7) >>> 3;
+ if ((sharedSecret.length - offset) < expectedLen) {
+ throw new ShortBufferException("Buffer too short for shared secret");
+ }
+ generateSecret = false;
+ byte[] secret = nativeComputeKey(y.toByteArray(), x.toByteArray(),
+ p.toByteArray(), g.toByteArray(), modulus.bitLength());
+
+ if (secret.length == expectedLen) {
+ System.arraycopy(secret, 0, sharedSecret, offset,
+ secret.length);
+ } else {
+ // Array too short, pad it w/ leading 0s
+ if (secret.length < expectedLen) {
+ System.arraycopy(secret, 0, sharedSecret,
+ offset + (expectedLen - secret.length),
+ secret.length);
+ } else {
+ // Array too long, check and trim off the excess
+ if ((secret.length == (expectedLen + 1)) && secret[0] == 0) {
+ // ignore the leading sign byte
+ System.arraycopy(secret, 1, sharedSecret, offset, expectedLen);
+ } else {
+ throw new ProviderException("Generated secret is out-of-range");
+ }
+ }
+ }
+
+ return expectedLen;
+ }
+
+ @Override
+ protected SecretKey engineGenerateSecret(String algorithm)
+ throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException {
+ if (algorithm == null) {
+ throw new NoSuchAlgorithmException("null algorithm");
+ }
+
+ if (!algorithm.equalsIgnoreCase("TlsPremasterSecret") &&
+ !AllowKDF.VALUE) {
+
+ throw new NoSuchAlgorithmException("Unsupported secret key "
+ + "algorithm: " + algorithm);
+ }
+
+ byte[] secret = engineGenerateSecret();
+ if (algorithm.equalsIgnoreCase("DES")) {
+ // DES
+ try {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
+ return factory.generateSecret(new DESKeySpec(secret));
+ } catch (InvalidKeySpecException e) {
+ throw new ProviderException("Generate DES Secret failed.", e);
+ }
+ } else if (algorithm.equalsIgnoreCase("DESede")
+ || algorithm.equalsIgnoreCase("TripleDES")) {
+ // Triple DES
+ try {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
+ return factory.generateSecret(new DESedeKeySpec(secret));
+ } catch (InvalidKeySpecException e) {
+ throw new ProviderException("Generate DESede Secret failed.", e);
+ }
+ } else if (algorithm.equalsIgnoreCase("Blowfish")) {
+ // Blowfish
+ int keysize = secret.length;
+ if (keysize >= BLOWFISH_MAX_KEYSIZE)
+ keysize = BLOWFISH_MAX_KEYSIZE;
+ return new SecretKeySpec(secret, 0, keysize, "Blowfish");
+ } else if (algorithm.equalsIgnoreCase("AES")) {
+ int idx = AES_KEYSIZES.length - 1;
+ int keysize = secret.length;
+ SecretKeySpec secretKey = null;
+ while (secretKey == null && idx >= 0) {
+ if (keysize >= AES_KEYSIZES[idx]) {
+ keysize = AES_KEYSIZES[idx];
+ secretKey = new SecretKeySpec(secret, 0, keysize, "AES");
+ }
+ idx--;
+ }
+ if (secretKey == null) {
+ throw new InvalidKeyException("Key material is too short");
+ }
+ return secretKey;
+ } else if (algorithm.equals("TlsPremasterSecret")) {
+ // remove leading zero bytes per RFC 5246 Section 8.1.2
+ return new SecretKeySpec(
+ KeyUtil.trimZeroes(secret), "TlsPremasterSecret");
+ } else {
+ throw new NoSuchAlgorithmException("Unsupported secret key "
+ + "algorithm: " + algorithm);
+ }
+ }
+ protected native byte[] nativeComputeKey(byte[] y, byte[] x, byte[] p, byte[] g, int pSize);
+}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEDHKeyPairGenerator.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEDHKeyPairGenerator.java
new file mode 100644
index 00000000..429c65fc
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEDHKeyPairGenerator.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import java.math.BigInteger;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.KeyPairGeneratorSpi;
+import java.security.SecureRandom;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidParameterException;
+import java.security.GeneralSecurityException;
+import java.security.ProviderException;
+import java.security.KeyFactory;
+import java.security.spec.InvalidKeySpecException;
+import sun.security.jca.JCAUtil;
+import sun.security.provider.ParameterCache;
+import javax.crypto.spec.DHPublicKeySpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.interfaces.DHPrivateKey;
+
+import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
+
+public class KAEDHKeyPairGenerator
+ extends KeyPairGeneratorSpi {
+ private DHParameterSpec parameterSpec;
+ // The size in bits of the random exponent (private value)
+ private int pSize;
+ // The size in bits of the random exponent (private value)
+ private int lSize;
+ private SecureRandom random;
+
+ public KAEDHKeyPairGenerator() {
+ super();
+ initialize(DEF_DH_KEY_SIZE, null);
+ }
+
+ private static void checkKeySize(int keySize) {
+ if ((keySize < 512) || (keySize > 8192) || ((keySize & 0x3F) != 0)) {
+ throw new InvalidParameterException(
+ "DH key size must be multiple of 64, and can only range " +
+ "from 512 to 8192(inclusize). " +
+ "The specific key size " + keySize + " is not supported");
+ }
+ }
+ @Override
+ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+
+ if (!(params instanceof DHParameterSpec)){
+ throw new InvalidAlgorithmParameterException
+ ("Inappropriate parameter type");
+ }
+
+ parameterSpec = (DHParameterSpec) params;
+ pSize = parameterSpec.getP().bitLength();
+
+ try {
+ checkKeySize(pSize);
+ } catch (InvalidParameterException e) {
+ throw new InvalidAlgorithmParameterException(e.getMessage());
+ }
+
+ // exponent size is optional, could be 0
+ lSize = parameterSpec.getL();
+
+ // Require exponentSize < primeSize
+ if ((lSize != 0) && (lSize > pSize)) {
+ throw new InvalidAlgorithmParameterException
+ ("Exponent size must not be larger than modulus size");
+ }
+
+ this.random = random;
+ }
+
+ @Override
+ public void initialize(int keysize, SecureRandom random) {
+ checkKeySize(keysize);
+ this.parameterSpec = ParameterCache.getCachedDHParameterSpec(keysize);
+ if ((this.parameterSpec == null) && (keysize > 1024)) {
+ throw new InvalidParameterException("Unsupported " + keysize + "-bit DH parameter generation.");
+ }
+ this.pSize = keysize;
+ this.lSize = 0;
+ this.random = random;
+ }
+
+ @Override
+ public KeyPair generateKeyPair() {
+
+ if (random == null) {
+ random = JCAUtil.getSecureRandom();
+ }
+
+ if (parameterSpec == null) {
+ try {
+ parameterSpec = ParameterCache.getDHParameterSpec(pSize, random);
+ } catch (GeneralSecurityException e) {
+ // should never happen
+ throw new ProviderException(e);
+ }
+ }
+
+ BigInteger p = parameterSpec.getP();
+ BigInteger g = parameterSpec.getG();
+
+ if (lSize <= 0) {
+ lSize = pSize >> 1;
+ // use an exponent size of (pSize / 2) but at least 384 bits
+ if (lSize < 384) {
+ lSize = 384;
+ }
+ }
+ byte[][] keys;
+ try {
+ keys = nativeGenerateKeyPair(p.toByteArray(), g.toByteArray(), lSize);
+ } catch (Exception e){
+ throw new ProviderException("Invoke nativeGenerateKeyPair failed.", e);
+ }
+
+ BigInteger pubKey = new BigInteger(keys[0]);
+ BigInteger priKey = new BigInteger(keys[1]);
+
+ try{
+ KeyFactory fk = KeyFactory.getInstance("DH");
+ DHPublicKey publicKey = (DHPublicKey)fk.generatePublic(new DHPublicKeySpec(pubKey, p , g));
+ DHPrivateKey privateKey = (DHPrivateKey)fk.generatePrivate(new DHPrivateKeySpec(priKey, p, g));
+ return new KeyPair(publicKey, privateKey);
+ } catch (NoSuchAlgorithmException noalg) {
+ throw new ProviderException(noalg);
+ } catch (InvalidKeySpecException ikse) {
+ throw new ProviderException(ikse);
+ }
+ }
+ protected native static byte[][] nativeGenerateKeyPair(byte[] p, byte[] g, int lSize);
+}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java
new file mode 100644
index 00000000..ac05e6d5
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import sun.security.ec.ECKeyFactory;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.SecretKeySpec;
+
+public class KAEECDHKeyAgreement extends KeyAgreementSpi {
+ private ECPrivateKey privateKey;
+ private ECPublicKey publicKey;
+
+ // Length of the secret to be derived.
+ private int expectedSecretLen;
+ private String curveName;
+
+ @Override
+ protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+ if (!(key instanceof PrivateKey)) {
+ throw new InvalidKeyException("Key must be instance of PrivateKey");
+ }
+ privateKey = (ECPrivateKey) ECKeyFactory.toECKey(key);
+ publicKey = null;
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("Parameters not supported");
+ }
+ engineInit(key, random);
+ }
+
+ @Override
+ protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException {
+ if (privateKey == null) {
+ throw new IllegalStateException("Not initialized");
+ }
+ if (publicKey != null) {
+ throw new IllegalStateException("Phase already executed");
+ }
+ if (!lastPhase) {
+ throw new IllegalStateException
+ ("Only two party agreement supported, lastPhase must be true");
+ }
+ if (!(key instanceof ECPublicKey)) {
+ throw new InvalidKeyException
+ ("Key must be a PublicKey with algorithm EC");
+ }
+
+ publicKey = (ECPublicKey) key;
+ ECParameterSpec params = publicKey.getParams();
+ int keyLenBits = params.getCurve().getField().getFieldSize();
+ // Bits to bytes.
+ expectedSecretLen = (keyLenBits + 7) >> 3;
+
+ curveName = KAEUtils.getCurveBySize(keyLenBits);
+ if (curveName == null) {
+ throw new InvalidParameterException("unknown keyLenBits" + keyLenBits);
+ }
+ if (KAEUtils.getCurveByAlias(curveName) != null) {
+ curveName = KAEUtils.getCurveByAlias(curveName);
+ }
+ return null;
+ }
+
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ if ((privateKey == null) || (publicKey == null)) {
+ throw new IllegalStateException("Not initialized correctly");
+ }
+ ECPoint w = publicKey.getW();
+ BigInteger wX = w.getAffineX();
+ BigInteger wY = w.getAffineY();
+
+ BigInteger s = privateKey.getS();
+ byte[] secret = nativeGenerateSecret(curveName, wX.toByteArray(), wY.toByteArray(), s.toByteArray());
+ if (secret == null || secret.length != expectedSecretLen) {
+ throw new RuntimeException("nativeGenerateSecret error. Expected: " + expectedSecretLen + ", actual: " + (secret == null ? "null" : secret.length));
+ }
+ return secret;
+ }
+
+ @Override
+ protected int engineGenerateSecret(byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException {
+ if (offset + expectedSecretLen > sharedSecret.length) {
+ throw new ShortBufferException("Need " + expectedSecretLen +
+ " bytes, only " + (sharedSecret.length - offset) + "available");
+ }
+ byte[] secret = engineGenerateSecret();
+ System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
+ return secret.length;
+ }
+
+ @Override
+ protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ if (algorithm == null) {
+ throw new NoSuchAlgorithmException("Algorithm must not be null");
+ }
+ return new SecretKeySpec(engineGenerateSecret(), algorithm);
+ }
+
+ protected static native byte[] nativeGenerateSecret(String curveName, byte[] wX, byte[] wY, byte[] s);
+}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java
new file mode 100644
index 00000000..5f0c4db0
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import sun.security.ec.ECPrivateKeyImpl;
+import sun.security.ec.ECPublicKeyImpl;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGeneratorSpi;
+import java.security.ProviderException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECField;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+import java.util.HashMap;
+import java.util.Map;
+
+public class KAEECKeyPairGenerator extends KeyPairGeneratorSpi {
+ private ECParameterSpec param = null;
+ private final int defaultKeySize = 256;
+
+ @Override
+ public void initialize(int keysize, SecureRandom random) {
+ String curveName = KAEUtils.getCurveBySize(keysize);
+ if (curveName == null) {
+ throw new InvalidParameterException("unknown key size " + keysize);
+ }
+ if (KAEUtils.getCurveByAlias(curveName) != null) {
+ curveName = KAEUtils.getCurveByAlias(curveName);
+ }
+ this.param = getParamsByCurve(curveName);
+ }
+
+ private ECParameterSpec getParamsByCurve(String curveName) {
+ byte[][] params = nativeGenerateParam(curveName);
+ if (params == null) {
+ throw new InvalidParameterException("unknown curve " + curveName);
+ }
+ BigInteger p = new BigInteger(params[0]);
+ BigInteger a = new BigInteger(params[1]);
+ BigInteger b = new BigInteger(params[2]);
+ BigInteger x = new BigInteger(params[3]);
+ BigInteger y = new BigInteger(params[4]);
+ BigInteger order = new BigInteger(params[5]);
+ BigInteger cofactor = new BigInteger(params[6]);
+ ECField field = new ECFieldFp(p);
+ EllipticCurve curve = new EllipticCurve(field, a, b);
+ ECPoint g = new ECPoint(x, y);
+ ECParameterSpec spec = new ECParameterSpec(curve, g, order, cofactor.intValue());
+ return spec;
+ }
+
+ @Override
+ public void initialize(AlgorithmParameterSpec param, SecureRandom random) throws InvalidAlgorithmParameterException {
+ if (param instanceof ECParameterSpec) {
+ this.param = (ECParameterSpec) param;
+ } else if (param instanceof ECGenParameterSpec) {
+ ECGenParameterSpec ecParam = (ECGenParameterSpec)param;
+ String curveName = ecParam.getName();
+ if (KAEUtils.getCurveByAlias(curveName) != null) {
+ curveName = KAEUtils.getCurveByAlias(curveName);
+ }
+ this.param = getParamsByCurve(curveName);
+ } else {
+ throw new InvalidAlgorithmParameterException("ECParameterSpec or ECGenParameterSpec for EC");
+ }
+ }
+
+ @Override
+ public KeyPair generateKeyPair() {
+ if (param == null) {
+ String curveName = KAEUtils.getCurveBySize(defaultKeySize);
+ param = getParamsByCurve(curveName);
+ }
+ EllipticCurve curve = param.getCurve();
+ ECFieldFp field = (ECFieldFp) curve.getField();
+ BigInteger p = field.getP();
+ BigInteger a = curve.getA();
+ BigInteger b = curve.getB();
+ ECPoint generator = param.getGenerator();
+ BigInteger x = generator.getAffineX();
+ BigInteger y = generator.getAffineY();
+ BigInteger order = param.getOrder();
+ int cofactor = param.getCofactor();
+
+ byte[][] keys = nativeGenerateKeyPair(p.toByteArray(), a.toByteArray(),
+ b.toByteArray(), x.toByteArray(), y.toByteArray(), order.toByteArray(), cofactor);
+ if (keys == null) {
+ throw new RuntimeException("nativeGenerateKeyPair failed");
+ }
+ BigInteger wX = new BigInteger(keys[0]);
+ BigInteger wY = new BigInteger(keys[1]);
+ BigInteger s = new BigInteger(keys[2]);
+ ECPoint w = new ECPoint(wX, wY);
+
+ ECPrivateKeyImpl privateKey = null;
+ ECPublicKeyImpl publicKey = null;
+ try {
+ publicKey = new ECPublicKeyImpl(w, param);
+ privateKey = new ECPrivateKeyImpl(s, param);
+ } catch (InvalidKeyException e) {
+ throw new ProviderException(e);
+ }
+ return new KeyPair(publicKey, privateKey);
+ }
+
+ protected static native byte[][] nativeGenerateParam(String curveName);
+
+ protected static native byte[][] nativeGenerateKeyPair(byte[] p, byte[] a, byte[] b, byte[] x, byte[] y,
+ byte[] order, int cofactor);
+}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEMac.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEHMac.java
similarity index 90%
rename from jdk/src/solaris/classes/org/openeuler/security/openssl/KAEMac.java
rename to jdk/src/solaris/classes/org/openeuler/security/openssl/KAEHMac.java
index 54c5cbdf..ce6b608e 100644
--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEMac.java
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEHMac.java
@@ -34,12 +34,12 @@ import java.security.spec.AlgorithmParameterSpec;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
-public abstract class KAEMac extends MacSpi implements Cloneable {
+public abstract class KAEHMac extends MacSpi {
private final String algorithm;
/**
- * The secret key used in this keyed MAC.
+ * The secret key used in this keyed HMAC.
*/
private byte[] keyBytes;
@@ -55,22 +55,22 @@ public abstract class KAEMac extends MacSpi implements Cloneable {
private HmacContextRef contextRef = null;
- private KAEMac(String algo, int size) {
+ private KAEHMac(String algo, int size) {
this.algorithm = algo;
this.digestSize = size;
}
- private static class HmacContextRef extends PhantomReference<KAEMac>
+ private static class HmacContextRef extends PhantomReference<KAEHMac>
implements Comparable<HmacContextRef> {
- private static ReferenceQueue<KAEMac> referenceQueue = new ReferenceQueue<>();
+ private static ReferenceQueue<KAEHMac> referenceQueue = new ReferenceQueue<>();
private static Set<HmacContextRef> referenceList = new ConcurrentSkipListSet<>();
private static boolean disableKaeDispose = Boolean.getBoolean("kae.disableKaeDispose");
private final long address;
- HmacContextRef(KAEMac kaeMac, long address) {
- super(kaeMac, referenceQueue);
+ HmacContextRef(KAEHMac kaeHMac, long address) {
+ super(kaeHMac, referenceQueue);
this.address = address;
if (!disableKaeDispose) {
referenceList.add(this);
@@ -187,32 +187,32 @@ public abstract class KAEMac extends MacSpi implements Cloneable {
}
}
- public static final class HmacMD5 extends KAEMac {
+ public static final class HmacMD5 extends KAEHMac {
public HmacMD5() {
super("MD5", 16);
}
}
- public static final class HmacSHA1 extends KAEMac {
+ public static final class HmacSHA1 extends KAEHMac {
public HmacSHA1() {
super("SHA1", 20);
}
}
- public static final class HmacSHA224 extends KAEMac {
+ public static final class HmacSHA224 extends KAEHMac {
public HmacSHA224() throws NoSuchAlgorithmException {
super("SHA224", 28);
}
}
- public static final class HmacSHA256 extends KAEMac {
+ public static final class HmacSHA256 extends KAEHMac {
public HmacSHA256() throws NoSuchAlgorithmException {
super("SHA256", 32);
}
}
- public static final class HmacSHA384 extends KAEMac {
+ public static final class HmacSHA384 extends KAEHMac {
public HmacSHA384() throws NoSuchAlgorithmException {
super("SHA384", 48);
}
}
- public static final class HmacSHA512 extends KAEMac {
+ public static final class HmacSHA512 extends KAEHMac {
public HmacSHA512() throws NoSuchAlgorithmException {
super("SHA512", 64);
}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java
index fb84b768..419a8744 100644
--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java
@@ -25,13 +25,17 @@
package org.openeuler.security.openssl;
import java.io.BufferedWriter;
+import java.io.BufferedInputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Date;
+import java.util.Properties;
import java.security.Provider;
/**
@@ -79,8 +83,63 @@ public class KAEProvider extends Provider {
KAEProvider.excp = null; // Exception already logged, clean it.
}
- private void putCipherAES() {
- final String blockModes = "ECB|CBC|CTR";
+ private Properties getProp() {
+ Properties props = new Properties();
+ String sep = File.separator;
+ File propFile = new File(System.getProperty("java.home") + sep + "lib" + sep +
+ "ext" + sep + "kaeprovider.conf");
+ if (propFile.exists()) {
+ try (InputStream is = new BufferedInputStream(new FileInputStream(propFile))) {
+ props.load(is);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return props;
+ }
+
+ public KAEProvider() {
+ super("KAEProvider", 1.8d, "KAE provider");
+ if (needLog) {
+ logStart(excp);
+ needLog = false; // Log only once
+ }
+ Properties props = getProp();
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.md5"))) {
+ putMD5();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.sha256"))) {
+ putSHA256();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.sha384"))) {
+ putSHA384();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.sm3"))) {
+ putSM3();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.aes"))) {
+ putAES();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.sm4"))) {
+ putSM4();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.hmac"))) {
+ putHMAC();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.rsa"))) {
+ putRSA();
+ putSignatureRSA();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.dh"))) {
+ putDH();
+ }
+ if (!"false".equalsIgnoreCase(props.getProperty("kae.ec"))) {
+ putEC();
+ }
+ }
+
+ private void putAES() {
+ final String blockModes = "ECB|CBC|CTR|GCM";
final String blockPads = "NOPADDING|PKCS5PADDING";
put("Cipher.AES SupportedModes", blockModes);
@@ -94,6 +153,8 @@ public class KAEProvider extends Provider {
put("Cipher.AES/ECB/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes$Ecb$PKCS5Padding");
put("Alg.Alias.Cipher.AES/ECB/PKCS7Padding", "AES/ECB/PKCS5Padding");
put("Cipher.AES/CTR/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes$Ctr$NoPadding");
+ put("Cipher.AES/GCM/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes$Gcm$NoPadding");
+ put("Alg.Alias.Cipher.AES/GCM/PKCS5Padding", "AES/GCM/NoPadding"); // PKCS5Padding -> noPadding
put("Cipher.AES_128/CBC/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes_128$Cbc$PKCS5Padding");
put("Cipher.AES_128/CBC/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_128$Cbc$NoPadding");
@@ -102,6 +163,8 @@ public class KAEProvider extends Provider {
put("Cipher.AES_128/ECB/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes_128$Ecb$PKCS5Padding");
put("Alg.Alias.Cipher.AES_128/ECB/PKCS7Padding", "AES_128/ECB/PKCS5Padding");
put("Cipher.AES_128/CTR/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_128$Ctr$NoPadding");
+ put("Cipher.AES_128/GCM/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_128$Gcm$NoPadding");
+ put("Alg.Alias.Cipher.AES_128/GCM/PKCS5Padding", "AES/GCM/NoPadding");
put("Cipher.AES_192/CBC/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes_192$Cbc$PKCS5Padding");
put("Cipher.AES_192/CBC/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_192$Cbc$NoPadding");
@@ -110,6 +173,8 @@ public class KAEProvider extends Provider {
put("Cipher.AES_192/ECB/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes_192$Ecb$PKCS5Padding");
put("Alg.Alias.Cipher.AES_192/ECB/PKCS7Padding", "AES_192/ECB/PKCS5Padding");
put("Cipher.AES_192/CTR/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_192$Ctr$NoPadding");
+ put("Cipher.AES_192/GCM/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_192$Gcm$NoPadding");
+ put("Alg.Alias.Cipher.AES_192/GCM/PKCS5Padding", "AES/GCM/NoPadding");
put("Cipher.AES_256/CBC/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes_256$Cbc$PKCS5Padding");
put("Cipher.AES_256/CBC/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_256$Cbc$NoPadding");
@@ -118,15 +183,50 @@ public class KAEProvider extends Provider {
put("Cipher.AES_256/ECB/PKCS5Padding", "org.openeuler.security.openssl.KAEAESCipher$Aes_256$Ecb$PKCS5Padding");
put("Alg.Alias.Cipher.AES_256/ECB/PKCS7Padding", "AES_256/ECB/PKCS5Padding");
put("Cipher.AES_256/CTR/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_256$Ctr$NoPadding");
+ put("Cipher.AES_256/GCM/NoPadding", "org.openeuler.security.openssl.KAEAESCipher$Aes_256$Gcm$NoPadding");
+ put("Alg.Alias.Cipher.AES_256/GCM/PKCS5Padding", "AES/GCM/NoPadding");
}
- private void putMessageDigest() {
+ private void putMD5() {
put("MessageDigest.MD5", "org.openeuler.security.openssl.KAEDigest$MD5");
+ }
+
+ private void putSHA256() {
put("MessageDigest.SHA-256", "org.openeuler.security.openssl.KAEDigest$SHA256");
+ }
+
+ private void putSHA384() {
put("MessageDigest.SHA-384", "org.openeuler.security.openssl.KAEDigest$SHA384");
}
- private void putCipherRSA() {
+ private void putSM3() {
+ put("MessageDigest.SM3", "org.openeuler.security.openssl.KAEDigest$SM3");
+ }
+
+ private void putSM4() {
+ final String blockModes = "ECB|CBC|CTR|OFB";
+ final String blockPads = "NOPADDING|PKCS5PADDING";
+
+ put("Cipher.SM4 SupportedModes", blockModes);
+ put("Cipher.SM4 SupportedPaddings", blockPads);
+ put("Cipher.SM4", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Ecb$PKCS5Padding");
+
+ put("Cipher.SM4/CBC/PKCS5Padding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Cbc$PKCS5Padding");
+ put("Cipher.SM4/CBC/NoPadding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Cbc$NoPadding");
+ put("Alg.Alias.Cipher.SM4/CBC/PKCS7Padding", "SM4/CBC/PKCS5Padding");
+ put("Cipher.SM4/ECB/NoPadding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Ecb$NoPadding");
+ put("Cipher.SM4/ECB/PKCS5Padding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Ecb$PKCS5Padding");
+ put("Alg.Alias.Cipher.SM4/ECB/PKCS7Padding", "SM4/ECB/PKCS5Padding");
+ put("Cipher.SM4/CTR/NoPadding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Ctr$NoPadding");
+ put("Cipher.SM4/OFB/NoPadding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Ofb$NoPadding");
+ put("Cipher.SM4/OFB/PKCS5Padding", "org.openeuler.security.openssl.KAESM4Cipher$Sm4$Ofb$PKCS5Padding");
+ put("Alg.Alias.Cipher.SM4/OFB/PKCS7Padding", "SM4/OFB/PKCS5Padding");
+
+ put("KeyGenerator.SM4", "com.sun.crypto.provider.AESKeyGenerator");
+ put("AlgorithmParameters.SM4", "com.sun.crypto.provider.AESParameters");
+ }
+
+ private void putRSA() {
// rsa
put("KeyPairGenerator.RSA", "org.openeuler.security.openssl.KAERSAKeyPairGenerator$Legacy");
put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
@@ -154,27 +254,78 @@ public class KAEProvider extends Provider {
"|java.security.interfaces.RSAPrivateKey");
}
- private void putMAC() {
- put("MAC.HmacMD5", "org.openeuler.security.openssl.KAEMac$HmacMD5");
- put("MAC.HmacSHA1", "org.openeuler.security.openssl.KAEMac$HmacSHA1");
- put("MAC.HmacSHA224", "org.openeuler.security.openssl.KAEMac$HmacSHA224");
- put("MAC.HmacSHA256", "org.openeuler.security.openssl.KAEMac$HmacSHA256");
- put("MAC.HmacSHA384", "org.openeuler.security.openssl.KAEMac$HmacSHA384");
- put("MAC.HmacSHA512", "org.openeuler.security.openssl.KAEMac$HmacSHA512");
+ private void putHMAC() {
+ put("MAC.HmacMD5", "org.openeuler.security.openssl.KAEHMac$HmacMD5");
+ put("MAC.HmacSHA1", "org.openeuler.security.openssl.KAEHMac$HmacSHA1");
+ put("MAC.HmacSHA224", "org.openeuler.security.openssl.KAEHMac$HmacSHA224");
+ put("MAC.HmacSHA256", "org.openeuler.security.openssl.KAEHMac$HmacSHA256");
+ put("MAC.HmacSHA384", "org.openeuler.security.openssl.KAEHMac$HmacSHA384");
+ put("MAC.HmacSHA512", "org.openeuler.security.openssl.KAEHMac$HmacSHA512");
}
- public KAEProvider() {
- super("KAEProvider", 1.8d, "KAE provider");
- if (needLog) {
- logStart(excp);
- needLog = false; // Log only once
- }
- putMessageDigest();
- putCipherAES();
- putMAC();
- putCipherRSA();
+ private void putDH() {
+ put("KeyPairGenerator.DiffieHellman", "org.openeuler.security.openssl.KAEDHKeyPairGenerator");
+ put("Alg.Alias.KeyPairGenerator.DH", "DiffieHellman");
+ put("KeyAgreement.DiffieHellman", "org.openeuler.security.openssl.KAEDHKeyAgreement");
+ put("Alg.Alias.KeyAgreement.DH", "DiffieHellman");
}
+ private void putSignatureRSA() {
+ put("Signature.MD5withRSA",
+ "org.openeuler.security.openssl.KAERSASignature$MD5withRSA");
+ put("Signature.SHA1withRSA",
+ "org.openeuler.security.openssl.KAERSASignature$SHA1withRSA");
+ put("Signature.SHA224withRSA",
+ "org.openeuler.security.openssl.KAERSASignature$SHA224withRSA");
+ put("Signature.SHA256withRSA",
+ "org.openeuler.security.openssl.KAERSASignature$SHA256withRSA");
+ put("Signature.SHA384withRSA",
+ "org.openeuler.security.openssl.KAERSASignature$SHA384withRSA");
+ put("Signature.SHA512withRSA",
+ "org.openeuler.security.openssl.KAERSASignature$SHA512withRSA");
+
+ // alias
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
+
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
+ put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA");
+
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.14", "SHA224withRSA");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA");
+
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
+
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
+
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
+
+ put("Signature.RSASSA-PSS", "org.openeuler.security.openssl.KAERSAPSSSignature");
+
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS");
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
+
+ // attributes for supported key classes
+ String rsaKeyClasses = "java.security.interfaces.RSAPublicKey" +
+ "|java.security.interfaces.RSAPrivateKey";
+ put("Signature.MD5withRSA SupportedKeyClasses", rsaKeyClasses);
+ put("Signature.SHA1withRSA SupportedKeyClasses", rsaKeyClasses);
+ put("Signature.SHA224withRSA SupportedKeyClasses", rsaKeyClasses);
+ put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
+ put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
+ put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
+ put("Signature.RSASSA-PSS SupportedKeyClasses", rsaKeyClasses);
+ }
+
+ private void putEC() {
+ put("KeyPairGenerator.EC", "org.openeuler.security.openssl.KAEECKeyPairGenerator");
+ put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC");
+ put("KeyAgreement.ECDH", "org.openeuler.security.openssl.KAEECDHKeyAgreement");
+ }
// init openssl
static native void initOpenssl() throws RuntimeException;
}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPSSSignature.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPSSSignature.java
new file mode 100644
index 00000000..cfe19d7b
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPSSSignature.java
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openeuler.security.openssl;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.interfaces.*;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+import sun.security.rsa.PSSParameters;
+import sun.security.rsa.RSACore;
+import sun.security.jca.JCAUtil;
+
+import javax.crypto.BadPaddingException;
+
+/**
+ * PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms.
+ * RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm,
+ * and salt length values through the required signature PSS parameters.
+ * We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512.
+ * The Openssl does not support rsa signatures with SHA-512/224 and SHA-512/256 as the digest algorithm,
+ * so we have not implemented them.
+ * The Openssl does not support non-CRT private key , when signing with a non-CRT private key, we use the sun sign.
+ */
+public class KAERSAPSSSignature extends SignatureSpi {
+ // openssl unsupport rsa sign with digest algorithm
+ private static final Set<String> UNSUPPORTED_DIGEST_ALGORITHM = new HashSet<>(
+ Arrays.asList("SHA-512/224", "SHA-512/256"));
+
+ private static Method generateAndXorMethod;
+
+ private static Constructor mgf1Constructor;
+
+ private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8];
+
+ private static Exception exception;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ try {
+ Class<?> mgf1Class = Class.forName("sun.security.rsa.MGF1");
+ generateAndXorMethod = mgf1Class.getDeclaredMethod("generateAndXor",
+ byte[].class, int.class, int.class, int.class, byte[].class, int.class);
+ generateAndXorMethod.setAccessible(true);
+ mgf1Constructor = mgf1Class.getDeclaredConstructor(String.class);
+ mgf1Constructor.setAccessible(true);
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ exception = e;
+ }
+ return null;
+ }
+ });
+ }
+
+ // message digest implementation we use for hashing the data
+ private MessageDigest md;
+
+ // flag indicating whether the digest is reset
+ private boolean digestReset = true;
+
+ // private key, if initialized for signing
+ private RSAPrivateKey privKey = null;
+
+ // public key, if initialized for verifying
+ private RSAPublicKey pubKey = null;
+
+ // PSS parameters from signatures and keys respectively
+ private PSSParameterSpec sigParams = null;
+
+ // PRNG used to generate salt bytes if none given
+ private SecureRandom random;
+
+ /**
+ * Construct a new RSAPSSSignatur with arbitrary digest algorithm
+ */
+ public KAERSAPSSSignature() throws SignatureException {
+ if (exception != null) {
+ throw new SignatureException(exception.getMessage());
+ }
+ this.md = null;
+ }
+
+ // initialize for verification. See JCA doc
+ @Override
+ protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+ if (!(publicKey instanceof RSAPublicKey)) {
+ throw new InvalidKeyException("key must be RSAPublicKey");
+ }
+ this.pubKey = (RSAPublicKey) isValid((RSAKey) publicKey);
+ this.privKey = null;
+ resetDigest();
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+ engineInitSign(privateKey, null);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException {
+ if (!(privateKey instanceof RSAPrivateKey)) {
+ throw new InvalidKeyException("key must be RSAPrivateKey");
+ }
+ this.privKey = (RSAPrivateKey) isValid((RSAKey) privateKey);
+ this.pubKey = null;
+ this.random =
+ (random == null ? JCAUtil.getSecureRandom() : random);
+ resetDigest();
+ }
+
+ /**
+ * Utility method for checking the key PSS parameters against signature
+ * PSS parameters.
+ * Returns false if any of the digest/MGF algorithms and trailerField
+ * values does not match or if the salt length in key parameters is
+ * larger than the value in signature parameters.
+ */
+ private static boolean isCompatible(AlgorithmParameterSpec keyParams, PSSParameterSpec sigParams) {
+ if (keyParams == null) {
+ // key with null PSS parameters means no restriction
+ return true;
+ }
+ if (!(keyParams instanceof PSSParameterSpec)) {
+ return false;
+ }
+ // nothing to compare yet, defer the check to when sigParams is set
+ if (sigParams == null) {
+ return true;
+ }
+ PSSParameterSpec pssKeyParams = (PSSParameterSpec) keyParams;
+ // first check the salt length requirement
+ if (pssKeyParams.getSaltLength() > sigParams.getSaltLength()) {
+ return false;
+ }
+
+ // compare equality of the rest of fields based on DER encoding
+ PSSParameterSpec keyParams2 =
+ new PSSParameterSpec(pssKeyParams.getDigestAlgorithm(),
+ pssKeyParams.getMGFAlgorithm(),
+ pssKeyParams.getMGFParameters(),
+ sigParams.getSaltLength(),
+ pssKeyParams.getTrailerField());
+
+ // skip the JCA overhead
+ try {
+ byte[] encoded = PSSParameters.getEncoded(keyParams2);
+ byte[] encoded2 = PSSParameters.getEncoded(sigParams);
+ return Arrays.equals(encoded, encoded2);
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Validate the specified RSAKey and its associated parameters against
+ * internal signature parameters.
+ */
+ private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException {
+ try {
+ AlgorithmParameterSpec keyParams = rsaKey.getParams();
+ // validate key parameters
+ if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
+ throw new InvalidKeyException
+ ("Key contains incompatible PSS parameter values");
+ }
+ // validate key length
+ if (this.sigParams != null) {
+ Integer hLen =
+ KAEUtils.getDigestLength(this.sigParams.getDigestAlgorithm());
+ if (hLen == null) {
+ throw new ProviderException("Unsupported digest algo: " +
+ this.sigParams.getDigestAlgorithm());
+ }
+ checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength());
+ }
+ return rsaKey;
+ } catch (SignatureException e) {
+ throw new InvalidKeyException(e);
+ }
+ }
+
+ /**
+ * Validate the specified Signature PSS parameters.
+ */
+ private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p) throws InvalidAlgorithmParameterException {
+ if (p == null) {
+ throw new InvalidAlgorithmParameterException
+ ("Parameters cannot be null");
+ }
+ if (!(p instanceof PSSParameterSpec)) {
+ throw new InvalidAlgorithmParameterException
+ ("parameters must be type PSSParameterSpec");
+ }
+ // no need to validate again if same as current signature parameters
+ PSSParameterSpec params = (PSSParameterSpec) p;
+ if (params == this.sigParams) {
+ return params;
+ }
+
+ RSAKey key = (this.privKey == null ? this.pubKey : this.privKey);
+ // check against keyParams if set
+ if (key != null) {
+ if (!isCompatible(key.getParams(), params)) {
+ throw new InvalidAlgorithmParameterException
+ ("Signature parameters does not match key parameters");
+ }
+ }
+ // now sanity check the parameter values
+ if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
+ throw new InvalidAlgorithmParameterException("Only supports MGF1");
+ }
+ if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
+ throw new InvalidAlgorithmParameterException("Only supports TrailerFieldBC(1)");
+ }
+ String digestAlgo = params.getDigestAlgorithm();
+ // check key length again
+ if (key != null) {
+ try {
+ int hLen = KAEUtils.getDigestLength(digestAlgo);
+ checkKeyLength(key, hLen, params.getSaltLength());
+ } catch (SignatureException e) {
+ throw new InvalidAlgorithmParameterException(e);
+ }
+ }
+ return params;
+ }
+
+ /**
+ * Ensure the object is initialized with key and parameters and
+ * reset digest
+ */
+ private void ensureInit() throws SignatureException {
+ RSAKey key = (this.privKey == null ? this.pubKey : this.privKey);
+ if (key == null) {
+ throw new SignatureException("Missing key");
+ }
+ if (this.sigParams == null) {
+ // Parameters are required for signature verification
+ throw new SignatureException
+ ("Parameters required for RSASSA-PSS signatures");
+ }
+ }
+
+ /**
+ * Utility method for checking key length against digest length and
+ * salt length
+ */
+ private static void checkKeyLength(RSAKey key, int digestLen, int saltLen) throws SignatureException {
+ if (key != null) {
+ int keyLength = getKeyLengthInBits(key) >> 3;
+ int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2);
+ if (keyLength < minLength) {
+ throw new SignatureException
+ ("Key is too short, need min " + minLength);
+ }
+ }
+ }
+
+ /**
+ * Reset the message digest if it is not already reset.
+ */
+ private void resetDigest() {
+ if (digestReset == false) {
+ this.md.reset();
+ digestReset = true;
+ }
+ }
+
+ /**
+ * Return the message digest value.
+ */
+ private byte[] getDigestValue() {
+ digestReset = true;
+ return this.md.digest();
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ ensureInit();
+ this.md.update(b);
+ digestReset = false;
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ ensureInit();
+ this.md.update(b, off, len);
+ digestReset = false;
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(ByteBuffer b) {
+ try {
+ ensureInit();
+ } catch (SignatureException se) {
+ // hack for working around API bug
+ throw new RuntimeException(se.getMessage());
+ }
+ this.md.update(b);
+ digestReset = false;
+ }
+
+ // determine whether the digest is valid
+ private boolean isValidDigest() {
+ String digestName = this.md.getAlgorithm();
+ if (UNSUPPORTED_DIGEST_ALGORITHM.contains(digestName.toUpperCase(Locale.ROOT))) {
+ return false;
+ }
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ String mgfDigestName = "";
+ if (mgfParams != null) {
+ mgfDigestName =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ }
+ return !UNSUPPORTED_DIGEST_ALGORITHM.contains(mgfDigestName.toUpperCase(Locale.ROOT));
+ }
+
+ // determine whether use kae sign
+ private boolean useKaeSign() {
+ return (privKey instanceof RSAPrivateCrtKey) && isValidDigest();
+ }
+
+ // sun sign
+ private byte[] sunSign(byte[] mHash) throws SignatureException {
+ try {
+ byte[] encoded = encodeSignature(mHash);
+ return RSACore.rsa(encoded, privKey, true);
+ } catch (GeneralSecurityException e) {
+ throw new SignatureException("Could not sign data", e);
+ } catch (IOException e) {
+ throw new SignatureException("Could not encode data", e);
+ }
+ }
+
+ // kae sign
+ private byte[] kaeSign(byte[] mHash) throws SignatureException {
+ String kaeDigestName = KAEUtils.getKAEDigestName(this.sigParams.getDigestAlgorithm());
+ String mgfDigestName = kaeDigestName;
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ if (mgfParams != null) {
+ mgfDigestName =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ }
+ String mgf1DigestName = KAEUtils.getKAEDigestName(mgfDigestName);
+
+ RSAPrivateCrtKey privateCrtKey = (RSAPrivateCrtKey) privKey;
+ long keyAddress = KAERSACipher.nativeCreateRSAPrivateCrtKey(
+ privateCrtKey.getModulus().toByteArray(),
+ privateCrtKey.getPublicExponent().toByteArray(),
+ privateCrtKey.getPrivateExponent().toByteArray(),
+ privateCrtKey.getPrimeP().toByteArray(),
+ privateCrtKey.getPrimeQ().toByteArray(),
+ privateCrtKey.getPrimeExponentP().toByteArray(),
+ privateCrtKey.getPrimeExponentQ().toByteArray(),
+ privateCrtKey.getCrtCoefficient().toByteArray());
+ byte[] bytes;
+ try {
+ bytes = KAERSASignatureNative.pssSign(keyAddress, kaeDigestName, mHash,
+ KAERSAPaddingType.PKCS1PssPadding.getId(),
+ mgf1DigestName, this.sigParams.getSaltLength());
+ } catch (SignatureException e) {
+ throw e;
+ } finally {
+ KAERSACipher.nativeFreeKey(keyAddress);
+ }
+ return bytes;
+ }
+
+ // sign the data and return the signature. See JCA doc
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ ensureInit();
+ byte[] mHash = getDigestValue();
+ if (useKaeSign()) {
+ return kaeSign(mHash);
+ }
+ return sunSign(mHash);
+ }
+
+ // determine whether use kae verify
+ private boolean useKaeVerify() {
+ return isValidDigest();
+ }
+
+ // sun verify
+ private boolean sunVerify(byte[] mHash, byte[] sigBytes) throws SignatureException {
+ try {
+ byte[] decrypted = RSACore.rsa(sigBytes, this.pubKey);
+ return decodeSignature(mHash, decrypted);
+ } catch (javax.crypto.BadPaddingException e) {
+ // occurs if the app has used the wrong RSA public key
+ // or if sigBytes is invalid
+ // return false rather than propagating the exception for
+ // compatibility/ease of use
+ return false;
+ } catch (IOException e) {
+ throw new SignatureException("Signature encoding error", e);
+ } finally {
+ resetDigest();
+ }
+ }
+
+ // kae verify
+ private boolean kaeVerify(byte[] mHash, byte[] sigBytes) throws SignatureException {
+ String kaeDigestName = KAEUtils.getKAEDigestName(this.sigParams.getDigestAlgorithm());
+ String mgfDigestName = kaeDigestName;
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ if (mgfParams != null) {
+ mgfDigestName =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ }
+ String mgf1KaeDigestName = KAEUtils.getKAEDigestName(mgfDigestName);
+
+ long keyAddress = KAERSACipher.nativeCreateRSAPublicKey(this.pubKey.getModulus().toByteArray(),
+ this.pubKey.getPublicExponent().toByteArray());
+ boolean verify;
+ try {
+ verify = KAERSASignatureNative.pssVerify(keyAddress, kaeDigestName, mHash,
+ KAERSAPaddingType.PKCS1PssPadding.getId(), mgf1KaeDigestName,
+ this.sigParams.getSaltLength(), sigBytes);
+ } catch (SignatureException e) {
+ throw e;
+ } catch (BadPaddingException e) {
+ // occurs if the app has used the wrong RSA public key
+ // or if sigBytes is invalid or sourceBytes is invalid
+ // return false rather than propagating the exception for
+ // compatibility/ease of use
+ return false;
+ } finally {
+ resetDigest();
+ KAERSACipher.nativeFreeKey(keyAddress);
+ }
+ return verify;
+ }
+
+ // verify the data and return the result. See JCA doc
+ // should be reset to the state after engineInitVerify call.
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ ensureInit();
+ if (sigBytes.length != RSACore.getByteLength(this.pubKey)) {
+ throw new SignatureException("Signature length not correct: got " +
+ sigBytes.length + " but was expecting " +
+ RSACore.getByteLength(this.pubKey));
+ }
+ byte[] mHash = getDigestValue();
+ if (useKaeVerify()) {
+ return kaeVerify(mHash, sigBytes);
+ }
+ return sunVerify(mHash, sigBytes);
+ }
+
+ // return the modulus length in bits
+ private static int getKeyLengthInBits(RSAKey k) {
+ if (k != null) {
+ return k.getModulus().bitLength();
+ }
+ return -1;
+ }
+
+ /**
+ * Encode the digest 'mHash', return the to-be-signed data.
+ * Also used by the PKCS#11 provider.
+ */
+ private byte[] encodeSignature(byte[] mHash) throws IOException, DigestException {
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ String mgfDigestAlgo;
+ if (mgfParams != null) {
+ mgfDigestAlgo =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ } else {
+ mgfDigestAlgo = this.md.getAlgorithm();
+ }
+ try {
+ int emBits = getKeyLengthInBits(this.privKey) - 1;
+ int emLen = (emBits + 7) >> 3;
+ int hLen = this.md.getDigestLength();
+ int dbLen = emLen - hLen - 1;
+ int sLen = this.sigParams.getSaltLength();
+
+ // maps DB into the corresponding region of EM and
+ // stores its bytes directly into EM
+ byte[] em = new byte[emLen];
+
+ // step7 and some of step8
+ em[dbLen - sLen - 1] = (byte) 1; // set DB's padding2 into EM
+ em[em.length - 1] = (byte) 0xBC; // set trailer field of EM
+
+ if (!digestReset) {
+ throw new ProviderException("Digest should be reset");
+ }
+ // step5: generates M' using padding1, mHash, and salt
+ this.md.update(EIGHT_BYTES_OF_ZEROS);
+ digestReset = false; // mark digest as it now has data
+ this.md.update(mHash);
+ if (sLen != 0) {
+ // step4: generate random salt
+ byte[] salt = new byte[sLen];
+ this.random.nextBytes(salt);
+ this.md.update(salt);
+
+ // step8: set DB's salt into EM
+ System.arraycopy(salt, 0, em, dbLen - sLen, sLen);
+ }
+ // step6: generate H using M'
+ this.md.digest(em, dbLen, hLen); // set H field of EM
+ digestReset = true;
+
+ // step7 and 8 are already covered by the code which setting up
+ // EM as above
+
+ // step9 and 10: feed H into MGF and xor with DB in EM
+ Object mgf1 = mgf1Constructor.newInstance(mgfDigestAlgo);
+ generateAndXorMethod.invoke(mgf1, em, dbLen, hLen, dbLen, em, 0);
+ // step11: set the leftmost (8emLen - emBits) bits of the leftmost
+ // octet to 0
+ int numZeroBits = (emLen << 3) - emBits;
+ if (numZeroBits != 0) {
+ byte mask = (byte) (0xff >>> numZeroBits);
+ em[0] = (byte) (em[0] & mask);
+ }
+
+ // step12: em should now holds maskedDB || hash h || 0xBC
+ return em;
+ } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ private String getMgfDigestAlgo() {
+ String mgfDigestAlgo;
+ AlgorithmParameterSpec mgfParams = this.sigParams.getMGFParameters();
+ if (mgfParams != null) {
+ mgfDigestAlgo =
+ ((MGF1ParameterSpec) mgfParams).getDigestAlgorithm();
+ } else {
+ mgfDigestAlgo = this.md.getAlgorithm();
+ }
+ return mgfDigestAlgo;
+ }
+
+ private void generateAndXor(String mgfDigestAlgo, byte[] em, int dbLen, int hLen) throws IOException {
+ Object mgf1;
+ try {
+ mgf1 = mgf1Constructor.newInstance(mgfDigestAlgo);
+ generateAndXorMethod.invoke(mgf1, em, dbLen, hLen, dbLen, em, 0);
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ throw new IOException(e.toString());
+ }
+ }
+
+ /**
+ * Decode the signature data. Verify that the object identifier matches
+ * and return the message digest.
+ */
+ private boolean decodeSignature(byte[] mHash, byte[] em) throws IOException {
+ int hLen = mHash.length;
+ int sLen = this.sigParams.getSaltLength();
+ int emLen = em.length;
+ int emBits = getKeyLengthInBits(this.pubKey) - 1;
+
+ // step3
+ if (emLen < (hLen + sLen + 2)) {
+ return false;
+ }
+
+ // step4
+ if (em[emLen - 1] != (byte) 0xBC) {
+ return false;
+ }
+
+ // step6: check if the leftmost (8emLen - emBits) bits of the leftmost
+ // octet are 0
+ int numZeroBits = (emLen << 3) - emBits;
+ if (numZeroBits != 0) {
+ byte mask = (byte) (0xff << (8 - numZeroBits));
+ if ((em[0] & mask) != 0) {
+ return false;
+ }
+ }
+
+ // step 7 and 8
+ int dbLen = emLen - hLen - 1;
+
+ // generateAndXor
+ String mgfDigestAlgo = getMgfDigestAlgo();
+ generateAndXor(mgfDigestAlgo, em, dbLen, hLen);
+
+ // step9: set the leftmost (8emLen - emBits) bits of the leftmost
+ // octet to 0
+ if (numZeroBits != 0) {
+ byte mask = (byte) (0xff >>> numZeroBits);
+ em[0] = (byte) (em[0] & mask);
+ }
+
+ // step10
+ int index = 0;
+ for (; index < dbLen - sLen - 1; index++) {
+ if (em[index] != 0) {
+ return false;
+ }
+ }
+ if (em[index] != 0x01) {
+ return false;
+ }
+ // step12 and 13
+ this.md.update(EIGHT_BYTES_OF_ZEROS);
+ digestReset = false;
+ this.md.update(mHash);
+ if (sLen > 0) {
+ this.md.update(em, (dbLen - sLen), sLen);
+ }
+ byte[] digest2 = this.md.digest();
+ digestReset = true;
+
+ // step14
+ byte[] digestInEM = Arrays.copyOfRange(em, dbLen, emLen - 1);
+ return MessageDigest.isEqual(digest2, digestInEM);
+ }
+
+ // set parameter, not supported. See JCA doc
+ @Deprecated
+ @Override
+ protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
+ throw new UnsupportedOperationException("setParameter() not supported");
+ }
+
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
+ this.sigParams = validateSigParams(params);
+ // disallow changing parameters when digest has been used
+ if (!digestReset) {
+ throw new ProviderException
+ ("Cannot set parameters during operations");
+ }
+ String newHashAlg = this.sigParams.getDigestAlgorithm();
+ // re-allocate md if not yet assigned or algorithm changed
+ if ((this.md == null) ||
+ !(this.md.getAlgorithm().equalsIgnoreCase(newHashAlg))) {
+ try {
+ this.md = MessageDigest.getInstance(newHashAlg);
+ } catch (NoSuchAlgorithmException nsae) {
+ // should not happen as we pick default digest algorithm
+ throw new InvalidAlgorithmParameterException("Unsupported digest algorithm " + newHashAlg, nsae);
+ }
+ }
+ }
+
+ // get parameter, not supported. See JCA doc
+ @Deprecated
+ @Override
+ protected Object engineGetParameter(String param) throws InvalidParameterException {
+ throw new UnsupportedOperationException("getParameter() not supported");
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ AlgorithmParameters ap = null;
+ if (this.sigParams != null) {
+ try {
+ ap = AlgorithmParameters.getInstance("RSASSA-PSS");
+ ap.init(this.sigParams);
+ } catch (GeneralSecurityException gse) {
+ throw new ProviderException(gse.getMessage());
+ }
+ }
+ return ap;
+ }
+}
+
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPaddingType.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPaddingType.java
index 04036b8d..022271d9 100644
--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPaddingType.java
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSAPaddingType.java
@@ -50,7 +50,10 @@ enum KAERSAPaddingType {
"OAEPWITHSHA-512ANDMGF1PADDING",
"OAEPWITHSHA-512/224ANDMGF1PADDING",
"OAEPWITHSHA-512/256ANDMGF1PADDING"))
- );
+ ),
+
+ // PSS
+ PKCS1PssPadding(6, "RSA_PKCS1_PSS_PADDING");
private final int id;
private final String name;
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSASignature.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSASignature.java
new file mode 100644
index 00000000..c524f277
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSASignature.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import sun.security.rsa.RSACore;
+import sun.security.rsa.RSAKeyFactory;
+import sun.security.rsa.RSAPadding;
+import sun.security.rsa.RSAUtil;
+import sun.security.rsa.RSAUtil.KeyType;
+import sun.security.util.*;
+import sun.security.x509.AlgorithmId;
+
+import javax.crypto.BadPaddingException;
+
+/**
+ * We support support rsa signatures with MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 as the digest algorithm.
+ * The Openssl does not support rsa signatures with SHA-512/224 and SHA-512/256 as the digest algorithm,
+ * so we have not implemented them.
+ * The Openssl does not support non-CRT private key , when signing with a non-CRT private key, we use the sun sign.
+ */
+public abstract class KAERSASignature extends SignatureSpi {
+ // we sign an ASN.1 SEQUENCE of AlgorithmId and digest
+ // it has the form 30:xx:30:xx:[digestOID]:05:00:04:xx:[digest]
+ // this means the encoded length is (8 + digestOID.length + digest.length)
+ private static final int BASE_LENGTH = 8;
+
+ private String digestAlgorithm;
+
+ // object identifier for the message digest algorithm used
+ private final ObjectIdentifier digestOID;
+
+ // length of the encoded signature blob
+ private final int encodedLength;
+
+ // message digest implementation we use
+ private final MessageDigest md;
+
+ // flag indicating whether the digest is reset
+ private boolean digestReset;
+
+ // private key, if initialized for signing
+ private RSAPrivateKey privateKey;
+
+ // public key, if initialized for verifying
+ private RSAPublicKey publicKey;
+
+ // padding to use, set when the initSign/initVerify is called
+ private RSAPadding padding;
+
+ /**
+ * Construct a new RSASignature. Used by subclasses.
+ */
+ KAERSASignature(String algorithm, ObjectIdentifier digestOID, int oidLength) {
+ this.digestAlgorithm = algorithm;
+ this.digestOID = digestOID;
+ try {
+ md = MessageDigest.getInstance(algorithm);
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(e);
+ }
+ digestReset = true;
+ encodedLength = BASE_LENGTH + oidLength + md.getDigestLength();
+ }
+
+ // initialize for verification. See JCA doc
+ @Override
+ protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+ RSAPublicKey rsaKey = (RSAPublicKey) RSAKeyFactory.toRSAKey(publicKey);
+ this.privateKey = null;
+ this.publicKey = rsaKey;
+ initCommon(rsaKey, null);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+ engineInitSign(privateKey, null);
+ }
+
+ // initialize for signing. See JCA doc
+ @Override
+ protected void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException {
+ RSAPrivateKey rsaKey =
+ (RSAPrivateKey) RSAKeyFactory.toRSAKey(privateKey);
+ this.privateKey = rsaKey;
+ this.publicKey = null;
+ initCommon(rsaKey, random);
+ }
+
+ /**
+ * Init code common to sign and verify.
+ */
+ private void initCommon(RSAKey rsaKey, SecureRandom random) throws InvalidKeyException {
+ try {
+ RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams());
+ } catch (ProviderException e) {
+ throw new InvalidKeyException("Invalid key for RSA signatures", e);
+ }
+ resetDigest();
+ int keySize = RSACore.getByteLength(rsaKey);
+ try {
+ padding = RSAPadding.getInstance
+ (RSAPadding.PAD_BLOCKTYPE_1, keySize, random);
+ } catch (InvalidAlgorithmParameterException iape) {
+ throw new InvalidKeyException(iape.getMessage());
+ }
+ int maxDataSize = padding.getMaxDataSize();
+ if (encodedLength > maxDataSize) {
+ throw new InvalidKeyException
+ ("Key is too short for this signature algorithm");
+ }
+ }
+
+ /**
+ * Reset the message digest if it is not already reset.
+ */
+ private void resetDigest() {
+ if (digestReset == false) {
+ md.reset();
+ digestReset = true;
+ }
+ }
+
+ /**
+ * Return the message digest value.
+ */
+ private byte[] getDigestValue() {
+ digestReset = true;
+ return md.digest();
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ md.update(b);
+ digestReset = false;
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ md.update(b, off, len);
+ digestReset = false;
+ }
+
+ // update the signature with the plaintext data. See JCA doc
+ @Override
+ protected void engineUpdate(ByteBuffer b) {
+ md.update(b);
+ digestReset = false;
+ }
+
+ // sign the data and return the signature. See JCA doc
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ if (privateKey == null) {
+ throw new SignatureException("Missing private key");
+ }
+
+ byte[] digest = getDigestValue();
+ if (useKaeSign()) {
+ return kaeSign(digest);
+ }
+ return sunSign(digest);
+ }
+
+ // determine if use kae sign , openssl do not support non-CRT private key
+ private boolean useKaeSign() {
+ return privateKey instanceof RSAPrivateCrtKey;
+ }
+
+ // sun sign
+ private byte[] sunSign(byte[] digest) throws SignatureException {
+ try {
+ byte[] encoded = encodeSignature(digestOID, digest);
+ byte[] padded = padding.pad(encoded);
+ return RSACore.rsa(padded, privateKey, true);
+ } catch (GeneralSecurityException e) {
+ throw new SignatureException("Could not sign data", e);
+ } catch (IOException e) {
+ throw new SignatureException("Could not encode data", e);
+ }
+ }
+
+ // kae sign
+ private byte[] kaeSign(byte[] digest) throws SignatureException {
+ String kaeDigestName = KAEUtils.getKAEDigestName(this.digestAlgorithm);
+ RSAPrivateCrtKey privateCrtKey = (RSAPrivateCrtKey) privateKey;
+ long keyAddress = KAERSACipher.nativeCreateRSAPrivateCrtKey(
+ privateCrtKey.getModulus().toByteArray(),
+ privateCrtKey.getPublicExponent().toByteArray(),
+ privateCrtKey.getPrivateExponent().toByteArray(),
+ privateCrtKey.getPrimeP().toByteArray(),
+ privateCrtKey.getPrimeQ().toByteArray(),
+ privateCrtKey.getPrimeExponentP().toByteArray(),
+ privateCrtKey.getPrimeExponentQ().toByteArray(),
+ privateCrtKey.getCrtCoefficient().toByteArray());
+ byte[] sigBytes;
+ try {
+ sigBytes = KAERSASignatureNative.rsaSign(keyAddress,
+ kaeDigestName, digest, KAERSAPaddingType.PKCS1Padding.getId());
+ } catch (SignatureException e) {
+ throw e;
+ } finally {
+ // free keyAddress
+ KAERSACipher.nativeFreeKey(keyAddress);
+ }
+ return sigBytes;
+ }
+
+ // verify the data and return the result. See JCA doc
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ if (publicKey == null) {
+ throw new SignatureException("Missing public key");
+ }
+
+ if (sigBytes.length != RSACore.getByteLength(publicKey)) {
+ throw new SignatureException("Signature length not correct: got " +
+ sigBytes.length + " but was expecting " +
+ RSACore.getByteLength(publicKey));
+ }
+ String kaeDigestName = KAEUtils.getKAEDigestName(this.digestAlgorithm);
+ byte[] digest = getDigestValue();
+ long keyAddress = KAERSACipher.nativeCreateRSAPublicKey(publicKey.getModulus().toByteArray(),
+ publicKey.getPublicExponent().toByteArray());
+
+ boolean verify;
+ try {
+ verify = KAERSASignatureNative.rsaVerify(keyAddress,
+ kaeDigestName, digest, KAERSAPaddingType.PKCS1Padding.getId(), sigBytes);
+ } catch (SignatureException e) {
+ throw e;
+ } catch (BadPaddingException e) {
+ // occurs if the app has used the wrong RSA public key
+ // or if sigBytes is invalid or sourceBytes is invalid
+ // return false rather than propagating the exception for
+ // compatibility/ease of use
+ return false;
+ } finally {
+ // free keyAddress
+ KAERSACipher.nativeFreeKey(keyAddress);
+ }
+ return verify;
+ }
+
+ /**
+ * Encode the digest, return the to-be-signed data.
+ * Also used by the PKCS#11 provider.
+ */
+ public static byte[] encodeSignature(ObjectIdentifier oid, byte[] digest) throws IOException {
+ DerOutputStream out = new DerOutputStream();
+ new AlgorithmId(oid).encode(out);
+ out.putOctetString(digest);
+ DerValue result =
+ new DerValue(DerValue.tag_Sequence, out.toByteArray());
+ return result.toByteArray();
+ }
+
+ // set parameter, not supported. See JCA doc
+ @Deprecated
+ @Override
+ protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
+ throw new UnsupportedOperationException("setParameter() not supported");
+ }
+
+ // See JCA doc
+ @Override
+ protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No parameters accepted");
+ }
+ }
+
+ // get parameter, not supported. See JCA doc
+ @Deprecated
+ @Override
+ protected Object engineGetParameter(String param) throws InvalidParameterException {
+ throw new UnsupportedOperationException("getParameter() not supported");
+ }
+
+ // See JCA doc
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ // Nested class for MD5withRSA signatures
+ public static final class MD5withRSA extends KAERSASignature {
+ public MD5withRSA() {
+ super("MD5", AlgorithmId.MD5_oid, 10);
+ }
+ }
+
+ // Nested class for SHA1withRSA signatures
+ public static final class SHA1withRSA extends KAERSASignature {
+ public SHA1withRSA() {
+ super("SHA-1", AlgorithmId.SHA_oid, 7);
+ }
+ }
+
+ // Nested class for SHA224withRSA signatures
+ public static final class SHA224withRSA extends KAERSASignature {
+ public SHA224withRSA() {
+ super("SHA-224", AlgorithmId.SHA224_oid, 11);
+ }
+ }
+
+ // Nested class for SHA256withRSA signatures
+ public static final class SHA256withRSA extends KAERSASignature {
+ public SHA256withRSA() {
+ super("SHA-256", AlgorithmId.SHA256_oid, 11);
+ }
+ }
+
+ // Nested class for SHA384withRSA signatures
+ public static final class SHA384withRSA extends KAERSASignature {
+ public SHA384withRSA() {
+ super("SHA-384", AlgorithmId.SHA384_oid, 11);
+ }
+ }
+
+ // Nested class for SHA512withRSA signatures
+ public static final class SHA512withRSA extends KAERSASignature {
+ public SHA512withRSA() {
+ super("SHA-512", AlgorithmId.SHA512_oid, 11);
+ }
+ }
+}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSASignatureNative.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSASignatureNative.java
new file mode 100644
index 00000000..8f256ffe
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAERSASignatureNative.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import javax.crypto.BadPaddingException;
+import java.security.SignatureException;
+
+public class KAERSASignatureNative {
+ // rsa sign
+ protected static native byte[] rsaSign(long keyAddress, String digestName, byte[] digestBytes, int paddingType)
+ throws SignatureException;
+
+ // rsa verify
+ protected static native boolean rsaVerify(long keyAddress, String digestName, byte[] digestBytes, int paddingType,
+ byte[] sigBytes) throws SignatureException, BadPaddingException;
+
+ // rsa pss sign
+ protected static native byte[] pssSign(long keyAddress, String digestName, byte[] digestBytes, int paddingType,
+ String mgf1DigestName, int saltLen) throws SignatureException;
+
+ // rsa pss verify
+ protected static native boolean pssVerify(long keyAddress, String digestName, byte[] digestBytes, int paddingType,
+ String mgf1DigestName, int saltLen, byte[] sigBytes) throws SignatureException, BadPaddingException;
+}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java
new file mode 100644
index 00000000..b189bea3
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Key;
+import java.util.Locale;
+
+import javax.crypto.NoSuchPaddingException;
+
+/*
+ * This class currently supports:
+ * - SM4/ECB/NOPADDING
+ * - SM4/ECB/PKCS5PADDING
+ * - SM4/CBC/NOPADDING
+ * - SM4/CBC/PKCS5PADDING
+ * - SM4/CTR/NOPADDING
+ * - SM4/OFB/NOPADDING
+ * - SM4/OFB/PKCS5PADDING
+ */
+abstract class KAESM4Cipher extends KAESymmetricCipherBase {
+
+ public static class Sm4 extends KAESM4Cipher {
+ public Sm4(Mode mode, Padding padding) {
+ super(mode, padding, 16);
+ }
+
+ public static class Cbc extends Sm4 {
+ public Cbc(Padding padding) {
+ super(Mode.CBC, padding);
+ }
+ public static class NoPadding extends Cbc {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ public static class PKCS5Padding extends Cbc {
+ public PKCS5Padding() {
+ super(Padding.PKCS5PADDING);
+ }
+ }
+ }
+
+ public static class Ecb extends Sm4 {
+ public Ecb(Padding padding) {
+ super(Mode.ECB, padding);
+ }
+ public static class NoPadding extends Ecb {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ public static class PKCS5Padding extends Ecb {
+ public PKCS5Padding() {
+ super(Padding.PKCS5PADDING);
+ }
+ }
+ }
+
+ public static class Ctr extends Sm4 {
+ public Ctr(Padding padding) {
+ super(Mode.CTR, padding);
+ }
+ public static class NoPadding extends Ctr {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ }
+
+ public static class Ofb extends Sm4 {
+ public Ofb(Padding padding) {
+ super(Mode.OFB, padding);
+ }
+ public static class NoPadding extends Ofb {
+ public NoPadding() {
+ super(Padding.NOPADDING);
+ }
+ }
+ public static class PKCS5Padding extends Ofb {
+ public PKCS5Padding() {
+ super(Padding.PKCS5PADDING);
+ }
+ }
+ }
+ }
+
+ KAESM4Cipher(Mode mode, Padding padding, int fixedKeySize) {
+ super(mode, padding, fixedKeySize, "SM4");
+ }
+
+ protected void checkKey(Key key) throws InvalidKeyException {
+ if (key == null || key.getEncoded() == null) {
+ throw new InvalidKeyException("Key cannot be null");
+ } else {
+ int keyLen = key.getEncoded().length;
+ if (keyLen != fixedKeySize) {
+ throw new InvalidKeyException("Only " + fixedKeySize + "-byte keys are accepted. Got: " + keyLen);
+ }
+ }
+ }
+
+ protected String getCipherName(int keyLength, Mode mode) {
+ return "sm4" + "-" + mode.toString().toLowerCase(Locale.US);
+ }
+
+ @Override
+ protected void engineSetMode(String modeStr) throws NoSuchAlgorithmException {
+ if (modeStr == null) {
+ throw new NoSuchAlgorithmException("null mode");
+ }
+
+ if (modeStr.equalsIgnoreCase("ECB")) {
+ mode = Mode.ECB;
+ } else if (modeStr.equalsIgnoreCase("CBC")) {
+ mode = Mode.CBC;
+ } else if (modeStr.equalsIgnoreCase("CTR")) {
+ mode = Mode.CTR;
+ } else if (modeStr.equalsIgnoreCase("OFB")) {
+ mode = Mode.OFB;
+ } else {
+ throw new NoSuchAlgorithmException("Unsupported mode " + mode);
+ }
+ }
+
+ @Override
+ protected void engineSetPadding(String paddingStr) throws NoSuchPaddingException {
+ if (paddingStr == null) {
+ throw new NoSuchPaddingException("null padding");
+ }
+ if (paddingStr.equalsIgnoreCase("PKCS7PADDING")) {
+ paddingStr = "PKCS5Padding";
+ }
+
+ if (paddingStr.equalsIgnoreCase("NOPADDING")) {
+ this.padding = Padding.NOPADDING;
+ } else if(paddingStr.equalsIgnoreCase("PKCS5PADDING")) {
+ if (mode == Mode.CTR) {
+ throw new NoSuchPaddingException("PKCS#5 padding not supported with CTR mode");
+ }
+ this.padding = Padding.PKCS5PADDING;
+ } else {
+ throw new NoSuchPaddingException("Unsupported padding " + paddingStr);
+ }
+ }
+
+ protected void checkIvBytes(byte[] ivBytes) throws InvalidAlgorithmParameterException {
+ if (ivBytes == null) {
+ throw new InvalidAlgorithmParameterException("Wrong IV length: iv is null ");
+ }
+ if (mode == Mode.CTR) {
+ if (ivBytes.length < 8) {
+ throw new InvalidAlgorithmParameterException("Wrong IV length: CTR mode requires IV of at least: 8 bytes.");
+ }
+ return;
+ }
+ if (ivBytes.length != blockSize) {
+ throw new InvalidAlgorithmParameterException("Wrong IV length: must be " + blockSize + " bytes long.");
+ }
+ }
+}
+
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESymmetricCipherBase.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESymmetricCipherBase.java
new file mode 100644
index 00000000..897e2c6b
--- /dev/null
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESymmetricCipherBase.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.security.openssl;
+
+import sun.security.jca.JCAUtil;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.nio.ByteBuffer;
+import java.security.*;
+import java.security.spec.*;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import javax.crypto.*;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/*
+ * Cipher wrapper class utilizing openssl APIs.
+ */
+abstract class KAESymmetricCipherBase extends CipherSpi {
+ enum Padding {
+ NOPADDING,
+ PKCS5PADDING
+ }
+
+ enum Mode {
+ ECB,
+ CBC,
+ CTR,
+ OFB,
+ GCM
+ }
+
+ protected final String keyAlgo;
+ protected final int blockSize = 16;
+ protected Mode mode;
+ protected Padding padding;
+ protected int fixedKeySize;
+
+ private CipherContextRef pCtx = null;
+ private byte[] keyValue;
+ protected byte[] iv;
+ private boolean initialized = false;
+ private boolean encrypt = false;
+ private int bytesBuffered = 0;
+
+ private boolean calledUpdate;
+ private String cipherName;
+
+ // for gcm
+ private final int defaultGcmTagLen = blockSize;
+ private final int defaultGcmIvLen = 12;
+ private int tagLengthInBytes;
+ private byte[] lastEncKey = null;
+ private byte[] lastEncIv = null;
+ private byte[] aad;
+
+ private static PublicKey constructPublicKey(byte[] encodedKey, String encodedKeyAlgorithm)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ PublicKey key;
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
+ key = keyFactory.generatePublic(keySpec);
+ } catch (NoSuchAlgorithmException e) {
+ throw new NoSuchAlgorithmException("No provider found for " + encodedKeyAlgorithm + " KeyFactory");
+ } catch (InvalidKeySpecException e) {
+ throw new InvalidKeyException("Cannot construct public key", e);
+ }
+ return key;
+ }
+
+ private static PrivateKey constructPrivateKey(byte[] encodedKey,
+ String encodedKeyAlgorithm) throws InvalidKeyException, NoSuchAlgorithmException {
+ PrivateKey key = null;
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
+ key = keyFactory.generatePrivate(keySpec);
+ } catch (NoSuchAlgorithmException e) {
+ throw new NoSuchAlgorithmException("No provider found for " + encodedKeyAlgorithm + " KeyFactory");
+ } catch (InvalidKeySpecException e) {
+ throw new InvalidKeyException("Cannot construct private key", e);
+ }
+ return key;
+ }
+
+ private static SecretKey constructSecretKey(byte[] encodedKey, String encodedKeyAlgorithm) {
+ return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
+ }
+
+ static final Key constructKey(int keyType, byte[] encodedKey,
+ String encodedKeyAlgorithm) throws NoSuchAlgorithmException, InvalidKeyException {
+ Key res = null;
+ switch (keyType) {
+ case Cipher.SECRET_KEY:
+ res = constructSecretKey(encodedKey, encodedKeyAlgorithm);
+ break;
+ case Cipher.PRIVATE_KEY:
+ res = constructPrivateKey(encodedKey, encodedKeyAlgorithm);
+ break;
+ case Cipher.PUBLIC_KEY:
+ res = constructPublicKey(encodedKey, encodedKeyAlgorithm);
+ break;
+ default:
+ throw new InvalidKeyException("Unknown keytype " + keyType);
+ }
+ return res;
+ }
+
+ KAESymmetricCipherBase(Mode mode, Padding padding, int fixedKeySize, String keyAlgo) {
+ this.mode = mode;
+ this.padding = padding;
+ this.fixedKeySize = fixedKeySize;
+ this.keyAlgo = keyAlgo;
+ }
+
+ private static class CipherContextRef extends PhantomReference<KAESymmetricCipherBase>
+ implements Comparable<CipherContextRef> {
+ private static ReferenceQueue<KAESymmetricCipherBase> refQueue = new ReferenceQueue<>();
+ private static Set<CipherContextRef> refList = new ConcurrentSkipListSet<>();
+ private static boolean disableKaeDispose = Boolean.getBoolean("kae.disableKaeDispose");
+
+ final long ctxAddress;
+
+ private static void drainRefQueueBounded() {
+ while (true) {
+ CipherContextRef next = (CipherContextRef) refQueue.poll();
+ if (next == null) {
+ break;
+ }
+ next.dispose(true);
+ }
+ }
+
+ CipherContextRef(KAESymmetricCipherBase kaeCipher, long ctxAddress) {
+ super(kaeCipher, refQueue);
+ this.ctxAddress = ctxAddress;
+ if (!disableKaeDispose) {
+ refList.add(this);
+ drainRefQueueBounded();
+ }
+ }
+
+ @Override
+ public int compareTo(CipherContextRef o) {
+ if (this.ctxAddress == o.ctxAddress) {
+ return 0;
+ } else {
+ return (this.ctxAddress < o.ctxAddress) ? -1 : 1;
+ }
+ }
+
+ void dispose(boolean needFree) {
+ if (!disableKaeDispose) {
+ refList.remove(this);
+ try {
+ if (needFree) {
+ nativeFree(ctxAddress);
+ }
+ } finally {
+ this.clear();
+ }
+ } else {
+ nativeFree(ctxAddress);
+ }
+ }
+ }
+
+ @Override
+ protected int engineGetBlockSize() {
+ return blockSize;
+ }
+
+ @Override
+ protected int engineGetOutputSize(int inputLen) {
+ return getOutputSizeByOperation(inputLen, true);
+ }
+
+ @Override
+ protected byte[] engineGetIV() {
+ return iv == null ? null : iv.clone();
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ if (iv == null) {
+ return null;
+ }
+ AlgorithmParameterSpec spec;
+ AlgorithmParameters params;
+ String algName = keyAlgo;
+ if (mode == Mode.GCM) {
+ algName = "GCM";
+ spec = new GCMParameterSpec(tagLengthInBytes * 8, iv.clone());
+ } else {
+ spec = new IvParameterSpec(iv.clone());
+ }
+ try {
+ params = AlgorithmParameters.getInstance(algName);
+ params.init(spec);
+ return params;
+ } catch (GeneralSecurityException e) {
+ throw new RuntimeException("Could not encode parameters", e);
+ }
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
+ try {
+ engineInit(opmode, key, (AlgorithmParameterSpec) null, random);
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidKeyException("init() failed", e);
+ }
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ AlgorithmParameterSpec spec = null;
+ String paramType = null;
+ if (params != null) {
+ try {
+ if (mode == Mode.GCM) {
+ spec = params.getParameterSpec(GCMParameterSpec.class);
+ paramType = "GCM";
+ } else {
+ spec = params.getParameterSpec(IvParameterSpec.class);
+ paramType = "IV";
+ }
+ } catch (InvalidParameterSpecException e) {
+ throw new InvalidAlgorithmParameterException("Could not decode " + paramType, e);
+ }
+ }
+ engineInit(opmode, key, spec, random);
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ checkKey(key);
+ boolean doEncrypt = (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE);
+
+ byte[] ivBytes = null;
+ int tagLen = -1;
+ if (params != null) {
+ if (mode == Mode.GCM) {
+ if (params instanceof GCMParameterSpec) {
+ tagLen = ((GCMParameterSpec)params).getTLen();
+ checkTagLen(tagLen);
+ tagLen = tagLen >> 3;
+ ivBytes = ((GCMParameterSpec)params).getIV();
+ } else {
+ throw new InvalidAlgorithmParameterException("Unsupported parameter: " + params);
+ }
+ } else {
+ if (params instanceof IvParameterSpec) {
+ ivBytes = ((IvParameterSpec) params).getIV();
+ checkIvBytes(ivBytes);
+ } else {
+ throw new InvalidKeyException("IvParameterSpec required. Received: " + params.getClass().getName());
+ }
+ }
+ }
+ if (mode == Mode.ECB) {
+ if (params != null) {
+ throw new InvalidAlgorithmParameterException("No Parameters for ECB mode");
+ }
+ } else if (ivBytes == null) {
+ if (doEncrypt) {
+ if (mode == Mode.GCM) {
+ ivBytes = new byte[defaultGcmIvLen];
+ } else {
+ ivBytes = new byte[blockSize];
+ }
+ if (random == null) {
+ random = JCAUtil.getSecureRandom();
+ }
+ random.nextBytes(ivBytes);
+ } else {
+ throw new InvalidAlgorithmParameterException("Parameters required for decryption");
+ }
+ } else if (keyAlgo.equalsIgnoreCase("SM4") && ivBytes.length < blockSize) {
+ byte[] temp = new byte[blockSize];
+ System.arraycopy(ivBytes, 0, temp, 0, ivBytes.length);
+ ivBytes = temp;
+ }
+ implInit(doEncrypt, key.getEncoded(), ivBytes, tagLen);
+ }
+
+ private void checkTagLen(int tagLen) throws InvalidAlgorithmParameterException {
+ if ((tagLen < 96) || (tagLen > 128) || ((tagLen & 0x07) != 0)) {
+ throw new InvalidAlgorithmParameterException
+ ("Unsupported TLen value; must be one of {128, 120, 112, 104, 96}");
+ }
+ }
+
+ protected abstract void checkIvBytes(byte[] ivBytes) throws InvalidAlgorithmParameterException;
+
+ protected abstract String getCipherName(int keyLength, Mode mode);
+
+ private void implInit(boolean encrypt, byte[] keyVal, byte[] ivVal, int tagLen)
+ throws InvalidAlgorithmParameterException {
+ reset(true);
+ this.encrypt = encrypt;
+ this.keyValue = keyVal;
+ this.iv = ivVal;
+ this.cipherName = getCipherName(keyValue.length * 8, mode);
+
+ if (mode == Mode.GCM) {
+ if (tagLen == -1) {
+ tagLen = defaultGcmTagLen;
+ }
+ this.tagLengthInBytes = tagLen;
+ if (encrypt) {
+ // Check key+iv for encryption in GCM mode.
+ boolean requireReinit = Arrays.equals(ivVal, lastEncIv) && MessageDigest.isEqual(keyVal, lastEncKey);
+ if (requireReinit) {
+ throw new InvalidAlgorithmParameterException("Cannot reuse iv for GCM encryption");
+ }
+ lastEncIv = ivVal;
+ lastEncKey = keyVal;
+ }
+ }
+
+ // OpenSSL only supports PKCS5 Padding.
+ long pCtxVal;
+ try {
+ pCtxVal = nativeInit(cipherName, encrypt, keyValue, iv, padding == Padding.PKCS5PADDING);
+ } catch (RuntimeException e) {
+ throw new ProviderException("Invoke nativeInit failed for " + cipherName, e);
+ }
+
+ initialized = (pCtxVal != 0L);
+ if (initialized) {
+ pCtx = new CipherContextRef(this, pCtxVal);
+ } else {
+ throw new NullPointerException("pCtxVal == 0");
+ }
+ calledUpdate = false;
+ }
+
+ protected abstract void checkKey(Key key) throws InvalidKeyException;
+
+ @Override
+ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+ byte[] out = new byte[getOutputSizeByOperation(inputLen, false)];
+ int outLen = implUpdate(input, inputOffset, inputLen, out, 0);
+ if (outLen == 0) {
+ return new byte[0];
+ } else if (out.length != outLen) {
+ out = Arrays.copyOf(out, outLen);
+ }
+ return out;
+ }
+
+ @Override
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException {
+ int min = getOutputSizeByOperation(inputLen, false);
+ if (output == null || output.length - outputOffset < min) {
+ throw new ShortBufferException("min " + min + "-byte buffer needed");
+ }
+ return implUpdate(input, inputOffset, inputLen, output, outputOffset);
+ }
+
+ private int implUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
+ ensureInitialized();
+ if (inputLen <= 0) {
+ return 0;
+ }
+ int outLen;
+ try {
+ outLen = nativeUpdate(pCtx.ctxAddress, input, inputOffset, inputLen, output, outputOffset,
+ mode == Mode.GCM, aad);
+ aad = null;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ reset(true);
+ throw new ProviderException("Invoke nativeUpdate failed for " + cipherName, e);
+ }
+ bytesBuffered += (inputLen - outLen);
+
+ calledUpdate = true;
+ return outLen;
+ }
+
+ protected int getOutputSizeByOperation(int inLen, boolean isDoFinal) {
+ int ret;
+
+ if (inLen <= 0) {
+ inLen = 0;
+ }
+ if (padding == Padding.NOPADDING) {
+ ret = inLen + bytesBuffered;
+ } else {
+ int len = inLen + bytesBuffered;
+
+ // The amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1) for encrypt.
+ // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EVP_CipherUpdate.html} for details.
+ len += (len % blockSize != 0 || encrypt) ? blockSize : 0;
+ ret = len - (len % blockSize);
+ }
+ if (mode == Mode.GCM && isDoFinal) {
+ if (encrypt) {
+ ret = ret + tagLengthInBytes;
+ } else {
+ ret = Math.max(0, ret - tagLengthInBytes);
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ protected byte[] engineDoFinal(byte[] input, int inputOffset,
+ int inputLen) throws IllegalBlockSizeException, BadPaddingException {
+ byte[] out = new byte[getOutputSizeByOperation(inputLen, true)];
+ try {
+ int outLen = engineDoFinal(input, inputOffset, inputLen, out, 0);
+ if (out.length != outLen) {
+ out = Arrays.copyOf(out, outLen);
+ }
+ return out;
+ } catch (ShortBufferException e) {
+ throw new ProviderException(e);
+ }
+ }
+
+ @Override
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+ int outLen = 0;
+ int min = getOutputSizeByOperation(inputLen, true);
+ if (output == null || output.length - outputOffset < min) {
+ throw new ShortBufferException("min " + min + "-byte buffer needed");
+ }
+
+ int updateLen = inputLen;
+ if (mode == Mode.GCM && !encrypt) {
+ // Remove tagLengthInBytes suffix in GCM decrypt.
+ updateLen = inputLen - tagLengthInBytes;
+ }
+ outLen = implUpdate(input, inputOffset, updateLen, output, outputOffset);
+ outputOffset += outLen;
+
+ byte[] gcmTag = null;
+ if (mode == Mode.GCM && !encrypt) {
+ if (inputLen - outLen != tagLengthInBytes) {
+ throw new AEADBadTagException("Tag mismatch!");
+ }
+ // The last tagLengthInBytees in the input arg gcmTag.
+ gcmTag = Arrays.copyOfRange(input, inputOffset + inputLen - tagLengthInBytes, inputOffset + inputLen);
+ }
+
+ outLen += implDoFinal(output, outputOffset, gcmTag);
+ return outLen;
+ }
+
+ @Override
+ protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
+ byte[] res = null;
+ try {
+ byte[] encodedKey = key.getEncoded();
+ if (encodedKey == null || encodedKey.length == 0) {
+ throw new InvalidKeyException("Cannot get an encoding of the key to be wrapped");
+ }
+ res = engineDoFinal(encodedKey, 0, encodedKey.length);
+ } catch (BadPaddingException e) {
+ // Should never happen
+ }
+ return res;
+ }
+
+ @Override
+ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
+ byte[] encodedKey;
+ try {
+ encodedKey = engineDoFinal(wrappedKey, 0, wrappedKey.length);
+ } catch (IllegalBlockSizeException | BadPaddingException e) {
+ throw (InvalidKeyException) (new InvalidKeyException()).initCause(e);
+ }
+ return constructKey(wrappedKeyType, encodedKey, wrappedKeyAlgorithm);
+ }
+
+ @Override
+ protected void engineUpdateAAD(ByteBuffer byteBuffer) {
+ if (aad == null) {
+ aad = new byte[byteBuffer.remaining()];
+ byteBuffer.get(aad);
+ } else {
+ int newSize = aad.length + byteBuffer.remaining();
+ byte[] newaad = new byte[newSize];
+ System.arraycopy(aad, 0, newaad, 0, aad.length);
+ byteBuffer.get(newaad, aad.length, byteBuffer.remaining());
+ aad = newaad;
+ }
+ }
+
+ @Override
+ protected void engineUpdateAAD(byte[] input, int inputOffset, int inputLen) {
+ if (aad == null) {
+ aad = Arrays.copyOfRange(input, inputOffset, inputOffset + inputLen);
+ } else {
+ int newSize = aad.length + inputLen;
+ byte[] newaad = new byte[newSize];
+ System.arraycopy(aad, 0, newaad, 0, aad.length);
+ System.arraycopy(input, inputOffset, newaad, aad.length, inputLen);
+ aad = newaad;
+ }
+ }
+
+ private int implDoFinal(byte[] out, int outputOffset, byte[] gcmTag)
+ throws BadPaddingException, IllegalBlockSizeException {
+ if (!encrypt && !calledUpdate) {
+ return 0;
+ }
+ ensureInitialized();
+
+ int outLen;
+ try {
+ if (mode == Mode.GCM) {
+ outLen = nativeFinalGcm(pCtx.ctxAddress, out, outputOffset, mode == Mode.GCM, tagLengthInBytes,
+ gcmTag, encrypt);
+ } else {
+ outLen = nativeFinal(pCtx.ctxAddress, out, outputOffset);
+ }
+ } catch (ArrayIndexOutOfBoundsException | BadPaddingException e) {
+ if (e instanceof AEADBadTagException) {
+ throw e; // AEADBadTagException is expected for some tests
+ } else if (e instanceof BadPaddingException) {
+ if (padding == Padding.NOPADDING || e.getMessage().contains("wrong final block length")) {
+ throw new IllegalBlockSizeException("Input length not multiple of " + blockSize + " bytes");
+ } else {
+ throw e;
+ }
+ } else {
+ throw new ProviderException("Invoke nativeFinal failed for " + cipherName, e);
+ }
+ } finally {
+ reset(true);
+ }
+
+ return outLen;
+ }
+
+ protected void reset(boolean doCancel) {
+ initialized = false;
+ bytesBuffered = 0;
+ calledUpdate = false;
+
+ // for gcm
+ aad = null;
+
+ if (pCtx != null) {
+ pCtx.dispose(doCancel);
+ pCtx = null;
+ }
+ }
+
+ protected static native long nativeInit(String cipherType, boolean encrypt, byte[] key, byte[] iv, boolean padding)
+ throws RuntimeException;
+
+ protected static native int nativeUpdate(long pContext, byte[] in, int inOfs, int inLen, byte[] out,
+ int outOfs, boolean gcm, byte[] aad) throws ArrayIndexOutOfBoundsException;
+
+ protected static native int nativeFinal(long pContext, byte[] out,
+ int outOfs) throws ArrayIndexOutOfBoundsException, BadPaddingException;
+
+ protected static native void nativeFree(long pContext);
+
+ protected static native int nativeFinalGcm(long pContext, byte[] out, int outOfs, boolean gcm,
+ int tagLength, byte[] gcmTag, boolean encrypt) throws ArrayIndexOutOfBoundsException, BadPaddingException;
+
+ protected void ensureInitialized() {
+ if (!initialized) {
+ reset(true);
+ long pCtxVal = nativeInit(cipherName, encrypt, keyValue, iv, padding == Padding.PKCS5PADDING);
+ initialized = (pCtxVal != 0L);
+ if (initialized) {
+ pCtx = new CipherContextRef(this, pCtxVal);
+ } else {
+ throw new RuntimeException("Cannot initialize Cipher");
+ }
+ }
+ }
+}
+
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java
index f563fd07..21a6116e 100644
--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java
@@ -91,8 +91,12 @@ class KAEUtils {
private static final Map<String, String> DIGEST_ALGORITHM_NAME_MAP = new HashMap<>();
private static final Map<String, Integer> DIGEST_ALGORITHM_LENGTH_MAP = new HashMap<>();
+ private static final Map<Integer, String> SIZE_TO_CURVE = new HashMap<>();
+ private static final Map<String, String> CURVE_ALIAS = new HashMap<>();
+
static {
initDigest();
+ initECDH();
}
private static void initDigest() {
@@ -109,11 +113,11 @@ class KAEUtils {
// get the kae digest algorithm name
static String getKAEDigestName(String digestName) {
- return DIGEST_ALGORITHM_NAME_MAP.get(digestName);
+ return digestName == null ? null : DIGEST_ALGORITHM_NAME_MAP.get(digestName.toUpperCase(Locale.ROOT));
}
- static int getDigestLength(String digestName) {
- return DIGEST_ALGORITHM_LENGTH_MAP.get(digestName);
+ static Integer getDigestLength(String digestName) {
+ return digestName == null ? null :DIGEST_ALGORITHM_LENGTH_MAP.get(digestName.toUpperCase(Locale.ROOT));
}
static class ConstructKeys {
@@ -193,4 +197,24 @@ class KAEUtils {
}
}
}
+
+ private static void initECDH() {
+ SIZE_TO_CURVE.put(224, "secp224r1");
+ SIZE_TO_CURVE.put(256, "prime256v1");
+ SIZE_TO_CURVE.put(384, "secp384r1");
+ SIZE_TO_CURVE.put(521, "secp521r1");
+ CURVE_ALIAS.put("secp256r1", "prime256v1");
+ CURVE_ALIAS.put("1.3.132.0.33", "secp224r1");
+ CURVE_ALIAS.put("1.3.132.0.34", "secp384r1");
+ CURVE_ALIAS.put("1.3.132.0.35", "secp521r1");
+ CURVE_ALIAS.put("1.2.840.10045.3.1.7", "prime256v1");
+ }
+
+ static String getCurveBySize(int size) {
+ return SIZE_TO_CURVE.get(size);
+ }
+
+ static String getCurveByAlias(String alias) {
+ return CURVE_ALIAS.get(alias);
+ }
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_aes.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_aes.c
deleted file mode 100644
index 8a9526a2..00000000
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_aes.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <string.h>
-#include "kae_log.h"
-#include "kae_exception.h"
-#include "org_openeuler_security_openssl_KAEAESCipher.h"
-
-static const EVP_CIPHER* EVPGetCipherByName(JNIEnv* env, const char* algo)
-{
- static const EVP_CIPHER* aes128Ecb = NULL;
- static const EVP_CIPHER* aes128Cbc = NULL;
- static const EVP_CIPHER* aes128Ctr = NULL;
- static const EVP_CIPHER* aes192Ecb = NULL;
- static const EVP_CIPHER* aes192Cbc = NULL;
- static const EVP_CIPHER* aes192Ctr = NULL;
- static const EVP_CIPHER* aes256Ecb = NULL;
- static const EVP_CIPHER* aes256Cbc = NULL;
- static const EVP_CIPHER* aes256Ctr = NULL;
-
- if (strcasecmp(algo, "aes-128-ecb") == 0) {
- return aes128Ecb == NULL ? aes128Ecb = EVP_get_cipherbyname(algo) : aes128Ecb;
- } else if (strcasecmp(algo, "aes-128-cbc") == 0) {
- return aes128Cbc == NULL ? aes128Cbc = EVP_get_cipherbyname(algo) : aes128Cbc;
- } else if (strcasecmp(algo, "aes-128-ctr") == 0) {
- return aes128Ctr == NULL ? aes128Ctr = EVP_get_cipherbyname(algo) : aes128Ctr;
- } else if (strcasecmp(algo, "aes-192-ecb") == 0) {
- return aes192Ecb == NULL ? aes192Ecb = EVP_get_cipherbyname(algo) : aes192Ecb;
- } else if (strcasecmp(algo, "aes-192-cbc") == 0) {
- return aes192Cbc == NULL ? aes192Cbc = EVP_get_cipherbyname(algo) : aes192Cbc;
- } else if (strcasecmp(algo, "aes-192-ctr") == 0) {
- return aes192Ctr == NULL ? aes192Ctr = EVP_get_cipherbyname(algo) : aes192Ctr;
- } else if (strcasecmp(algo, "aes-256-ecb") == 0) {
- return aes256Ecb == NULL ? aes256Ecb = EVP_get_cipherbyname(algo) : aes256Ecb;
- } else if (strcasecmp(algo, "aes-256-cbc") == 0) {
- return aes256Cbc == NULL ? aes256Cbc = EVP_get_cipherbyname(algo) : aes256Cbc;
- } else if (strcasecmp(algo, "aes-256-ctr") == 0) {
- return aes256Ctr == NULL ? aes256Ctr = EVP_get_cipherbyname(algo) : aes256Ctr;
- } else {
- KAE_ThrowRuntimeException(env, "EVPGetCipherByName error");
- return 0;
- }
-}
-
-/*
- * Class: org_openeuler_security_openssl_KAEAESCipher
- * Method: nativeInit
- * Signature: (Ljava/lang/String;Z[B[B)J
- */
-JNIEXPORT jlong JNICALL
-Java_org_openeuler_security_openssl_KAEAESCipher_nativeInit(JNIEnv* env, jclass cls,
- jstring cipherType, jboolean encrypt, jbyteArray key, jbyteArray iv, jboolean padding)
-{
- EVP_CIPHER_CTX* ctx = NULL;
- jbyte* keyBytes = NULL;
- jbyte* ivBytes = NULL;
- const EVP_CIPHER* cipher = NULL;
-
- const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0);
- cipher = EVPGetCipherByName(env, algo);
- (*env)->ReleaseStringUTFChars(env, cipherType, algo);
- if (cipher == NULL) {
- KAE_ThrowOOMException(env, "create EVP_CIPHER fail");
- goto err;
- }
-
- ctx = EVP_CIPHER_CTX_new();
- if (ctx == NULL) {
- KAE_ThrowOOMException(env, "create EVP_CIPHER_CTX fail");
- goto err;
- }
-
- if (iv != NULL) {
- ivBytes = (*env)->GetByteArrayElements(env, iv, NULL);
- }
- const unsigned char* i = (const unsigned char*) ivBytes;
-
- if (key != NULL) {
- keyBytes = (*env)->GetByteArrayElements(env, key, NULL);
- }
- const unsigned char* k = (const unsigned char*) keyBytes;
-
- if (!EVP_CipherInit_ex(ctx, cipher, NULL, k, i, encrypt ? 1 : 0)) {
- KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException);
- goto err;
- }
- KAE_TRACE("KAEAESCipher_nativeInit EVP_CipherInit_ex(ctx = %p, cipher = %p, key = %p, iv = %p, encrypt = %d) "
- "success", ctx, cipher, key, iv, encrypt ? 1 : 0);
-
- EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
-
- if (iv != NULL) {
- (*env)->ReleaseByteArrayElements(env, iv, ivBytes, 0);
- }
- (*env)->ReleaseByteArrayElements(env, key, keyBytes, 0);
- return (jlong) ctx;
-err:
- if (ctx != NULL) {
- EVP_CIPHER_CTX_free(ctx);
- }
- if (ivBytes != NULL) {
- (*env)->ReleaseByteArrayElements(env, iv, ivBytes, 0);
- }
- if (keyBytes != NULL) {
- (*env)->ReleaseByteArrayElements(env, key, keyBytes, 0);
- }
- return 0;
-}
-
-/*
- * Class: org_openeuler_security_openssl_KAEAESCipher
- * Method: nativeUpdate
- * Signature: (JZ[BII[BI)I
- */
-JNIEXPORT jint JNICALL
-Java_org_openeuler_security_openssl_KAEAESCipher_nativeUpdate(JNIEnv* env, jclass cls,
- jlong ctxAddress, jbyteArray inArr, jint inOfs, jint inLen, jbyteArray outArr, jint outOfs)
-{
- jbyte* in = NULL;
- unsigned char* out = NULL;
-
- EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*) ctxAddress;
- if (ctx == NULL) {
- goto err;
- }
-
- if (inArr == NULL || outArr == NULL) {
- goto err;
- }
- int inputLen = (*env)->GetArrayLength(env, inArr);
- if ((inOfs < 0) || (inOfs > inputLen) || (inLen < 0) || (inLen > inputLen - inOfs)) {
- KAE_ThrowArrayIndexOutOfBoundsException(env, "inArr");
- goto err;
- }
- in = malloc(sizeof(jbyte) * inputLen);
- if (in == NULL) {
- KAE_ThrowOOMException(env, "malloc error");
- goto err;
- }
- (*env)->GetByteArrayRegion(env, inArr, 0, inputLen, in);
-
- int outputLen = (*env)->GetArrayLength(env, outArr);
- if ((outOfs < 0) || (outOfs > outputLen) || (inLen < 0) || (inLen > outputLen - outOfs)) {
- KAE_ThrowArrayIndexOutOfBoundsException(env, "outArr");
- goto err;
- }
- out = malloc(outputLen - outOfs);
- if (out == NULL) {
- KAE_ThrowOOMException(env, "malloc error");
- goto err;
- }
-
- unsigned int bytesWritten = 0;
- if (EVP_CipherUpdate(ctx, out, &bytesWritten, in + inOfs, inLen) == 0) {
- KAE_ThrowFromOpenssl(env, "EVP_CipherUpdate failed", KAE_ThrowRuntimeException);
- goto err;
- }
- KAE_TRACE("KAEAESCipher_nativeUpdate EVP_CipherUpdate success, bytesWritten = %d", bytesWritten);
- (*env)->SetByteArrayRegion(env, outArr, outOfs, bytesWritten, (jbyte*) out);
-
- free(in);
- free(out);
- return bytesWritten;
-err:
- if (in != NULL) {
- free(in);
- }
- if (out != NULL) {
- free(out);
- }
- return 0;
-}
-
-/*
- * Class: org_openeuler_security_openssl_KAEAESCipher
- * Method: nativeFinal
- * Signature: (JZ[BI)I
- */
-JNIEXPORT jint JNICALL
-Java_org_openeuler_security_openssl_KAEAESCipher_nativeFinal(JNIEnv* env, jclass cls,
- jlong ctxAddress, jbyteArray outArr, jint outOfs)
-{
- unsigned char* out;
- EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*) ctxAddress;
- KAE_TRACE("KAEAESCipher_nativeFinal(ctxAddress = %p, outArr = %p, outOfs = %d)",
- ctx, outArr, outOfs);
- if (ctx == NULL) {
- goto err;
- }
- if (outArr == NULL) {
- goto err;
- }
- int outputLen = (*env)->GetArrayLength(env, outArr);
- out = malloc(outputLen - outOfs);
- if (out == NULL) {
- KAE_ThrowOOMException(env, "malloc error");
- goto err;
- }
- unsigned int bytesWritten = 0;
- int result_code = EVP_CipherFinal_ex(ctx, out, &bytesWritten);
- if (result_code == 0) {
- KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowBadPaddingException);
- goto err;
- }
- KAE_TRACE("KAEAESCipher_nativeFinal EVP_CipherFinal_ex success, bytesWritten = %d", bytesWritten);
- (*env)->SetByteArrayRegion(env, outArr, outOfs, bytesWritten, (jbyte*) out);
- free(out);
- KAE_TRACE("KAEAESCipher_nativeFinal: finished");
- return bytesWritten;
-
-err:
- if (out != NULL) {
- free(out);
- }
- return 0;
-}
-
-/*
- * Class: org_openeuler_security_openssl_KAEAESCipher
- * Method: nativeFree
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL
-Java_org_openeuler_security_openssl_KAEAESCipher_nativeFree(JNIEnv* env, jclass cls, jlong ctxAddress)
-{
- EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*) ctxAddress;
- KAE_TRACE("KAEAESCipher_nativeFree(ctx = %p)", ctx);
- if (ctx != NULL) {
- EVP_CIPHER_CTX_free(ctx);
- }
-
- KAE_TRACE("KAEAESCipher_nativeFree: finished");
-}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c
index d689d4b1..3fbacf77 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c
@@ -21,15 +21,13 @@
* questions.
*/
+#include <stdbool.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include "kae_util.h"
#include "kae_exception.h"
#include "org_openeuler_security_openssl_KAERSACipher.h"
-#define SUCCESS 1
-#define FAILED -1
-
typedef int RSACryptOperation(int, const unsigned char*, unsigned char*, RSA*, int);
typedef int EvpPkeyCryptOperation(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t);
@@ -88,55 +86,55 @@ cleanup:
/*
* set rsa padding
*/
-static int SetRSAPadding(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, int paddingType) {
+static bool SetRSAPadding(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, int paddingType) {
if (EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_padding", KAE_ThrowInvalidAlgorithmParameterException);
- return FAILED;
+ return false;
}
- return SUCCESS;
+ return true;
}
/*
* set rsa mgf1 md
*/
-static int SetRSAMgf1Md(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* mgf1MdAlgoUTF) {
+static bool SetRSAMgf1Md(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* mgf1MdAlgoUTF) {
EVP_MD* mgf1MD = (EVP_MD*)EVP_get_digestbyname(mgf1MdAlgoUTF);
if (mgf1MD == NULL) {
KAE_ThrowFromOpenssl(env, "EVP_get_digestbyname", KAE_ThrowInvalidAlgorithmParameterException);
- return FAILED;
+ return false;
}
if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1MD) <= 0) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_mgf1_md", KAE_ThrowInvalidAlgorithmParameterException);
- return FAILED;
+ return false;
}
- return SUCCESS;
+ return true;
}
/*
* set rsa oaep md
*/
-static int SetRSAOaepMd(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* oaepMdAlgoUTF) {
+static bool SetRSAOaepMd(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* oaepMdAlgoUTF) {
EVP_MD* oaepMD = (EVP_MD*)EVP_get_digestbyname(oaepMdAlgoUTF);
if (oaepMD == NULL) {
KAE_ThrowFromOpenssl(env, "EVP_get_digestbyname", KAE_ThrowInvalidAlgorithmParameterException);
- return FAILED;
+ return false;
}
if (EVP_PKEY_CTX_set_rsa_oaep_md(pkeyCtx, oaepMD) <= 0) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_oaep_md", KAE_ThrowInvalidAlgorithmParameterException);
- return FAILED;
+ return false;
}
- return SUCCESS;
+ return true;
}
/*
* set rsa oaep label
*/
-static int SetRSAOaepLabel(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jbyte* labelBytes, jsize labelSize) {
+static bool SetRSAOaepLabel(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jbyte* labelBytes, jsize labelSize) {
if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkeyCtx, labelBytes, labelSize) <= 0) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set0_rsa_oaep_label", KAE_ThrowInvalidAlgorithmParameterException);
- return FAILED;
+ return false;
}
- return SUCCESS;
+ return true;
}
/*
@@ -194,9 +192,9 @@ static int RSACryptOAEPPadding(JNIEnv* env, jlong keyAddress, jint inLen, jbyteA
* set rsa mgf1 md
* set rsa oaep md
*/
- if(SetRSAPadding(env, pkeyCtx, paddingType) == FAILED ||
- SetRSAMgf1Md(env, pkeyCtx, mgf1MdAlgoUTF) == FAILED ||
- SetRSAOaepMd(env, pkeyCtx, oaepMdAlgoUTF) == FAILED) {
+ if(!SetRSAPadding(env, pkeyCtx, paddingType) ||
+ !SetRSAMgf1Md(env, pkeyCtx, mgf1MdAlgoUTF) ||
+ !SetRSAOaepMd(env, pkeyCtx, oaepMdAlgoUTF)) {
goto cleanup;
}
@@ -210,7 +208,7 @@ static int RSACryptOAEPPadding(JNIEnv* env, jlong keyAddress, jint inLen, jbyteA
goto cleanup;
}
(*env)->GetByteArrayRegion(env, label, 0, labelSize, labelBytes);
- if(SetRSAOaepLabel(env, pkeyCtx, labelBytes, labelSize) == FAILED) {
+ if(!SetRSAOaepLabel(env, pkeyCtx, labelBytes, labelSize)) {
free(labelBytes);
goto cleanup;
}
@@ -279,21 +277,21 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC
(bnDMP1 = KAE_GetBigNumFromByteArray(env, dmp1)) == NULL ||
(bnDMQ1 = KAE_GetBigNumFromByteArray(env, dmq1)) == NULL ||
(bnIQMP = KAE_GetBigNumFromByteArray(env, iqmp)) == NULL) {
- goto err;
+ goto cleanup;
}
// new pkey
pkey = EVP_PKEY_new();
if (pkey == NULL) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
// new rsa
rsa = RSA_new();
if (rsa == NULL) {
KAE_ThrowFromOpenssl(env, "RSA_new", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
// set rsa private crt key params n,e,d,p,q,dmp1,dmp1,iqmp
@@ -301,17 +299,17 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC
RSA_set0_factors(rsa, bnP, bnQ) <= 0 ||
RSA_set0_crt_params(rsa, bnDMP1, bnDMQ1, bnIQMP) <= 0) {
KAE_ThrowFromOpenssl(env, "RSA set param", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
// assign rsa to pkey
int result = EVP_PKEY_assign_RSA(pkey, rsa);
if (result <= 0) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_RSA", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
return (jlong)pkey;
-err:
+cleanup:
ReleaseRSAParams(bnN, bnE, bnD, bnP, bnQ, bnDMP1, bnDMQ1, bnIQMP);
RSA_free(rsa);
EVP_PKEY_free(pkey);
@@ -334,43 +332,43 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC
// get public key param n
bnN = KAE_GetBigNumFromByteArray(env, n);
if (bnN == NULL) {
- goto err;
+ goto cleanup;
}
// get public key param e
bnE = KAE_GetBigNumFromByteArray(env, e);
if (bnE == NULL) {
- goto err;
+ goto cleanup;
}
// new RSA
rsa = RSA_new();
if (rsa == NULL) {
KAE_ThrowFromOpenssl(env, "RSA_new", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
// new EVP_PKEY
pkey = EVP_PKEY_new();
if (pkey == NULL) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
// set rsa public key params n and e
if(RSA_set0_key(rsa, bnN, bnE, NULL) <= 0) {
KAE_ThrowFromOpenssl(env, "RSA_set0_key", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
// assign rsa to pkey
int result = EVP_PKEY_assign_RSA(pkey, rsa);
if (result <= 0) {
KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_RSA", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
return (jlong)pkey;
-err:
+cleanup:
KAE_ReleaseBigNumFromByteArray(bnN);
KAE_ReleaseBigNumFromByteArray(bnE);
RSA_free(rsa);
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c
index 6ae14969..f0e7b0be 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c
@@ -21,10 +21,12 @@
* questions.
*/
+#include <string.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
-#include "kae_log.h"
#include "kae_exception.h"
+#include "kae_log.h"
+#include "kae_util.h"
#include "org_openeuler_security_openssl_KAEDigest.h"
#define DIGEST_STACK_SIZE 1024
@@ -40,6 +42,7 @@ JNIEXPORT jlong JNICALL
Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls, jstring algorithmName)
{
EVP_MD_CTX* ctx = NULL;
+ static ENGINE* kaeEngine = NULL;
if (algorithmName == NULL) {
KAE_ThrowNullPointerException(env, "algorithm is null");
@@ -48,6 +51,11 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls
// EVP_get_digestbyname
const char* algo_utf = (*env)->GetStringUTFChars(env, algorithmName, 0);
+ if ((strcasecmp(algo_utf, "md5") == 0) || (strcasecmp(algo_utf, "sm3") == 0)) {
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+ } else {
+ kaeEngine = NULL;
+ }
EVP_MD* md = (EVP_MD*) EVP_get_digestbyname(algo_utf);
(*env)->ReleaseStringUTFChars(env, algorithmName, algo_utf);
if (md == NULL) {
@@ -64,17 +72,17 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls
KAE_TRACE("KAEDigest_nativeInit: create ctx => %p", ctx);
// EVP_DigestInit_ex
- int result_code = EVP_DigestInit_ex(ctx, md, NULL);
+ int result_code = EVP_DigestInit_ex(ctx, md, kaeEngine);
if (result_code == 0) {
KAE_ThrowFromOpenssl(env, "EVP_DigestInit_ex failed", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
KAE_TRACE("KAEDigest_nativeInit EVP_DigestInit_ex(ctx = %p, md = %p) success", ctx, md);
KAE_TRACE("KAEDigest_nativeInit: finished");
return (jlong) ctx;
-err:
+cleanup:
EVP_MD_CTX_destroy(ctx);
return 0;
}
@@ -198,13 +206,13 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeClone(JNIEnv *env, jclass cl
int result_code = EVP_MD_CTX_copy_ex(ctxCopy, ctx);
if (result_code == 0) {
KAE_ThrowFromOpenssl(env, "EVP_MD_CTX_copy_ex failed", KAE_ThrowRuntimeException);
- goto err;
+ goto cleanup;
}
KAE_TRACE("KAEDigest_nativeClone EVP_MD_CTX_copy_ex(ctxCopy = %p, ctx = %p) success", ctxCopy, ctx);
KAE_TRACE("KAEDigest_nativeClone: finished");
return (jlong) ctxCopy;
-err:
+cleanup:
EVP_MD_CTX_destroy(ctxCopy);
return 0;
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c
index b1a29334..a10fa646 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c
@@ -56,6 +56,8 @@ void KAE_ThrowEvpException(JNIEnv* env, int reason, const char* msg, void (* def
KAE_ThrowByName(env, "java/security/InvalidKeyException", msg);
break;
case EVP_R_BAD_DECRYPT:
+ case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
+ case EVP_F_EVP_PKEY_DECRYPT:
KAE_ThrowByName(env, "javax/crypto/BadPaddingException", msg);
break;
default:
@@ -90,7 +91,7 @@ void KAE_ThrowFromOpenssl(JNIEnv* env, const char* msg, void (* defaultException
err = ERR_get_error_line_data(&file, &line, &data, &flags);
if (err == 0) {
- KAE_ThrowRuntimeException(env, "Unknown OpenSSL error");
+ defaultException(env, msg);
return;
}
@@ -104,6 +105,7 @@ void KAE_ThrowFromOpenssl(JNIEnv* env, const char* msg, void (* defaultException
switch (lib) {
case ERR_LIB_EVP:
+ case ERR_LIB_RSA:
KAE_ThrowEvpException(env, reason, estring, defaultException);
break;
default:
@@ -114,3 +116,15 @@ void KAE_ThrowFromOpenssl(JNIEnv* env, const char* msg, void (* defaultException
ERR_clear_error();
}
+
+void KAE_ThrowAEADBadTagException(JNIEnv *env, const char *msg) {
+ KAE_ThrowByName(env, "javax/crypto/AEADBadTagException", msg);
+}
+
+void KAE_ThrowSignatureException(JNIEnv* env, const char* msg) {
+ KAE_ThrowByName(env, "java/security/SignatureException", msg);
+}
+
+void KAE_ThrowClassNotFoundException(JNIEnv* env, const char* msg) {
+ KAE_ThrowByName(env, "java/lang/ClassNotFoundException", msg);
+}
\ No newline at end of file
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h
index f528ad4a..53295399 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h
@@ -49,4 +49,9 @@ void KAE_ThrowInvalidKeyException(JNIEnv* env, const char* msg);
/* Throw AlgorithmParameterException */
void KAE_ThrowInvalidAlgorithmParameterException(JNIEnv* env, const char* msg);
+void KAE_ThrowAEADBadTagException(JNIEnv* env, const char* msg);
+
+void KAE_ThrowSignatureException(JNIEnv* env, const char* msg);
+
+void KAE_ThrowClassNotFoundException(JNIEnv* env, const char* msg);
#endif
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_mac.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c
similarity index 87%
rename from jdk/src/solaris/native/org/openeuler/security/openssl/kae_mac.c
rename to jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c
index 2df2a9cb..7b28fa1f 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_mac.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c
@@ -22,9 +22,11 @@
*/
#include <jni.h>
+#include <string.h>
#include <openssl/hmac.h>
#include "kae_exception.h"
#include "kae_log.h"
+#include "kae_util.h"
static const EVP_MD* EVPGetDigestByName(JNIEnv* env, const char* algo)
{
@@ -54,11 +56,11 @@ static const EVP_MD* EVPGetDigestByName(JNIEnv* env, const char* algo)
}
/*
- * Class: org_openeuler_security_openssl_KAEMac
+ * Class: org_openeuler_security_openssl_KAEHMac
* Method: nativeInit
* Signature: ([BILjava/lang/String;)J
*/
-JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeInit
+JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeInit
(JNIEnv* env, jclass cls, jbyteArray key, jint key_len, jstring algoStr) {
if (key == NULL || algoStr == NULL) {
KAE_ThrowNullPointerException(env, "param key or algoStr is null");
@@ -92,32 +94,32 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeInit
ctx = HMAC_CTX_new();
if (ctx == NULL) {
KAE_ThrowRuntimeException(env, "Hmac_CTX_new invoked failed");
- goto err;
+ goto cleanup;
}
// init hmac context with sc_key and evp_md
int result_code = HMAC_Init_ex(ctx, key_buffer, key_len, md, NULL);
if (result_code == 0) {
KAE_ThrowRuntimeException(env, "Hmac_Init_ex invoked failed");
- goto err;
+ goto cleanup;
}
free(key_buffer);
return (jlong) ctx;
-err:
+cleanup:
free(key_buffer);
HMAC_CTX_free(ctx);
return 0;
}
/*
- * Class: org_openeuler_security_openssl_KAEMac
+ * Class: org_openeuler_security_openssl_KAEHMac
* Method: nativeUpdate
* Signature: (J[BII)V
*/
-JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeUpdate
+JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeUpdate
(JNIEnv* env, jclass cls, jlong hmac_ctx, jbyteArray input, jint in_offset, jint in_len) {
- KAE_TRACE("KAEMac_nativeUpdate(ctx = %p, input = %p, offset = %d, inLen = %d", hmac_ctx, input, in_offset, in_len);
+ KAE_TRACE("KAEHMac_nativeUpdate(ctx = %p, input = %p, offset = %d, inLen = %d", hmac_ctx, input, in_offset, in_len);
HMAC_CTX* ctx = (HMAC_CTX*) hmac_ctx;
if (ctx == NULL || input == NULL) {
KAE_ThrowNullPointerException(env, "param ctx or input is null");
@@ -146,11 +148,11 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeUpdate
}
/*
- * Class: org_openeuler_security_openssl_KAEMac
+ * Class: org_openeuler_security_openssl_KAEHMac
* Method: nativeFinal
* Signature: (J[BII)I
*/
-JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeFinal
+JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeFinal
(JNIEnv* env, jclass cls, jlong hmac_ctx, jbyteArray output, jint out_offset, jint in_len) {
HMAC_CTX* ctx = (HMAC_CTX*) hmac_ctx;
if (ctx == NULL || output == NULL) {
@@ -180,7 +182,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeFinal
// write back to output_array
(*env)->SetByteArrayRegion(env, output, out_offset, bytesWritten, (jbyte*) temp_result);
- KAE_TRACE("KAEMac_nativeFinal success, output_offset = %d, bytesWritten = %d", out_offset, bytesWritten);
+ KAE_TRACE("KAEHMac_nativeFinal success, output_offset = %d, bytesWritten = %d", out_offset, bytesWritten);
cleanup:
free(temp_result);
@@ -188,11 +190,11 @@ cleanup:
}
/*
- * Class: org_openeuler_security_openssl_KAEMac
+ * Class: org_openeuler_security_openssl_KAEHMac
* Method: nativeFree
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEMac_nativeFree
+JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeFree
(JNIEnv* env, jclass cls, jlong hmac_ctx) {
HMAC_CTX* ctx = (HMAC_CTX*) hmac_ctx;
if (ctx != NULL) {
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c
new file mode 100644
index 00000000..5894a4b4
--- /dev/null
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <memory.h>
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/engine.h>
+#include <openssl/dh.h>
+#include <stdio.h>
+#include "kae_util.h"
+#include "kae_exception.h"
+#include "kae_log.h"
+#include "org_openeuler_security_openssl_KAEDHKeyAgreement.h"
+
+
+/*
+ * Class: org_openeuler_security_openssl_KAEDHKeyAgreement
+ * Method: nativeComputeKey
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyAgreement_nativeComputeKey(JNIEnv* env,
+ jobject obj, jbyteArray y, jbyteArray x, jbyteArray p, jbyteArray g, jint pSize) {
+
+ KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyAgreement_nativeComputeKey start.");
+
+ DH* dh = NULL;
+ BIGNUM* y_bn = NULL;
+ BIGNUM* x_bn = NULL;
+ BIGNUM* p_bn = NULL;
+ BIGNUM* g_bn = NULL;
+ BIGNUM* computeKeyRetBn = NULL;
+ int computekeyLength = 0;
+ unsigned char* secret = NULL;
+ jbyteArray retByteArray = NULL;
+ static ENGINE* kaeEngine = NULL;
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+
+ // bits to Bytes
+ int pSizeInByte = (pSize +7) >> 3;
+
+ if ((secret = (unsigned char*)malloc(pSizeInByte)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc secret failed.");
+ goto cleanup;
+ }
+ memset(secret, 0, pSizeInByte);
+
+ if ((dh = DH_new_method(kaeEngine)) == NULL) {
+ KAE_ThrowOOMException(env, "Allocate DH failed in nativeComputeKey.");
+ goto cleanup;
+ }
+
+ if ((y_bn = KAE_GetBigNumFromByteArray(env, y)) == NULL) {
+ KAE_ThrowOOMException(env, "Convert y to BIGNUM failed.");
+ goto cleanup;
+ }
+
+ if ((x_bn = KAE_GetBigNumFromByteArray(env, x)) == NULL) {
+ KAE_ThrowOOMException(env, "Convert x to BIGNUM failed.");
+ goto cleanup;
+ }
+
+ if ((p_bn = KAE_GetBigNumFromByteArray(env, p)) == NULL) {
+ KAE_ThrowOOMException(env, "Convert p to BIGNUM failed.");
+ goto cleanup;
+ }
+
+ if ((g_bn = KAE_GetBigNumFromByteArray(env, g)) == NULL) {
+ KAE_ThrowOOMException(env, "Convert g to BIGNUM failed.");
+ goto cleanup;
+ }
+
+ if ((computeKeyRetBn = BN_new()) == NULL) {
+ KAE_ThrowOOMException(env, "Allocate BN failed.");
+ goto cleanup;
+ }
+
+ if (!DH_set0_pqg(dh, BN_dup(p_bn), NULL, BN_dup(g_bn))) {
+ KAE_ThrowRuntimeException(env, "DH_set0_pqg failed.");
+ goto cleanup;
+ }
+
+ if (!DH_set0_key(dh, NULL, BN_dup(x_bn))) {
+ KAE_ThrowRuntimeException(env, "DH_set0_key failed.");
+ goto cleanup;
+ }
+
+ computekeyLength = DH_compute_key(secret, y_bn, dh);
+
+ if (computekeyLength <= 0 ) {
+ KAE_ThrowRuntimeException(env, "DH_compute_key failed.");
+ goto cleanup;
+ }
+
+ BN_bin2bn(secret, computekeyLength, computeKeyRetBn);
+
+ retByteArray = KAE_GetByteArrayFromBigNum(env, computeKeyRetBn, NULL);
+ if (retByteArray == NULL) {
+ KAE_ThrowRuntimeException(env, "GetByteArrayFromBigNum failed in nativeComputeKey.");
+ goto cleanup;
+ }
+ KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyAgreement_nativeGenerateSecret finished!");
+
+cleanup:
+ if (dh != NULL)
+ DH_free(dh);
+ if (y_bn != NULL)
+ KAE_ReleaseBigNumFromByteArray(y_bn);
+ if (x_bn != NULL)
+ KAE_ReleaseBigNumFromByteArray(x_bn);
+ if (p_bn != NULL)
+ KAE_ReleaseBigNumFromByteArray(p_bn);
+ if (g_bn != NULL)
+ KAE_ReleaseBigNumFromByteArray(g_bn);
+ if (secret != NULL)
+ free(secret);
+
+ return retByteArray;
+}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
new file mode 100644
index 00000000..5fc4d68f
--- /dev/null
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <memory.h>
+#include <openssl/objects.h>
+#include <openssl/ec.h>
+#include "kae_log.h"
+#include "kae_exception.h"
+#include "kae_util.h"
+#include "org_openeuler_security_openssl_KAEECDHKeyAgreement.h"
+
+static void FreeGenerateSecretParam(BIGNUM* s, BIGNUM* wX, BIGNUM* wY,
+ EC_POINT* pub, EC_KEY* eckey, EC_GROUP* group, unsigned char* shareKey)
+{
+ KAE_ReleaseBigNumFromByteArray(s);
+ KAE_ReleaseBigNumFromByteArray(wX);
+ KAE_ReleaseBigNumFromByteArray(wY);
+ if (pub != NULL) {
+ EC_POINT_free(pub);
+ }
+ if (eckey != NULL) {
+ EC_KEY_free(eckey);
+ }
+ if (group != NULL) {
+ EC_GROUP_free(group);
+ }
+ if (shareKey != NULL) {
+ free(shareKey);
+ }
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAEECDHKeyAgreement
+ * Method: nativeGenerateSecret
+ * Signature: (Ljava/lang/String;[B[B[B)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEECDHKeyAgreement_nativeGenerateSecret
+ (JNIEnv* env, jclass cls, jstring curveName, jbyteArray wXArr, jbyteArray wYArr, jbyteArray sArr)
+{
+ EC_GROUP* group = NULL;
+ EC_KEY* eckey = NULL;
+ BIGNUM* wX = NULL;
+ BIGNUM* wY = NULL;
+ BIGNUM* s = NULL;
+ EC_POINT* pub = NULL;
+ jbyteArray javaBytes = NULL;
+ unsigned char* shareKey = NULL;
+ const char *curve = (*env)->GetStringUTFChars(env, curveName, 0);
+ int nid = OBJ_sn2nid(curve);
+ (*env)->ReleaseStringUTFChars(env, curveName, curve);
+ if ((nid == NID_undef) || (group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
+ goto cleanup;
+ }
+ if ((s = KAE_GetBigNumFromByteArray(env, sArr)) == NULL || (wX = KAE_GetBigNumFromByteArray(env, wXArr)) == NULL
+ || (wY = KAE_GetBigNumFromByteArray(env, wYArr)) == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate BN_new");
+ goto cleanup;
+ }
+ if ((eckey = EC_KEY_new()) == NULL || !EC_KEY_set_group(eckey, group)) {
+ goto cleanup;
+ }
+ if ((pub = EC_POINT_new(group)) == NULL) {
+ goto cleanup;
+ }
+ if (!EC_POINT_set_affine_coordinates_GFp(group, pub, wX, wY, NULL)) {
+ goto cleanup;
+ }
+ if (!EC_KEY_set_public_key(eckey, pub) || !EC_KEY_set_private_key(eckey, s)) {
+ goto cleanup;
+ }
+
+ // Get the length of secret key, in bytes.
+ int expectSecretLen = (EC_GROUP_get_degree(group) + 7) / 8;
+ if ((shareKey = malloc(expectSecretLen)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc error");
+ goto cleanup;
+ }
+ memset(shareKey, 0, expectSecretLen);
+
+ // Perform ecdh keyagreement.
+ if (ECDH_compute_key(shareKey, expectSecretLen, pub, eckey, NULL) != expectSecretLen) {
+ goto cleanup;
+ }
+
+ if ((javaBytes = (*env)->NewByteArray(env, expectSecretLen)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetByteArrayRegion(env, javaBytes, 0, expectSecretLen, (jbyte*)shareKey);
+ FreeGenerateSecretParam(s, wX, wY, pub, eckey, group, shareKey);
+ return javaBytes;
+
+cleanup:
+ FreeGenerateSecretParam(s, wX, wY, pub, eckey, group, shareKey);
+ return NULL;
+}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c
new file mode 100644
index 00000000..808a2626
--- /dev/null
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/engine.h>
+#include <openssl/dh.h>
+#include <stdio.h>
+#include "kae_util.h"
+#include "kae_log.h"
+#include "org_openeuler_security_openssl_KAEDHKeyPairGenerator.h"
+#include "kae_exception.h"
+
+
+/*
+* Class: org_openeuler_security_openssl_KAEDHKeyPairGenerator
+* Method: nativeGenerateKeyPair
+* Signature: ([B[BI)[[B
+*/
+
+JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyPairGenerator_nativeGenerateKeyPair
+ (JNIEnv* env, jclass cls, jbyteArray p, jbyteArray g, jint lSize)
+{
+ DH* dh = NULL;
+ BIGNUM* p_bn = NULL;
+ BIGNUM* g_bn = NULL;
+ const BIGNUM* pri_key_bn = NULL;
+ const BIGNUM* pub_key_bn = NULL;
+ jclass byteArrayClass = NULL;
+ jobjectArray keys = NULL;
+ jbyteArray pri_key = NULL;
+ jbyteArray pub_key = NULL;
+ static ENGINE* kaeEngine = NULL;
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+
+ KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyPairGenerator_nativeGenerateKeyPair start !");
+
+ if ((dh = DH_new_method(kaeEngine)) == NULL) {
+ KAE_ThrowOOMException(env, "Allocate DH failed in nativeGenerateKeyPair!");
+ goto cleanup;
+ }
+
+ if ((p_bn = KAE_GetBigNumFromByteArray(env, p)) == NULL) {
+ KAE_ThrowOOMException(env, "Allocate p_bn failed in nativeGenerateKeyPair!");
+ goto cleanup;
+ }
+
+ if ((g_bn = KAE_GetBigNumFromByteArray(env, g)) == NULL) {
+ KAE_ThrowOOMException(env, "Allocate g_bn failed in nativeGenerateKeyPair!");
+ goto cleanup;
+ }
+
+ if (!DH_set0_pqg(dh, BN_dup(p_bn), NULL, BN_dup(g_bn))) {
+ KAE_ThrowRuntimeException(env, "DH_set0_pqg failed in nativeGenerateKeyPair.");
+ goto cleanup;
+ }
+
+ // Return value is fixed to 1, nothing to check.
+ DH_set_length(dh, lSize);
+
+ if (!DH_generate_key(dh)) {
+ KAE_ThrowInvalidAlgorithmParameterException(env, "DH generate key failed in nativeGenerateKeyPair.");
+ goto cleanup;
+ }
+
+ if ((byteArrayClass = (*env)->FindClass(env, "[B")) == NULL) {
+ KAE_ThrowClassNotFoundException(env, "Class byte[] not found.");
+ goto cleanup;
+ }
+
+ if ((keys = (*env)->NewObjectArray(env, 2, byteArrayClass, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "Allocate ByteArray failed in nativeGenerateKeyPair!");
+ goto cleanup;
+ }
+
+ // Return the ptr of private key in dh.
+ pri_key_bn = DH_get0_priv_key(dh);
+ pub_key_bn = DH_get0_pub_key(dh);
+
+ pub_key = KAE_GetByteArrayFromBigNum(env, pub_key_bn, NULL);
+ if (pub_key == NULL) {
+ KAE_ThrowOOMException(env, "PublicKey allocate failed in nativeGenerateKeyPair.");
+ goto cleanup;
+ }
+
+ pri_key = KAE_GetByteArrayFromBigNum(env, pri_key_bn, NULL);
+ if (pri_key == NULL) {
+ KAE_ThrowRuntimeException(env, "GetByteArrayFromBigNum failed in nativeGenerateKeyPair.");
+ goto cleanup;
+ }
+
+ (*env)->SetObjectArrayElement(env, keys, 0, pub_key);
+ (*env)->SetObjectArrayElement(env, keys, 1, pri_key);
+
+ KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyPairGenerator_nativeGenerateKeyPair finished !");
+
+cleanup:
+ if (dh != NULL)
+ DH_free(dh);
+ if (p_bn != NULL)
+ KAE_ReleaseBigNumFromByteArray(p_bn);
+ if (g_bn != NULL)
+ KAE_ReleaseBigNumFromByteArray(g_bn);
+ if (byteArrayClass != NULL)
+ (*env)->DeleteLocalRef(env, byteArrayClass);
+ if (pub_key != NULL)
+ (*env)->DeleteLocalRef(env, pub_key);
+ if (pri_key != NULL)
+ (*env)->DeleteLocalRef(env, pri_key);
+
+ return keys;
+}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c
new file mode 100644
index 00000000..93b710bf
--- /dev/null
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdbool.h>
+#include <openssl/objects.h>
+#include <openssl/ec.h>
+#include "kae_util.h"
+#include "kae_exception.h"
+#include "kae_log.h"
+#include "org_openeuler_security_openssl_KAEECKeyPairGenerator.h"
+
+#define KAE_EC_PARAM_NUM_SIZE 7
+#define KAE_EC_KEY_NUM_SIZE 3
+
+// ECDH param index.
+typedef enum ECDHParamIndex {
+ ecdhP = 0,
+ ecdhA,
+ ecdhB,
+ ecdhX,
+ ecdhY,
+ ecdhOrder,
+ ecdhCofactor
+} ECDHParamIndex;
+
+static const char* ecdhParamNames[] = {"p", "a", "b", "x", "y", "order", "cofactor"};
+
+static void FreeECDHCurveParam(JNIEnv* env, BIGNUM* p, BIGNUM* a, BIGNUM* b, jbyteArray paramP,
+ jbyteArray paramA, jbyteArray paramB)
+{
+ if (p != NULL) {
+ BN_free(p);
+ }
+ if (a != NULL) {
+ BN_free(a);
+ }
+ if (b != NULL) {
+ BN_free(b);
+ }
+ if (paramP != NULL) {
+ (*env)->DeleteLocalRef(env, paramP);
+ }
+ if (paramA != NULL) {
+ (*env)->DeleteLocalRef(env, paramA);
+ }
+ if (paramB != NULL) {
+ (*env)->DeleteLocalRef(env, paramB);
+ }
+}
+
+// Set p, a, b in group to params.
+static bool SetECDHCurve(JNIEnv* env, EC_GROUP* group, jobjectArray params, ECDHParamIndex ecdhParamIndex)
+{
+ BIGNUM* p = NULL;
+ BIGNUM* a = NULL;
+ BIGNUM* b = NULL;
+ jbyteArray paramP = NULL;
+ jbyteArray paramA = NULL;
+ jbyteArray paramB = NULL;
+ if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || (b = BN_new()) == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate BN_new");
+ goto cleanup;
+ }
+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, NULL)) {
+ goto cleanup;
+ }
+
+ // Set p.
+ const char* ecdhParamName = ecdhParamNames[ecdhParamIndex];
+ if ((paramP = KAE_GetByteArrayFromBigNum(env, p, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramP);
+
+ // Set a.
+ ecdhParamName = ecdhParamNames[++ecdhParamIndex];
+ if ((paramA = KAE_GetByteArrayFromBigNum(env, a, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramA);
+
+ // Set b.
+ ecdhParamName = ecdhParamNames[++ecdhParamIndex];
+ if ((paramB = KAE_GetByteArrayFromBigNum(env, b, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramB);
+ FreeECDHCurveParam(env, p, a, b, paramP, paramA, paramB);
+ return true;
+
+cleanup:
+ FreeECDHCurveParam(env, p, a, b, paramP, paramA, paramB);
+ return false;
+}
+
+// Set generator(x, y) in group to params.
+static bool SetECDHPoint(JNIEnv* env, EC_GROUP* group, jobjectArray params, ECDHParamIndex ecdhParamIndex)
+{
+ BIGNUM* x = NULL;
+ BIGNUM* y = NULL;
+ const EC_POINT* generator = NULL;
+ jbyteArray paramX = NULL;
+ jbyteArray paramY = NULL;
+ if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate BN_new");
+ goto cleanup;
+ }
+ if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate ec generator");
+ goto cleanup;
+ }
+ if (!EC_POINT_get_affine_coordinates_GFp(group, generator, x, y, NULL)) {
+ KAE_ThrowFromOpenssl(env, "EC_POINT_set_affine_coordinates_GFp", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+
+ // Set x.
+ const char* ecdhParamName = ecdhParamNames[ecdhParamIndex];
+ if ((paramX = KAE_GetByteArrayFromBigNum(env, x, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramX);
+
+ // Set y.
+ ecdhParamName = ecdhParamNames[++ecdhParamIndex];
+ if ((paramY = KAE_GetByteArrayFromBigNum(env, y, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramY);
+ BN_free(x);
+ BN_free(y);
+ (*env)->DeleteLocalRef(env, paramX);
+ (*env)->DeleteLocalRef(env, paramY);
+ return true;
+
+cleanup:
+ if (x != NULL) {
+ BN_free(x);
+ }
+ if (y != NULL) {
+ BN_free(y);
+ }
+ if (paramX != NULL) {
+ (*env)->DeleteLocalRef(env, paramX);
+ }
+ if (paramY != NULL) {
+ (*env)->DeleteLocalRef(env, paramY);
+ }
+ return false;
+}
+
+// Set order, cofactor in group to params.
+static bool SetECDHOrderAndCofactor(JNIEnv* env, EC_GROUP* group, jobjectArray params, ECDHParamIndex ecdhParamIndex)
+{
+ BIGNUM* order = NULL;
+ BIGNUM* cofactor = NULL;
+ jbyteArray paramOrder = NULL;
+ jbyteArray paramCofactor = NULL;
+ if ((order = BN_new()) == NULL || (cofactor = BN_new()) == NULL) {
+ goto cleanup;
+ }
+ if (!EC_GROUP_get_order(group, order, NULL)) {
+ goto cleanup;
+ }
+
+ // Set order.
+ const char* ecdhParamName = ecdhParamNames[ecdhParamIndex];
+ if ((paramOrder = KAE_GetByteArrayFromBigNum(env, order, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramOrder);
+ if (!EC_GROUP_get_cofactor(group, cofactor, NULL)) {
+ goto cleanup;
+ }
+
+ // Set cofactor.
+ ecdhParamName = ecdhParamNames[++ecdhParamIndex];
+ if ((paramCofactor = KAE_GetByteArrayFromBigNum(env, cofactor, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhParamIndex, paramCofactor);
+ BN_free(order);
+ BN_free(cofactor);
+ (*env)->DeleteLocalRef(env, paramOrder);
+ (*env)->DeleteLocalRef(env, paramCofactor);
+ return true;
+
+cleanup:
+ if (order != NULL) {
+ BN_free(order);
+ }
+ if (cofactor != NULL) {
+ BN_free(cofactor);
+ }
+ if (paramOrder != NULL) {
+ (*env)->DeleteLocalRef(env, paramOrder);
+ }
+ if (paramCofactor != NULL) {
+ (*env)->DeleteLocalRef(env, paramCofactor);
+ }
+ return false;
+}
+
+static void FreeECDHKeyParam(JNIEnv* env,
+ BIGNUM* wX, BIGNUM* wY, jbyteArray paramWX, jbyteArray paramWY, jbyteArray paramS)
+{
+ if (wX != NULL) {
+ BN_free(wX);
+ }
+ if (wY != NULL) {
+ BN_free(wY);
+ }
+ if (paramWX != NULL) {
+ (*env)->DeleteLocalRef(env, paramWX);
+ }
+ if (paramWY != NULL) {
+ (*env)->DeleteLocalRef(env, paramWY);
+ }
+ if (paramS != NULL) {
+ (*env)->DeleteLocalRef(env, paramS);
+ }
+}
+
+// Set publicKey(wX, wY) and privateKey(s) in eckey to params.
+static bool SetECDHKey(JNIEnv* env, const EC_GROUP* group, jobjectArray params,
+ ECDHParamIndex ecdhKeyIndex, const EC_KEY* eckey)
+{
+ BIGNUM* wX = NULL;
+ BIGNUM* wY = NULL;
+ const EC_POINT* pub = NULL;
+ const BIGNUM* s = NULL;
+ jbyteArray paramWX = NULL;
+ jbyteArray paramWY = NULL;
+ jbyteArray paramS = NULL;
+ if ((wX = BN_new()) == NULL || (wY = BN_new()) == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate array");
+ goto cleanup;
+ }
+
+ if ((pub = EC_KEY_get0_public_key(eckey)) == NULL ||
+ !EC_POINT_get_affine_coordinates_GFp(group, pub, wX, wY, NULL)) {
+ goto cleanup;
+ }
+ if ((s = EC_KEY_get0_private_key(eckey)) == NULL) {
+ goto cleanup;
+ }
+
+ // Set wX.
+ const char* ecdhParamName = ecdhParamNames[ecdhKeyIndex];
+ if ((paramWX = KAE_GetByteArrayFromBigNum(env, wX, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhKeyIndex, paramWX);
+
+ // Set wY.
+ ecdhParamName = ecdhParamNames[++ecdhKeyIndex];
+ if ((paramWY = KAE_GetByteArrayFromBigNum(env, wY, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhKeyIndex, paramWY);
+
+ // Set s.
+ ecdhParamName = ecdhParamNames[++ecdhKeyIndex];
+ if ((paramS = KAE_GetByteArrayFromBigNum(env, s, ecdhParamName)) == NULL) {
+ goto cleanup;
+ }
+ (*env)->SetObjectArrayElement(env, params, ecdhKeyIndex, paramS);
+ FreeECDHKeyParam(env, wX, wY, paramWX, paramWY, paramS);
+ return true;
+
+cleanup:
+ FreeECDHKeyParam(env, wX, wY, paramWX, paramWY, paramS);
+ return false;
+}
+
+// Convert EC_GROUP in openssl to byte[][] in java
+static jobjectArray NewECDHParam(JNIEnv* env, EC_GROUP* group)
+{
+ jclass byteArrayClass = NULL;
+ jobjectArray params = NULL;
+
+ byteArrayClass = (*env)->FindClass(env, "[B");
+ params = (*env)->NewObjectArray(env, KAE_EC_PARAM_NUM_SIZE, byteArrayClass, NULL);
+ if (params == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate array");
+ goto cleanup;
+ }
+
+ if (!SetECDHCurve(env, group, params, ecdhP)) {
+ goto cleanup;
+ }
+ if (!SetECDHPoint(env, group, params, ecdhX)) {
+ goto cleanup;
+ }
+ if (!SetECDHOrderAndCofactor(env, group, params, ecdhOrder)) {
+ goto cleanup;
+ }
+
+ (*env)->DeleteLocalRef(env, byteArrayClass);
+ return params;
+
+cleanup:
+ if (byteArrayClass != NULL) {
+ (*env)->DeleteLocalRef(env, byteArrayClass);
+ }
+ if (params != NULL) {
+ (*env)->DeleteLocalRef(env, params);
+ }
+ return NULL;
+}
+
+// Convert EC_KEY in openssl to byte[][] in java
+static jobjectArray NewECDHKey(JNIEnv* env, const EC_GROUP* group, const EC_KEY* eckey)
+{
+ jclass byteArrayClass = NULL;
+ jobjectArray params = NULL;
+
+ byteArrayClass = (*env)->FindClass(env, "[B");
+ params = (*env)->NewObjectArray(env, KAE_EC_KEY_NUM_SIZE, byteArrayClass, NULL);
+ if (params == NULL) {
+ KAE_ThrowOOMException(env, "failed to allocate array");
+ goto cleanup;
+ }
+ if (!SetECDHKey(env, group, params, 0, eckey)) {
+ goto cleanup;
+ }
+
+ (*env)->DeleteLocalRef(env, byteArrayClass);
+ return params;
+
+cleanup:
+ if (byteArrayClass != NULL) {
+ (*env)->DeleteLocalRef(env, byteArrayClass);
+ }
+ if (params != NULL) {
+ (*env)->DeleteLocalRef(env, params);
+ }
+ return NULL;
+}
+
+static void FreeECDHParam(BIGNUM* p, BIGNUM* a, BIGNUM* b, BIGNUM* x, BIGNUM* y, BIGNUM* order, BIGNUM* cofactor)
+{
+ KAE_ReleaseBigNumFromByteArray(p);
+ KAE_ReleaseBigNumFromByteArray(a);
+ KAE_ReleaseBigNumFromByteArray(b);
+ KAE_ReleaseBigNumFromByteArray(x);
+ KAE_ReleaseBigNumFromByteArray(y);
+ KAE_ReleaseBigNumFromByteArray(order);
+ KAE_ReleaseBigNumFromByteArray(cofactor);
+}
+
+// Convert params in java to EC_GROUP in openssl
+static EC_GROUP* GetGroupByParam(JNIEnv* env, jbyteArray pArr, jbyteArray aArr, jbyteArray bArr,
+ jbyteArray xArr, jbyteArray yArr, jbyteArray orderArr, jint cofactorInt)
+{
+ BIGNUM* p = NULL;
+ BIGNUM* a = NULL;
+ BIGNUM* b = NULL;
+ BIGNUM* x = NULL;
+ BIGNUM* y = NULL;
+ BIGNUM* order = NULL;
+ BIGNUM* cofactor = NULL;
+ EC_GROUP* group = NULL;
+ BN_CTX* ctx = NULL;
+ EC_POINT* generator = NULL;
+ p = KAE_GetBigNumFromByteArray(env, pArr);
+ if ((p = KAE_GetBigNumFromByteArray(env, pArr)) == NULL || (a = KAE_GetBigNumFromByteArray(env, aArr)) == NULL ||
+ (b = KAE_GetBigNumFromByteArray(env, bArr)) == NULL || (x = KAE_GetBigNumFromByteArray(env, xArr)) == NULL ||
+ (y = KAE_GetBigNumFromByteArray(env, yArr)) == NULL || (cofactor = BN_new()) == NULL ||
+ (order = KAE_GetBigNumFromByteArray(env, orderArr)) == NULL || !BN_set_word(cofactor, cofactorInt)) {
+ goto cleanup;
+ }
+
+ // Create the curve.
+ if ((ctx = BN_CTX_new()) == NULL || (group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
+ goto cleanup;
+ }
+
+ // Create the generator and set x, y.
+ if ((generator = EC_POINT_new(group)) == NULL ||
+ !EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) {
+ goto cleanup;
+ }
+
+ // Set the generator, order and cofactor.
+ if (!EC_GROUP_set_generator(group, generator, order, cofactor)) {
+ goto cleanup;
+ }
+
+ FreeECDHParam(p, a, b, x, y, order, cofactor);
+ EC_POINT_free(generator);
+ BN_CTX_free(ctx);
+ return group;
+
+cleanup:
+ FreeECDHParam(p, a, b, x, y, order, cofactor);
+ if (group != NULL) {
+ EC_GROUP_free(group);
+ }
+ if (generator != NULL) {
+ EC_POINT_free(generator);
+ }
+ if (ctx != NULL) {
+ BN_CTX_free(ctx);
+ }
+ return NULL;
+}
+
+
+/*
+ * Class: org_openeuler_security_openssl_KAEECKeyPairGenerator
+ * Method: nativeGenerateParam
+ * Signature: (Ljava/lang/String;)[[B
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEECKeyPairGenerator_nativeGenerateParam(
+ JNIEnv* env, jclass cls, jstring curveName)
+{
+ EC_GROUP* group = NULL;
+
+ const char *curve = (*env)->GetStringUTFChars(env, curveName, 0);
+ KAE_TRACE("KAEECKeyPairGenerator_nativeGenerateParam(curveName = %s)", curve);
+ int nid = OBJ_sn2nid(curve);
+ (*env)->ReleaseStringUTFChars(env, curveName, curve);
+ if (nid == NID_undef) {
+ goto cleanup;
+ }
+ // Construct a builtin curve.
+ if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
+ goto cleanup;
+ }
+ jobjectArray ecdhParam = NewECDHParam(env, group);
+
+ if (group != NULL) {
+ EC_GROUP_free(group);
+ }
+ KAE_TRACE("KAEECKeyPairGenerator_nativeGenerateParam success, ecdhParam = %p", ecdhParam);
+ return ecdhParam;
+
+cleanup:
+ if (group != NULL) {
+ EC_GROUP_free(group);
+ }
+ if (ecdhParam != NULL) {
+ (*env)->DeleteLocalRef(env, ecdhParam);
+ }
+ return NULL;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAEECKeyPairGenerator
+ * Method: nativeGenerateKeyPair
+ * Signature: ([B[B[B[B[B[BI)[[B
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEECKeyPairGenerator_nativeGenerateKeyPair(
+ JNIEnv* env, jclass cls, jbyteArray pArr, jbyteArray aArr, jbyteArray bArr,
+ jbyteArray xArr, jbyteArray yArr, jbyteArray orderArr, jint cofactorInt)
+{
+ EC_GROUP* group = NULL;
+ EC_KEY* eckey = NULL;
+
+ if ((group = GetGroupByParam(env, pArr, aArr, bArr, xArr, yArr, orderArr, cofactorInt)) == NULL) {
+ goto cleanup;
+ }
+ if ((eckey = EC_KEY_new()) == NULL) {
+ goto cleanup;
+ }
+ if (!EC_KEY_set_group(eckey, group)) {
+ goto cleanup;
+ }
+ // Generates a new public and private key for the supplied eckey object.
+ // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EC_KEY_generate_key.html} for details.
+ if (!EC_KEY_generate_key(eckey)) {
+ goto cleanup;
+ }
+
+ jobjectArray ecdhKey = NewECDHKey(env, group, eckey);
+
+ EC_KEY_free(eckey);
+ EC_GROUP_free(group);
+
+ KAE_TRACE("KAEECKeyPairGenerator_nativeGenerateKeyPair success, ecdhKey = %p", ecdhKey);
+ return ecdhKey;
+
+cleanup:
+ if (eckey != NULL) {
+ EC_KEY_free(eckey);
+ }
+ if (group != NULL) {
+ EC_GROUP_free(group);
+ }
+ if (ecdhKey != NULL) {
+ (*env)->DeleteLocalRef(env, ecdhKey);
+ }
+ return NULL;
+}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c
index 01848c0e..ddbc2958 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c
@@ -20,6 +20,8 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+#include <stdbool.h>
#include <openssl/rsa.h>
#include "kae_util.h"
#include "kae_exception.h"
@@ -31,18 +33,18 @@
// rsa param index
typedef enum RSAParamIndex {
- rsa_n = 0,
- rsa_e = 1,
- rsa_d = 2,
- rsa_p = 3,
- rsa_q = 4,
- rsa_dmp1 = 5,
- rsa_dmq1 = 6,
- rsa_iqmp = 7
+ rsaN = 0,
+ rsaE,
+ rsaD,
+ rsaP,
+ rsaQ,
+ rsaDmp1,
+ rsaDmq1,
+ rsaIqmp
} RSAParamIndex;
// rsa param name array
-static const char* RSAParamNames[] = {"n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp"};
+static const char* rsaParamNames[] = {"n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp"};
// rsa get rsa param function list
static const BIGNUM* (* GetRSAParamFunctionList[])(const RSA*) = {
@@ -103,25 +105,25 @@ static void ReleaseRSA(RSA* rsa) {
* step 3. Convert paramValue (BIGNUM) to jbyteArray
* step 4. Set the rsa param to the param array
*/
-static int SetRSAKeyParam(JNIEnv* env, RSA* rsa, jobjectArray params, RSAParamIndex rsaParamIndex) {
+static bool SetRSAKeyParam(JNIEnv* env, RSA* rsa, jobjectArray params, RSAParamIndex rsaParamIndex) {
// get rsa param name
- const char* rsaParamName = RSAParamNames[rsaParamIndex];
+ const char* rsaParamName = rsaParamNames[rsaParamIndex];
// get rsa param value
const BIGNUM* rsaParamValue = GetRSAParamFunctionList[rsaParamIndex](rsa);
if (rsaParamValue == NULL) {
- return FAILED;
+ return false;
}
// Convert paramValue to jbyteArray
jbyteArray param = KAE_GetByteArrayFromBigNum(env, rsaParamValue, rsaParamName);
if (param == NULL) {
- return FAILED;
+ return false;
}
// Set the rsa param to the param array
(*env)->SetObjectArrayElement(env, params, rsaParamIndex, param);
- return SUCCESS;
+ return true;
}
/*
@@ -139,8 +141,8 @@ static jobjectArray NewRSAKeyParams(JNIEnv* env, RSA* rsa) {
}
// set rsa key param
- for (RSAParamIndex paramIndex = rsa_n; paramIndex <= rsa_iqmp; paramIndex++) {
- if (SetRSAKeyParam(env, rsa, params, paramIndex) == FAILED) {
+ for (RSAParamIndex paramIndex = rsaN; paramIndex <= rsaIqmp; paramIndex++) {
+ if (!SetRSAKeyParam(env, rsa, params, paramIndex)) {
return NULL;
}
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c
index cfd2480e..aa46e737 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c
@@ -25,9 +25,11 @@
#include <openssl/ssl.h>
#include <openssl/engine.h>
#include "kae_exception.h"
+#include "kae_util.h"
#include "org_openeuler_security_openssl_KAEProvider.h"
+
/*
- * Class: org_openeuler_security_openssl_WdProvider
+ * Class: Java_org_openeuler_security_openssl_KAEProvider
* Method: initOpenssl
* Signature: ()V
*/
@@ -37,11 +39,19 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEProvider_initOpens
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
+ // check if KaeEngine holder is already set
+ ENGINE* e = GetKaeEngine();
+ if (e != NULL) {
+ ENGINE_free(e);
+ e = NULL;
+ }
+
// determine whether KAE is loaded successfully
- ENGINE *e = ENGINE_by_id("kae");
+ e = ENGINE_by_id("kae");
if (e == NULL) {
+ ERR_clear_error();
KAE_ThrowRuntimeException(env, "kae engine not found");
return;
}
- ENGINE_free(e);
+ SetKaeEngine(e);
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c
new file mode 100644
index 00000000..e81dc140
--- /dev/null
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include <stdbool.h>
+#include <string.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include "kae_util.h"
+#include "kae_exception.h"
+
+// get EVP_MD by digestName
+static const EVP_MD* getEvpMd(JNIEnv* env, jstring digestName) {
+ const char* digestNameUtf = (*env)->GetStringUTFChars(env, digestName, 0);
+ const EVP_MD* md = (EVP_MD*)EVP_get_digestbyname(digestNameUtf);
+ (*env)->ReleaseStringUTFChars(env, digestName, digestNameUtf);
+ if (md == NULL) {
+ KAE_ThrowSignatureException(env, "Unsupported digest algorithm.");
+ }
+ return md;
+}
+
+// sign release
+static void signRelease(JNIEnv* env, jbyteArray digestValue, jbyte* digestBytes, jbyte* sigBytes,
+ EVP_PKEY_CTX* pkeyCtx) {
+ if (digestBytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, digestValue, digestBytes, 0);
+ }
+ if (sigBytes != NULL) {
+ free(sigBytes);
+ }
+ if (pkeyCtx != NULL) {
+ EVP_PKEY_CTX_free(pkeyCtx);
+ }
+}
+
+// verify release
+static void verifyRelease(JNIEnv* env, jbyteArray digestValue, jbyte* digestBytes, jbyteArray sigValue, jbyte* sigBytes,
+ EVP_PKEY_CTX* pkeyCtx) {
+ if (digestBytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, digestValue, digestBytes, 0);
+ }
+ if (sigBytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, sigValue, sigBytes, 0);
+ }
+ if (pkeyCtx != NULL) {
+ EVP_PKEY_CTX_free(pkeyCtx);
+ }
+}
+
+// set rsa PkeyCtx parameters
+static bool setRsaPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint paddingType, jstring digestName) {
+ // set rsa padding
+ if (EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_padding", KAE_ThrowSignatureException);
+ return false;
+ }
+
+ // set signature md
+ const EVP_MD* md = getEvpMd(env, digestName);
+ if (md == NULL) {
+ return false;
+ }
+
+ if (EVP_PKEY_CTX_set_signature_md(pkeyCtx, md) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_signature_md", KAE_ThrowSignatureException);
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAERSASignatureNative
+ * Method: rsaSign
+ * Signature: (JLjava/lang/String;[BI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNative_rsaSign(JNIEnv* env, jclass cls,
+ jlong keyAddress, jstring digestName, jbyteArray digestValue, jint paddingType) {
+ EVP_PKEY* pkey = (EVP_PKEY*)keyAddress;
+ EVP_PKEY_CTX* pkeyCtx = NULL;
+ jbyte* digestBytes = NULL;
+ jbyte* sigBytes = NULL;
+ jbyteArray sigByteArray = NULL;
+ static ENGINE* kaeEngine = NULL;
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+ // new EVP_PKEY_CTX
+ if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // sign init
+ if (EVP_PKEY_sign_init(pkeyCtx) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // set rsa PkeyCtx parameters
+ if (!setRsaPkeyCtxParameters(env, pkeyCtx, paddingType, digestName)) {
+ goto cleanup;
+ }
+
+ // sign
+ size_t sigLen = (size_t)EVP_PKEY_size(pkey);
+ if (sigLen <= 0) {
+ KAE_ThrowSignatureException(env, "The sigLen size cannot be zero or negative");
+ goto cleanup;
+ }
+ if ((sigBytes = malloc(sigLen)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc failed");
+ goto cleanup;
+ }
+ if ((digestBytes = (*env)->GetByteArrayElements(env, digestValue, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "GetByteArrayElements failed");
+ goto cleanup;
+ }
+ size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue);
+ if (EVP_PKEY_sign(pkeyCtx, (unsigned char*)sigBytes, &sigLen,
+ (const unsigned char*)digestBytes, digestLen) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // set signature byte to jbyteArray
+ if ((sigByteArray = (*env)->NewByteArray(env, (jsize)sigLen)) == NULL) {
+ KAE_ThrowOOMException(env, "NewByteArray failed");
+ goto cleanup;
+ }
+ (*env)->SetByteArrayRegion(env, sigByteArray, 0, (jsize)sigLen, sigBytes);
+
+cleanup:
+ signRelease(env, digestValue, digestBytes, sigBytes, pkeyCtx);
+ return sigByteArray;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAERSASignatureNative
+ * Method: rsaVerify
+ * Signature: (JLjava/lang/String;[BI[B)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNative_rsaVerify(JNIEnv* env, jclass cls,
+ jlong keyAddress, jstring digestName, jbyteArray digestValue, jint paddingType, jbyteArray sigValue) {
+ EVP_PKEY* pkey = (EVP_PKEY*)keyAddress;
+ EVP_PKEY_CTX* pkeyCtx = NULL;
+ jbyte* digestBytes = NULL;
+ jbyte* sigBytes = NULL;
+ jboolean isSuccess = JNI_FALSE;
+ static ENGINE* kaeEngine = NULL;
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+ // new EVP_PKEY_CTX
+ if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // verify init
+ if (EVP_PKEY_verify_init(pkeyCtx) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // set rsa PkeyCtx parameters
+ if (!setRsaPkeyCtxParameters(env, pkeyCtx, paddingType, digestName)) {
+ goto cleanup;
+ }
+
+ // verify
+ if ((digestBytes = (*env)->GetByteArrayElements(env, digestValue, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "GetByteArrayElements failed");
+ goto cleanup;
+ }
+ if ((sigBytes = (*env)->GetByteArrayElements(env, sigValue, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "GetByteArrayElements failed");
+ goto cleanup;
+ }
+ size_t sigLen = (size_t)(*env)->GetArrayLength(env, sigValue);
+ size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue);
+ if (EVP_PKEY_verify(pkeyCtx, (const unsigned char*)sigBytes, sigLen,
+ (const unsigned char*)digestBytes, digestLen) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_verify", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+ isSuccess = JNI_TRUE;
+
+cleanup:
+ verifyRelease(env, digestValue, digestBytes, sigValue, sigBytes, pkeyCtx);
+ return isSuccess;
+}
+
+// set pss pkeyCtx parameters
+static bool setPssPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint paddingType, jstring digestName,
+ jstring mgf1DigestName, jint saltLen) {
+ // set rsa padding
+ if (EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_padding", KAE_ThrowSignatureException);
+ return false;
+ }
+
+ // set signature md
+ const EVP_MD* md = getEvpMd(env, digestName);
+ if (md == NULL) {
+ return false;
+ }
+ if (EVP_PKEY_CTX_set_signature_md(pkeyCtx, md) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_signature_md", KAE_ThrowSignatureException);
+ return false;
+ }
+
+ // set rsa mgf1 md
+ const EVP_MD* mgf1Md = getEvpMd(env, mgf1DigestName);
+ if (mgf1Md == NULL) {
+ return false;
+ }
+ if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1Md) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_mgf1_md", KAE_ThrowSignatureException);
+ return false;
+ }
+
+ // set salt len
+ if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, saltLen) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_pss_saltlen", KAE_ThrowSignatureException);
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAERSASignatureNative
+ * Method: pssSign
+ * Signature: (JLjava/lang/String;[BILjava/lang/String;I)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNative_pssSign(JNIEnv* env, jclass cls,
+ jlong keyAddress, jstring digestName, jbyteArray digestValue, jint paddingType, jstring mgf1DigestName,
+ jint saltLen) {
+ EVP_PKEY* pkey = (EVP_PKEY*)keyAddress;
+ EVP_PKEY_CTX* pkeyCtx = NULL;
+ jbyte* digestBytes = NULL;
+ jbyte* sigBytes = NULL;
+ jbyteArray sigByteArray = NULL;
+ static ENGINE* kaeEngine = NULL;
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+ // new EVP_PKEY_CTX
+ if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // sign init
+ if (EVP_PKEY_sign_init(pkeyCtx) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // set pss pkeyCtx parameters
+ if (!setPssPkeyCtxParameters(env, pkeyCtx, paddingType, digestName, mgf1DigestName, saltLen)) {
+ goto cleanup;
+ }
+
+ // sign
+ size_t sigLen = (size_t)EVP_PKEY_size(pkey);
+ if (sigLen <= 0) {
+ KAE_ThrowSignatureException(env, "The sigLen size cannot be zero or negative");
+ goto cleanup;
+ }
+ if ((sigBytes = malloc(sigLen)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc failed");
+ goto cleanup;
+ }
+ if ((digestBytes = (*env)->GetByteArrayElements(env, digestValue, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "GetByteArrayElements failed");
+ goto cleanup;
+ }
+ size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue);
+ if (EVP_PKEY_sign(pkeyCtx, (unsigned char*)sigBytes, &sigLen,
+ (const unsigned char*)digestBytes, digestLen) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // set signature byte to jbyteArray
+ if ((sigByteArray = (*env)->NewByteArray(env, (jsize)sigLen)) == NULL) {
+ KAE_ThrowOOMException(env, "NewByteArray failed");
+ goto cleanup;
+ }
+ (*env)->SetByteArrayRegion(env, sigByteArray, 0, (jsize)sigLen, sigBytes);
+
+cleanup:
+ signRelease(env, digestValue, digestBytes, sigBytes, pkeyCtx);
+ return sigByteArray;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAERSASignatureNative
+ * Method: pssVerify
+ * Signature: (JLjava/lang/String;[BILjava/lang/String;I[B)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNative_pssVerify(JNIEnv* env, jclass cls,
+ jlong keyAddress, jstring digestName, jbyteArray digestValue, jint paddingType, jstring mgf1DigestName,
+ jint saltLen, jbyteArray sigValue) {
+ EVP_PKEY* pkey = (EVP_PKEY*)keyAddress;
+ EVP_PKEY_CTX* pkeyCtx = NULL;
+ jbyte* digestBytes = NULL;
+ jbyte* sigBytes = NULL;
+ jboolean isSuccess = JNI_FALSE;
+ static ENGINE* kaeEngine = NULL;
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+ // new EVP_PKEY_CTX
+ if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // verify init
+ if (EVP_PKEY_verify_init(pkeyCtx) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+
+ // set pkeyCtx parameters
+ if (!setPssPkeyCtxParameters(env, pkeyCtx, paddingType, digestName, mgf1DigestName, saltLen)) {
+ goto cleanup;
+ }
+
+ // verify
+ if ((digestBytes = (*env)->GetByteArrayElements(env, digestValue, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "GetByteArrayElements failed");
+ goto cleanup;
+ }
+ if ((sigBytes = (*env)->GetByteArrayElements(env, sigValue, NULL)) == NULL) {
+ KAE_ThrowOOMException(env, "GetByteArrayElements failed");
+ goto cleanup;
+ }
+ size_t sigLen = (size_t)(*env)->GetArrayLength(env, sigValue);
+ size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue);
+ if (EVP_PKEY_verify(pkeyCtx, (const unsigned char*)sigBytes, sigLen,
+ (const unsigned char*)digestBytes, digestLen) <= 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_PKEY_verify", KAE_ThrowSignatureException);
+ goto cleanup;
+ }
+ isSuccess = JNI_TRUE;
+
+cleanup:
+ verifyRelease(env, digestValue, digestBytes, sigValue, sigBytes, pkeyCtx);
+ return isSuccess;
+}
\ No newline at end of file
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
new file mode 100644
index 00000000..81c7b3ef
--- /dev/null
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <memory.h>
+#include <stdbool.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include "kae_exception.h"
+#include "kae_log.h"
+#include "kae_util.h"
+#include "org_openeuler_security_openssl_KAESymmetricCipherBase.h"
+
+bool StartsWith(const char* str1, const char* str2)
+{
+ if (str1 == NULL || str2 == NULL) {
+ return 0;
+ }
+ int len1 = strlen(str1);
+ int len2 = strlen(str2);
+ if (len1 > len2 || (len1 == 0 || len2 == 0)) {
+ return false;
+ }
+ const char *cur = str1;
+ int i = 0;
+ while (*cur != '\0') {
+ if (*cur != str2[i]) {
+ return 0;
+ }
+ cur++;
+ i++;
+ }
+ return true;
+}
+
+static const EVP_CIPHER* EVPGetSm4CipherByName(JNIEnv* env, const char* algo)
+{
+ static const EVP_CIPHER* sm4Ecb = NULL;
+ static const EVP_CIPHER* sm4Cbc = NULL;
+ static const EVP_CIPHER* sm4Ctr = NULL;
+ static const EVP_CIPHER* sm4Ofb = NULL;
+
+ if (strcasecmp(algo, "sm4-ecb") == 0) {
+ return sm4Ecb == NULL ? sm4Ecb = EVP_get_cipherbyname(algo) : sm4Ecb;
+ } else if (strcasecmp(algo, "sm4-cbc") == 0) {
+ return sm4Cbc == NULL ? sm4Cbc = EVP_get_cipherbyname(algo) : sm4Cbc;
+ } else if (strcasecmp(algo, "sm4-ctr") == 0) {
+ return sm4Ctr == NULL ? sm4Ctr = EVP_get_cipherbyname(algo) : sm4Ctr;
+ } else if (strcasecmp(algo, "sm4-ofb") == 0) {
+ return sm4Ofb == NULL ? sm4Ofb = EVP_get_cipherbyname(algo) : sm4Ofb;
+ } else {
+ KAE_ThrowRuntimeException(env, "EVPGetSm4CipherByName error");
+ return 0;
+ }
+}
+
+static const EVP_CIPHER* EVPGetAesCipherByName(JNIEnv* env, const char* algo)
+{
+ static const EVP_CIPHER* aes128Ecb = NULL;
+ static const EVP_CIPHER* aes128Cbc = NULL;
+ static const EVP_CIPHER* aes128Ctr = NULL;
+ static const EVP_CIPHER* aes128Gcm = NULL;
+ static const EVP_CIPHER* aes192Ecb = NULL;
+ static const EVP_CIPHER* aes192Cbc = NULL;
+ static const EVP_CIPHER* aes192Ctr = NULL;
+ static const EVP_CIPHER* aes192Gcm = NULL;
+ static const EVP_CIPHER* aes256Ecb = NULL;
+ static const EVP_CIPHER* aes256Cbc = NULL;
+ static const EVP_CIPHER* aes256Ctr = NULL;
+ static const EVP_CIPHER* aes256Gcm = NULL;
+
+ if (strcasecmp(algo, "aes-128-ecb") == 0) {
+ return aes128Ecb == NULL ? aes128Ecb = EVP_get_cipherbyname(algo) : aes128Ecb;
+ } else if (strcasecmp(algo, "aes-128-cbc") == 0) {
+ return aes128Cbc == NULL ? aes128Cbc = EVP_get_cipherbyname(algo) : aes128Cbc;
+ } else if (strcasecmp(algo, "aes-128-ctr") == 0) {
+ return aes128Ctr == NULL ? aes128Ctr = EVP_get_cipherbyname(algo) : aes128Ctr;
+ } else if (strcasecmp(algo, "aes-128-gcm") == 0) {
+ return aes128Gcm == NULL ? aes128Gcm = EVP_get_cipherbyname(algo) : aes128Gcm;
+ } else if (strcasecmp(algo, "aes-192-ecb") == 0) {
+ return aes192Ecb == NULL ? aes192Ecb = EVP_get_cipherbyname(algo) : aes192Ecb;
+ } else if (strcasecmp(algo, "aes-192-cbc") == 0) {
+ return aes192Cbc == NULL ? aes192Cbc = EVP_get_cipherbyname(algo) : aes192Cbc;
+ } else if (strcasecmp(algo, "aes-192-ctr") == 0) {
+ return aes192Ctr == NULL ? aes192Ctr = EVP_get_cipherbyname(algo) : aes192Ctr;
+ } else if (strcasecmp(algo, "aes-192-gcm") == 0) {
+ return aes192Gcm == NULL ? aes192Gcm = EVP_get_cipherbyname(algo) : aes192Gcm;
+ } else if (strcasecmp(algo, "aes-256-ecb") == 0) {
+ return aes256Ecb == NULL ? aes256Ecb = EVP_get_cipherbyname(algo) : aes256Ecb;
+ } else if (strcasecmp(algo, "aes-256-cbc") == 0) {
+ return aes256Cbc == NULL ? aes256Cbc = EVP_get_cipherbyname(algo) : aes256Cbc;
+ } else if (strcasecmp(algo, "aes-256-ctr") == 0) {
+ return aes256Ctr == NULL ? aes256Ctr = EVP_get_cipherbyname(algo) : aes256Ctr;
+ } else if (strcasecmp(algo, "aes-256-gcm") == 0) {
+ return aes256Gcm == NULL ? aes256Gcm = EVP_get_cipherbyname(algo) : aes256Gcm;
+ } else {
+ KAE_ThrowRuntimeException(env, "EVPGetAesCipherByName error");
+ return 0;
+ }
+}
+
+void FreeMemoryFromInit(JNIEnv* env, jbyteArray iv, jbyte* ivBytes, jbyteArray key, jbyte* keyBytes)
+{
+ if (ivBytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, iv, ivBytes, 0);
+ }
+ if (keyBytes != NULL) {
+ (*env)->ReleaseByteArrayElements(env, key, keyBytes, 0);
+ }
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAESymmetricCipherBase
+ * Method: nativeInit
+ * Signature: (Ljava/lang/String;Z[B[B)J
+ */
+JNIEXPORT jlong JNICALL
+Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* env, jclass cls,
+ jstring cipherType, jboolean encrypt, jbyteArray key, jbyteArray iv, jboolean padding)
+{
+ EVP_CIPHER_CTX* ctx = NULL;
+ jbyte* keyBytes = NULL;
+ jbyte* ivBytes = NULL;
+ const EVP_CIPHER* cipher = NULL;
+ static ENGINE* kaeEngine = NULL;
+
+ const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0);
+ if (StartsWith("aes", algo)) {
+ cipher = EVPGetAesCipherByName(env, algo);
+ kaeEngine = NULL;
+ } else {
+ cipher = EVPGetSm4CipherByName(env, algo);
+ kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine;
+ }
+ (*env)->ReleaseStringUTFChars(env, cipherType, algo);
+ if (cipher == NULL) {
+ KAE_ThrowOOMException(env, "create EVP_CIPHER fail");
+ goto cleanup;
+ }
+ if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
+ KAE_ThrowOOMException(env, "create EVP_CIPHER_CTX fail");
+ goto cleanup;
+ }
+
+ if (iv != NULL) {
+ ivBytes = (*env)->GetByteArrayElements(env, iv, NULL);
+ }
+ if (key != NULL) {
+ keyBytes = (*env)->GetByteArrayElements(env, key, NULL);
+ }
+
+ if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, (const unsigned char*)keyBytes,
+ (const unsigned char*)ivBytes, encrypt ? 1 : 0)) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+
+ EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
+
+ FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes);
+ return (jlong)ctx;
+
+cleanup:
+ if (ctx != NULL) {
+ EVP_CIPHER_CTX_free(ctx);
+ }
+ FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes);
+ return 0;
+}
+
+static void FreeMemoryFromUpdate(unsigned char* in, unsigned char* aad, unsigned char* out)
+{
+ if (in != NULL) {
+ free(in);
+ }
+ if (out != NULL) {
+ free(out);
+ }
+ if (aad != NULL) {
+ free(aad);
+ }
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAESymmetricCipherBase
+ * Method: nativeUpdate
+ * Signature: (J[BII[BIZ[B)I
+ */
+JNIEXPORT jint JNICALL
+Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeUpdate(JNIEnv* env, jclass cls, jlong ctxAddress,
+ jbyteArray inArr, jint inOfs, jint inLen, jbyteArray outArr, jint outOfs, jboolean gcm, jbyteArray gcmAAD)
+{
+ unsigned char* in = NULL;
+ unsigned char* aad = NULL;
+ unsigned char* out = NULL;
+
+ EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*)ctxAddress;
+ if (ctx == NULL || inArr == NULL || outArr == NULL) {
+ goto cleanup;
+ }
+
+ in = (unsigned char*)malloc(inLen);
+ int outLen = (*env)->GetArrayLength(env, outArr) - outOfs;
+ out = (unsigned char*)malloc(outLen);
+ if (in == NULL || out == NULL) {
+ KAE_ThrowOOMException(env, "malloc error");
+ goto cleanup;
+ }
+ memset(in, 0, inLen);
+ memset(out, 0, outLen);
+ (*env)->GetByteArrayRegion(env, inArr, inOfs, inLen, (jbyte*)in);
+
+ int bytesWritten = 0;
+ if (gcm && (gcmAAD != NULL)) {
+ int aadLen = (*env)->GetArrayLength(env, gcmAAD);
+ if ((aad = (unsigned char*)malloc(aadLen)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc error");
+ goto cleanup;
+ }
+ memset(aad, 0, aadLen);
+ (*env)->GetByteArrayRegion(env, gcmAAD, 0, aadLen, (jbyte*)aad);
+
+ // Specify aad.
+ if (EVP_CipherUpdate(ctx, NULL, &bytesWritten, aad, aadLen) == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherUpdate failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+ }
+
+ if (EVP_CipherUpdate(ctx, out, &bytesWritten, in, inLen) == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherUpdate failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+ (*env)->SetByteArrayRegion(env, outArr, outOfs, bytesWritten, (jbyte*)out);
+
+ FreeMemoryFromUpdate(in, aad, out);
+ return bytesWritten;
+
+cleanup:
+ FreeMemoryFromUpdate(in, aad, out);
+ return 0;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAESymmetricCipherBase
+ * Method: nativeFinal
+ * Signature: (JZ[BI)I
+ */
+JNIEXPORT jint JNICALL
+Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFinal(JNIEnv* env, jclass cls,
+ jlong ctxAddress, jbyteArray outArr, jint outOfs)
+{
+ unsigned char* out = NULL;
+ EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*)ctxAddress;
+ KAE_TRACE("KAESymmetricCipherBase_nativeFinal(ctxAddress = %p, outArr = %p, outOfs = %d)",
+ ctx, outArr, outOfs);
+ if (ctx == NULL || outArr == NULL) {
+ goto cleanup;
+ }
+ int outLen = (*env)->GetArrayLength(env, outArr) - outOfs;
+ out = (unsigned char*)malloc(outLen);
+ if (out == NULL) {
+ KAE_ThrowOOMException(env, "malloc error");
+ goto cleanup;
+ }
+ memset(out, 0, outLen);
+ int bytesWritten = 0;
+ int result_code = EVP_CipherFinal_ex(ctx, out, &bytesWritten);
+ if (result_code == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowBadPaddingException);
+ goto cleanup;
+ }
+ KAE_TRACE("KAESymmetricCipherBase_nativeFinal EVP_CipherFinal_ex success, bytesWritten = %d", bytesWritten);
+ (*env)->SetByteArrayRegion(env, outArr, outOfs, bytesWritten, (jbyte*)out);
+ free(out);
+ KAE_TRACE("KAESymmetricCipherBase_nativeFinal: finished");
+ return bytesWritten;
+
+cleanup:
+ if (out != NULL) {
+ free(out);
+ }
+ return 0;
+}
+
+static void FreeMemoryFromFinalGcm(unsigned char* out, unsigned char* gcmTag, unsigned char* gcmOut)
+{
+ if (out != NULL) {
+ free(out);
+ }
+ if (gcmTag != NULL) {
+ free(gcmTag);
+ }
+ if (gcmOut != NULL) {
+ free(gcmOut);
+ }
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAECipherAES
+ * Method: nativeFinalGcm
+ * Signature: (J[BIZI[BZ)I
+ */
+JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFinalGcm(JNIEnv* env,
+ jclass cls, jlong ctxAddress, jbyteArray outArr, jint outOfs, jboolean gcm, jint tagLength,
+ jbyteArray gcmTagArr, jboolean encrypt)
+{
+ unsigned char* out = NULL;
+ unsigned char* gcmTag = NULL;
+ unsigned char* gcmOut = NULL;
+
+ EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*)ctxAddress;
+ if (ctx == NULL || outArr == NULL) {
+ goto cleanup;
+ }
+
+ int bytesWritten = 0;
+ if (encrypt) {
+ int outLen = (*env)->GetArrayLength(env, outArr) - outOfs;
+ if ((out = malloc(outLen)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc error");
+ goto cleanup;
+ }
+ memset(out, 0, outLen);
+ if (EVP_CipherFinal_ex(ctx, out, &bytesWritten) == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowBadPaddingException);
+ goto cleanup;
+ }
+ (*env)->SetByteArrayRegion(env, outArr, outOfs, bytesWritten, (jbyte*)out);
+
+ // Writes tagLength bytes of the tag value to the buffer.
+ // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EVP_CIPHER_CTX_ctrl.html} for details.
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tagLength, out + bytesWritten) == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CIPHER_CTX_ctrl failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+ (*env)->SetByteArrayRegion(env, outArr, outOfs + bytesWritten, tagLength, (jbyte*)(out + bytesWritten));
+ bytesWritten += tagLength;
+ } else {
+ // gcmOut is the plaintext that has been decrypted in the EVP_CipherUpdate.
+ // outOfs is the length of the gcmOut, where it's always > 0.
+ if ((gcmTag = (unsigned char*)malloc(tagLength)) == NULL || (gcmOut = (unsigned char*)malloc(outOfs)) == NULL) {
+ KAE_ThrowOOMException(env, "malloc error");
+ goto cleanup;
+ }
+ memset(gcmTag, 0, tagLength);
+ memset(gcmOut, 0, outOfs);
+
+ (*env)->GetByteArrayRegion(env, gcmTagArr, 0, tagLength, (jbyte*)gcmTag);
+ // Sets the expected gcmTag to tagLength bytes from gcmTag.
+ // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EVP_CIPHER_CTX_ctrl.html} for details.
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tagLength, gcmTag) == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CTRL_AEAD_SET_TAG failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+
+ (*env)->GetByteArrayRegion(env, outArr, 0, outOfs, (jbyte*)gcmOut);
+ // Finalise: note get no output for GCM
+ if (EVP_CipherFinal_ex(ctx, gcmOut, &bytesWritten) == 0) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowAEADBadTagException);
+ goto cleanup;
+ }
+ }
+ FreeMemoryFromFinalGcm(out, gcmTag, gcmOut);
+
+ return bytesWritten;
+
+cleanup:
+ FreeMemoryFromFinalGcm(out, gcmTag, gcmOut);
+ return 0;
+}
+
+/*
+ * Class: org_openeuler_security_openssl_KAESymmetricCipherBase
+ * Method: nativeFree
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL
+Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFree(JNIEnv* env, jclass cls, jlong ctxAddress)
+{
+ EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*)ctxAddress;
+ KAE_TRACE("KAESymmetricCipherBase_nativeFree(ctx = %p)", ctx);
+ if (ctx != NULL) {
+ EVP_CIPHER_CTX_free(ctx);
+ ctx = NULL;
+ }
+
+ KAE_TRACE("KAESymmetricCipherBase_nativeFree: finished");
+}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c
index 4e4c31ec..a92ba406 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c
@@ -25,6 +25,15 @@
#include "kae_util.h"
#include "kae_exception.h"
+static ENGINE* kaeEngine = NULL;
+
+void SetKaeEngine(ENGINE* engine) {
+ kaeEngine = engine;
+}
+
+ENGINE* GetKaeEngine() {
+ return kaeEngine;
+}
BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray) {
if (byteArray == NULL) {
@@ -47,17 +56,17 @@ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray) {
jbyte* bytes = (*env)->GetByteArrayElements(env, byteArray, NULL);
if (bytes == NULL) {
KAE_ThrowNullPointerException(env,"GetByteArrayElements failed");
- goto error;
+ goto cleanup;
}
BIGNUM* result = BN_bin2bn((const unsigned char*) bytes, len, bn);
(*env)->ReleaseByteArrayElements(env, byteArray, bytes, 0);
if (result == NULL) {
KAE_ThrowFromOpenssl(env, "BN_bin2bn", KAE_ThrowRuntimeException);
- goto error;
+ goto cleanup;
}
return bn;
-error:
+cleanup:
BN_free(bn);
return NULL;
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h
index 35715e1c..fee81627 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h
@@ -36,4 +36,12 @@ void KAE_ReleaseBigNumFromByteArray(BIGNUM* bn);
/* BIGNUM convert to jbyteArray */
jbyteArray KAE_GetByteArrayFromBigNum(JNIEnv* env, const BIGNUM* bn, const char* sourceName);
+void SetKaeEngine(ENGINE* engine);
+
+ENGINE* GetKaeEngine();
+
+void SetKaeEngine(ENGINE* engine);
+
+ENGINE* GetKaeEngine();
+
#endif
diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups
index 9733e17c..d1b13922 100644
--- a/jdk/test/TEST.groups
+++ b/jdk/test/TEST.groups
@@ -180,6 +180,9 @@ jdk_security = \
security/infra/java/security/cert/CertPathValidator/certification \
sun/security/lib/cacerts
+jdk_kae_security = \
+ org/openeuler/security/openssl
+
jdk_text = \
java/text \
sun/text
diff --git a/jdk/test/java/security/Signature/SignatureGetInstance.java b/jdk/test/java/security/Signature/SignatureGetInstance.java
index 1c1d796a..4584527d 100644
--- a/jdk/test/java/security/Signature/SignatureGetInstance.java
+++ b/jdk/test/java/security/Signature/SignatureGetInstance.java
@@ -48,8 +48,11 @@ public class SignatureGetInstance {
MyPrivKey testPriv = new MyPrivKey();
MyPubKey testPub = new MyPubKey();
+ Provider kaeProvider = Security.getProvider("KAEProvider");
+ String expectedProvName = kaeProvider != null ? "KAEProvider" : "SunRsaSign";
+
testDblInit(testPriv, testPub, true, "TestProvider");
- testDblInit(kp.getPrivate(), kp.getPublic(), true, "SunRsaSign");
+ testDblInit(kp.getPrivate(), kp.getPublic(), true, expectedProvName);
testDblInit(testPriv, kp.getPublic(), false, null);
testDblInit(kp.getPrivate(), testPub, false, null);
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/AESBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/AESBenchmark.java
index 0034b67c..e075bb03 100644
--- a/jdk/test/micro/org/openeuler/bench/security/openssl/AESBenchmark.java
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/AESBenchmark.java
@@ -83,7 +83,7 @@ public class AESBenchmark extends BenchmarkBase {
}
@Benchmark
- @Fork(jvmArgsAppend = {"-Dkae.disableKaeDispose=true"})
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
public byte[] encryptDispose() throws IllegalBlockSizeException, BadPaddingException {
byte[] d = data[index];
index = (index + 1) % SET_SIZE;
@@ -98,7 +98,7 @@ public class AESBenchmark extends BenchmarkBase {
}
@Benchmark
- @Fork(jvmArgsAppend = {"-Dkae.disableKaeDispose=true"})
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
public byte[] decryptDispose() throws IllegalBlockSizeException, BadPaddingException {
byte[] e = encryptedData[index];
index = (index + 1) % SET_SIZE;
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/AESGCMBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/AESGCMBenchmark.java
new file mode 100644
index 00000000..92eb6a59
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/AESGCMBenchmark.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openeuler.bench.security.openssl;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.Fork;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidParameterSpecException;
+
+import java.security.Provider;
+
+
+public class AESGCMBenchmark extends BenchmarkBase{
+
+ @Param({"AES/GCM/NoPadding","AES/GCM/PKCS5Padding"})
+ private String algorithm;
+
+ @Param({"128", "192", "256"})
+ private int keyLength;
+
+ @Param({""+1024, "" + 10 * 1024, "" + 100 * 1024, "" + 1024 * 1024})
+ private int dataSize;
+
+ byte[] data;
+ byte[] encryptedData;
+ private Cipher encryptCipher;
+ private Cipher decryptCipher;
+ SecretKeySpec ks;
+ GCMParameterSpec gcm_spec;
+ byte[] aad;
+ byte[] iv;
+
+ public static final int IV_BUFFER_SIZE = 32;
+ public static final int IV_MODULO = IV_BUFFER_SIZE - 16;
+ int iv_index = 0;
+
+ private int next_iv_index() {
+ int r = iv_index;
+ iv_index = (iv_index + 1) % IV_MODULO;
+ return r;
+ }
+
+ @Setup
+ public void setup() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidParameterSpecException {
+ setupProvider();
+ assert algorithm.split("/")[1].compareToIgnoreCase("GCM") == 0;
+
+ byte[] keystring = fillSecureRandom(new byte[keyLength / 8]);
+ ks = new SecretKeySpec(keystring, "AES");
+ iv = fillSecureRandom(new byte[IV_BUFFER_SIZE]);
+ gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16);
+ aad = fillSecureRandom(new byte[5]);
+ encryptCipher = makeCipher(prov, algorithm);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec);
+ encryptCipher.updateAAD(aad);
+ decryptCipher = makeCipher(prov, algorithm);
+ decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters().getParameterSpec(GCMParameterSpec.class));
+ decryptCipher.updateAAD(aad);
+ data = fillRandom(new byte[dataSize]);
+ encryptedData = encryptCipher.doFinal(data);
+ }
+
+ @Benchmark
+ public byte[] encrypt() throws BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
+ gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec);
+ encryptCipher.updateAAD(aad);
+ return encryptCipher.doFinal(data);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
+ public byte[] encrypt_arg() throws BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
+ gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec);
+ encryptCipher.updateAAD(aad);
+ return encryptCipher.doFinal(data);
+ }
+
+ @Benchmark
+ public byte[] decrypt() throws BadPaddingException, IllegalBlockSizeException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException {
+ decryptCipher.init(Cipher.DECRYPT_MODE, ks, gcm_spec);
+ decryptCipher.updateAAD(aad);
+ return decryptCipher.doFinal(encryptedData);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
+ public byte[] decrypt_arg() throws BadPaddingException, IllegalBlockSizeException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException {
+ decryptCipher.init(Cipher.DECRYPT_MODE, ks, gcm_spec);
+ decryptCipher.updateAAD(aad);
+ return decryptCipher.doFinal(encryptedData);
+ }
+
+ public static Cipher makeCipher(Provider prov, String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException {
+ return (prov == null) ? Cipher.getInstance(algorithm) : Cipher.getInstance(algorithm, prov);
+ }
+}
+
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/BenchmarkBase.java b/jdk/test/micro/org/openeuler/bench/security/openssl/BenchmarkBase.java
index 574d3a6d..9aef6dc6 100644
--- a/jdk/test/micro/org/openeuler/bench/security/openssl/BenchmarkBase.java
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/BenchmarkBase.java
@@ -82,6 +82,12 @@ public class BenchmarkBase {
return data;
}
+ public static byte[] fillRandom(byte[] data) {
+ Random rnd = new Random();
+ rnd.nextBytes(data);
+ return data;
+ }
+
public static byte[] fillSecureRandom(byte[] data) {
SecureRandom rnd = new SecureRandom();
rnd.nextBytes(data);
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/DHKeyAgreementBenchMark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/DHKeyAgreementBenchMark.java
new file mode 100644
index 00000000..8a9a2d5d
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/DHKeyAgreementBenchMark.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.bench.security.openssl;
+
+import java.math.BigInteger;
+import java.security.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.security.KeyPairGenerator;
+
+public class DHKeyAgreementBenchMark extends BenchmarkBase {
+ @Param({"DH"})
+ private String algorithm;
+
+ @Param({"512", "1024", "2048", "3072", "4096"})
+ private int keySize;
+
+ private KeyPairGenerator aliceKpairGen, bobKpairGen, carolKpairGen;
+
+ private KeyPair aliceKpair, bobKpair, carolKpair;
+
+ private DHParameterSpec dhSkipParamSpec;
+
+ @Setup
+ public void setUp() throws Exception {
+ setupProvider();
+ aliceKpairGen = createKeyPairGenerator();
+ bobKpairGen = createKeyPairGenerator();
+ carolKpairGen = createKeyPairGenerator();
+
+ // Alice creates her own DH key pair
+ aliceKpairGen.initialize(keySize);
+ aliceKpair = aliceKpairGen.generateKeyPair();
+ // Bob creates his own DH key pair
+ bobKpairGen.initialize(keySize);
+ bobKpair = bobKpairGen.generateKeyPair();
+ // Carol creates her own DH key pair
+ carolKpairGen.initialize(keySize);
+ carolKpair = carolKpairGen.generateKeyPair();
+ }
+
+ @Benchmark
+ public void KeyAgreement() throws Exception {
+
+ // Alice initialize
+ KeyAgreement aliceKeyAgree = (prov == null ? KeyAgreement.getInstance("DH") : KeyAgreement.getInstance("DH", prov));
+ aliceKeyAgree.init(aliceKpair.getPrivate());
+ // Bob initialize
+ KeyAgreement bobKeyAgree = (prov == null ? KeyAgreement.getInstance("DH") : KeyAgreement.getInstance("DH", prov));
+ bobKeyAgree.init(bobKpair.getPrivate());
+ // Carol initialize
+ KeyAgreement carolKeyAgree = (prov == null ? KeyAgreement.getInstance("DH") : KeyAgreement.getInstance("DH", prov));
+ carolKeyAgree.init(carolKpair.getPrivate());
+ // Alice uses Carol's public key
+ Key ac = aliceKeyAgree.doPhase(carolKpair.getPublic(), false);
+ // Bob uses Alice's public key
+ Key ba = bobKeyAgree.doPhase(aliceKpair.getPublic(), false);
+ // Carol uses Bob's public key
+ Key cb = carolKeyAgree.doPhase(bobKpair.getPublic(), false);
+ // Alice uses Carol's result from above
+ aliceKeyAgree.doPhase(cb, true);
+ // Bob uses Alice's result from above
+ bobKeyAgree.doPhase(ac, true);
+ // Carol uses Bob's result from above
+ carolKeyAgree.doPhase(ba, true);
+
+ // Alice, Bob and Carol compute their secrets
+ byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
+ int aliceLen = aliceSharedSecret.length;
+
+ byte[] bobSharedSecret = bobKeyAgree.generateSecret();
+ int bobLen = bobSharedSecret.length;
+
+ byte[] carolSharedSecret = carolKeyAgree.generateSecret();
+ int carolLen = carolSharedSecret.length;
+
+ // Compare Alice and Bob
+ if (aliceLen != bobLen) {
+ throw new Exception("Alice and Bob have different lengths");
+ }
+ for (int i=0; i<aliceLen; i++) {
+ if (aliceSharedSecret[i] != bobSharedSecret[i]) {
+ throw new Exception("Alice and Bob differ");
+ }
+ }
+
+ // Compare Bob and Carol
+ if (bobLen != carolLen) {
+ throw new Exception("Bob and Carol have different lengths");
+ }
+ for (int i=0; i<bobLen; i++) {
+ if (bobSharedSecret[i] != carolSharedSecret[i]) {
+ throw new Exception("Bob and Carol differ");
+ }
+ }
+ }
+
+
+ private KeyPairGenerator createKeyPairGenerator() throws Exception {
+ if (prov != null) {
+ return KeyPairGenerator.getInstance(algorithm, prov);
+ }
+ return KeyPairGenerator.getInstance(algorithm);
+ }
+
+}
+
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/DHKeyPairGeneratorBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/DHKeyPairGeneratorBenchmark.java
new file mode 100644
index 00000000..b3f65b28
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/DHKeyPairGeneratorBenchmark.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.bench.security.openssl;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.security.KeyPairGenerator;
+import java.security.KeyPair;
+
+public class DHKeyPairGeneratorBenchmark extends BenchmarkBase {
+ @Param({"DH"})
+ private String algorithm;
+
+ @Param({"512", "1024", "2048", "3072", "4096"})
+ private int keyLength;
+
+ private KeyPairGenerator keyPairGenerator;
+
+ @Setup
+ public void setUp() throws Exception {
+ setupProvider();
+ keyPairGenerator = createKeyPairGenerator();
+ }
+
+ @Benchmark
+ public KeyPair generateKeyPair() throws Exception {
+ keyPairGenerator.initialize(keyLength);
+ return keyPairGenerator.generateKeyPair();
+ }
+
+ private KeyPairGenerator createKeyPairGenerator() throws Exception {
+ if (prov != null) {
+ return KeyPairGenerator.getInstance(algorithm, prov);
+ }
+ return KeyPairGenerator.getInstance(algorithm);
+ }
+}
+
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/DigestBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/DigestBenchmark.java
index 96d2a24f..16184195 100644
--- a/jdk/test/micro/org/openeuler/bench/security/openssl/DigestBenchmark.java
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/DigestBenchmark.java
@@ -59,7 +59,7 @@ public class DigestBenchmark extends BenchmarkBase {
}
@Benchmark
- @Fork(jvmArgsAppend = {"-Dkae.disableKaeDispose=true"})
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
public byte[] digestDispose() {
byte[] d = data[index];
index = (index + 1) % SET_SIZE;
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/ECKeyAgreementBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/ECKeyAgreementBenchmark.java
new file mode 100644
index 00000000..611998b0
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/ECKeyAgreementBenchmark.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.bench.security.openssl;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Warmup;
+
+import javax.crypto.KeyAgreement;
+import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+@Warmup(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS)
+public class ECKeyAgreementBenchmark extends BenchmarkBase {
+ @Param({"EC"})
+ private String kpgAlgorithm;
+
+ @Param({"ECDH"})
+ private String algorithm;
+
+ @Param({"224", "256", "384", "521"})
+ private int keySize;
+
+ private KeyPairGenerator keyPairGenerator;
+ private KeyAgreement keyAgreement;
+ private PrivateKey privKey;
+ private PublicKey pubKey;
+
+ @Setup
+ public void setUp() throws Exception {
+ setupProvider();
+ keyPairGenerator = createKeyPairGenerator();
+ keyPairGenerator.initialize(keySize);
+ KeyPair kpA = keyPairGenerator.generateKeyPair();
+ privKey = kpA.getPrivate();
+ KeyPair kpB = keyPairGenerator.generateKeyPair();
+ pubKey = kpB.getPublic();
+ keyPairGenerator = createKeyPairGenerator();
+ keyAgreement = createKeyAgreement();
+ }
+
+ @Benchmark
+ public void generateKeyAgreement() throws Exception {
+ keyAgreement.init(privKey);
+ keyAgreement.doPhase(pubKey, true);
+ keyAgreement.generateSecret();
+ }
+
+ private KeyPairGenerator createKeyPairGenerator() throws Exception {
+ if (prov != null) {
+ return KeyPairGenerator.getInstance(kpgAlgorithm, prov);
+ }
+ return KeyPairGenerator.getInstance(kpgAlgorithm);
+ }
+
+ private KeyAgreement createKeyAgreement() throws Exception {
+ if (prov != null) {
+ return KeyAgreement.getInstance(algorithm, prov);
+ }
+ return KeyAgreement.getInstance(algorithm);
+ }
+}
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/ECKeyPairGeneratorBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/ECKeyPairGeneratorBenchmark.java
new file mode 100644
index 00000000..5c37a4f1
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/ECKeyPairGeneratorBenchmark.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openeuler.bench.security.openssl;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.security.KeyPairGenerator;
+
+@Warmup(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS)
+public class ECKeyPairGeneratorBenchmark extends BenchmarkBase {
+ @Param({"EC"})
+ private String algorithm;
+
+ @Param({"224", "256", "384", "521"})
+ private int keySize;
+
+ private KeyPairGenerator keyPairGenerator;
+
+ @Setup
+ public void setUp() throws Exception {
+ setupProvider();
+ keyPairGenerator = createKeyPairGenerator();
+ keyPairGenerator.initialize(keySize);
+ }
+
+ @Benchmark
+ public void generateKeyPair() throws Exception {
+ keyPairGenerator.generateKeyPair();
+ }
+
+ private KeyPairGenerator createKeyPairGenerator() throws Exception {
+ if (prov != null) {
+ return KeyPairGenerator.getInstance(algorithm, prov);
+ }
+ return KeyPairGenerator.getInstance(algorithm);
+ }
+}
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/HMacBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/HMacBenchmark.java
index 584484f3..c9678b74 100644
--- a/jdk/test/micro/org/openeuler/bench/security/openssl/HMacBenchmark.java
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/HMacBenchmark.java
@@ -63,7 +63,7 @@ public class HMacBenchmark extends BenchmarkBase {
}
@Benchmark
- @Fork(jvmArgsAppend = {"-Dkae.disableKaeDispose=true"})
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
public byte[] macDispose() {
byte[] d = data[index];
index = (index + 1) % SET_SIZE;
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/RSAPSSSignatureBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/RSAPSSSignatureBenchmark.java
new file mode 100644
index 00000000..ade15f46
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/RSAPSSSignatureBenchmark.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openeuler.bench.security.openssl;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+
+import java.security.*;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * RSASSA-PSS Signature Benchmark
+ */
+public class RSAPSSSignatureBenchmark extends BenchmarkBase {
+ private static Map<String, PSSParameterSpec> pssParameterSpecMap;
+
+ static {
+ initPSSParameterSpecMap();
+ }
+
+ @Param({"SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"})
+ private String algorithm;
+
+ @Param({"2048", "3072", "4096"})
+ private int keySize;
+
+ @Param({"" + 1024, "" + 10 * 1024, "" + 100 * 1024, "" + 256 * 1024, "" + 1024 * 1024, "" + 10 * 1024 * 1024})
+ private int dataSize;
+
+ private KeyPair keyPair;
+
+ private byte[][] sigData;
+
+
+ private static void initPSSParameterSpecMap() {
+ pssParameterSpecMap = new HashMap<>();
+ pssParameterSpecMap.put("SHA-1", new PSSParameterSpec("SHA-1",
+ "MGF1", MGF1ParameterSpec.SHA1, 20, PSSParameterSpec.TRAILER_FIELD_BC));
+ pssParameterSpecMap.put("SHA-224", new PSSParameterSpec("SHA-224",
+ "MGF1", MGF1ParameterSpec.SHA224, 28, PSSParameterSpec.TRAILER_FIELD_BC));
+ pssParameterSpecMap.put("SHA-256", new PSSParameterSpec("SHA-256",
+ "MGF1", MGF1ParameterSpec.SHA256, 32, PSSParameterSpec.TRAILER_FIELD_BC));
+ pssParameterSpecMap.put("SHA-384", new PSSParameterSpec("SHA-384",
+ "MGF1", MGF1ParameterSpec.SHA384, 48, PSSParameterSpec.TRAILER_FIELD_BC));
+ pssParameterSpecMap.put("SHA-512", new PSSParameterSpec("SHA-512",
+ "MGF1", MGF1ParameterSpec.SHA512, 64, PSSParameterSpec.TRAILER_FIELD_BC));
+ }
+
+ @Setup
+ public void setup() throws Exception {
+ setupProvider();
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(keySize);
+ keyPair = keyPairGenerator.generateKeyPair();
+ data = new byte[SET_SIZE][dataSize];
+ sigData = getSigBytes(data);
+ }
+
+ private byte[][] getSigBytes(byte[][] data) throws Exception {
+ byte[][] sigBytes = new byte[data.length][];
+ Signature signature = prov != null ? Signature.getInstance("RSASSA-PSS", prov) :
+ Signature.getInstance("RSASSA-PSS");
+ signature.setParameter(pssParameterSpecMap.get(algorithm));
+ signature.initSign(keyPair.getPrivate());
+ for (int i = 0; i < sigBytes.length; i++) {
+ signature.update(data[i]);
+ sigBytes[i] = signature.sign();
+ }
+ return sigBytes;
+ }
+
+ @Benchmark
+ public void sign() throws Exception {
+ Signature signature = prov != null ? Signature.getInstance("RSASSA-PSS", prov) :
+ Signature.getInstance("RSASSA-PSS");
+ signature.setParameter(pssParameterSpecMap.get(algorithm));
+ signature.initSign(keyPair.getPrivate());
+ signature.update(data[index]);
+ signature.sign();
+ index = (index + 1) % SET_SIZE;
+ }
+
+ @Benchmark
+ public void verify() throws Exception {
+ Signature signature = prov != null ? Signature.getInstance("RSASSA-PSS", prov) :
+ Signature.getInstance("RSASSA-PSS");
+ signature.setParameter(pssParameterSpecMap.get(algorithm));
+ signature.initVerify(keyPair.getPublic());
+ signature.update(data[index]);
+ signature.verify(sigData[index]);
+ index = (index + 1) % SET_SIZE;
+ }
+}
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/RSASignatureBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/RSASignatureBenchmark.java
new file mode 100644
index 00000000..f1cd4b64
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/RSASignatureBenchmark.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openeuler.bench.security.openssl;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+
+import java.security.*;
+
+/**
+ * RSA Signature Benchmark
+ */
+public class RSASignatureBenchmark extends BenchmarkBase {
+ @Param({"MD5withRSA", "SHA1withRSA", "SHA224withRSA", "SHA384withRSA", "SHA256withRSA", "SHA512withRSA"})
+ private String algorithm;
+
+ @Param({"2048", "3072", "4096"})
+ private int keySize;
+
+ @Param({"" + 1024, "" + 10 * 1024, "" + 100 * 1024, "" + 256 * 1024, "" + 1024 * 1024, "" + 10 * 1024 * 1024})
+ private int dataSize;
+
+ private KeyPair keyPair;
+
+ private byte[][] sigData;
+
+ @Setup
+ public void setup() throws Exception {
+ setupProvider();
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(keySize);
+ keyPair = keyPairGenerator.generateKeyPair();
+ data = new byte[SET_SIZE][dataSize];
+ sigData = getSigBytes(data);
+ }
+
+ private byte[][] getSigBytes(byte[][] data) throws Exception {
+ byte[][] sigBytes = new byte[data.length][];
+ Signature signature = prov != null ? Signature.getInstance(algorithm, prov) :
+ Signature.getInstance(algorithm);
+ signature.initSign(keyPair.getPrivate());
+ for (int i = 0; i < sigBytes.length; i++) {
+ signature.update(data[i]);
+ sigBytes[i] = signature.sign();
+ }
+ return sigBytes;
+ }
+
+ @Benchmark
+ public void sign() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
+ Signature signature = prov != null ? Signature.getInstance(algorithm, prov) :
+ Signature.getInstance(algorithm);
+ signature.initSign(keyPair.getPrivate());
+ signature.update(data[index]);
+ signature.sign();
+ index = (index + 1) % SET_SIZE;
+ }
+
+ @Benchmark
+ public void verify() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
+ Signature signature = prov != null ? Signature.getInstance(algorithm, prov) :
+ Signature.getInstance(algorithm);
+ signature.initVerify(keyPair.getPublic());
+ signature.update(data[index]);
+ signature.verify(sigData[index]);
+ index = (index + 1) % SET_SIZE;
+ }
+}
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/SM3Benchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/SM3Benchmark.java
new file mode 100644
index 00000000..66465037
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/SM3Benchmark.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openeuler.bench.security.openssl;
+
+import org.openeuler.security.openssl.KAEProvider;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 8, time = 2, timeUnit = TimeUnit.SECONDS)
+@Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch"}, value = 5)
+@Threads(1)
+@State(Scope.Thread)
+public class SM3Benchmark {
+ public static final int SET_SIZE = 128;
+ byte[][] data;
+ int index = 0;
+
+ @Param({"SM3"})
+ private String algorithm;
+
+ @Param({"" + 1024, "" + 10 * 1024, "" + 100 * 1024, "" + 1024 * 1024})
+ int dataSize;
+
+ MessageDigest md;
+
+ @Setup
+ public void setup() throws NoSuchAlgorithmException {
+ Security.addProvider(new KAEProvider());
+ Provider prov = Security.getProvider("KAEProvider");
+ data = fillRandom(new byte[SET_SIZE][dataSize]);
+ md = (prov == null) ? MessageDigest.getInstance(algorithm) : MessageDigest.getInstance(algorithm, prov);
+ }
+
+ @Benchmark
+ public byte[] digest() {
+ byte[] d = data[index];
+ index = (index + 1) % SET_SIZE;
+ return md.digest(d);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
+ public byte[] digestDispose() {
+ byte[] d = data[index];
+ index = (index + 1) % SET_SIZE;
+ return md.digest(d);
+ }
+
+ public static byte[][] fillRandom(byte[][] data) {
+ Random rnd = new Random();
+ for (byte[] d : data) {
+ rnd.nextBytes(d);
+ }
+ return data;
+ }
+}
+
diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/SM4Benchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/SM4Benchmark.java
new file mode 100644
index 00000000..e62e68c4
--- /dev/null
+++ b/jdk/test/micro/org/openeuler/bench/security/openssl/SM4Benchmark.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openeuler.bench.security.openssl;
+
+import org.openeuler.security.openssl.KAEProvider;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 8, time = 2, timeUnit = TimeUnit.SECONDS)
+@Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch"}, value = 5)
+@Threads(1)
+@State(Scope.Thread)
+public class SM4Benchmark {
+ public static final int SET_SIZE = 128;
+ byte[][] data;
+ int index = 0;
+
+ @Param({"SM4/ECB/NoPadding", "SM4/ECB/PKCS5Padding", "SM4/CBC/NoPadding", "SM4/CBC/PKCS5Padding", "SM4/CTR/NoPadding", "SM4/OFB/NoPadding", "SM4/OFB/PKCS5Padding"})
+ private String algorithm;
+
+ @Param({"128"})
+ private int keyLength;
+
+ @Param({"" + 1024, "" + 10 * 1024, "" + 100 * 1024, "" + 1024 * 1024})
+ private int dataSize;
+
+ private byte[][] encryptedData;
+ private Cipher encryptCipher;
+ private Cipher decryptCipher;
+
+ @Setup
+ public void setup() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
+ Security.addProvider(new KAEProvider());
+ Provider prov = Security.getProvider("KAEProvider");
+
+ byte[] keystring = fillSecureRandom(new byte[keyLength / 8]);
+ SecretKeySpec ks = new SecretKeySpec(keystring, "SM4");
+
+ encryptCipher = (prov == null) ? Cipher.getInstance(algorithm) : Cipher.getInstance(algorithm, prov);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks);
+ decryptCipher = (prov == null) ? Cipher.getInstance(algorithm) : Cipher.getInstance(algorithm, prov);
+ decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters());
+
+ data = fillRandom(new byte[SET_SIZE][dataSize]);
+ encryptedData = fillEncrypted(data, encryptCipher);
+ }
+
+ @Benchmark
+ public byte[] encrypt() throws IllegalBlockSizeException, BadPaddingException {
+ byte[] d = data[index];
+ index = (index + 1) % SET_SIZE;
+ return encryptCipher.doFinal(d);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
+ public byte[] encryptDispose() throws IllegalBlockSizeException, BadPaddingException {
+ byte[] d = data[index];
+ index = (index + 1) % SET_SIZE;
+ return encryptCipher.doFinal(d);
+ }
+
+ @Benchmark
+ public byte[] decrypt() throws IllegalBlockSizeException, BadPaddingException {
+ byte[] e = encryptedData[index];
+ index = (index + 1) % SET_SIZE;
+ return decryptCipher.doFinal(e);
+ }
+
+ @Benchmark
+ @Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch", "-Dkae.disableKaeDispose=true"}, value = 5)
+ public byte[] decryptDispose() throws IllegalBlockSizeException, BadPaddingException {
+ byte[] e = encryptedData[index];
+ index = (index + 1) % SET_SIZE;
+ return decryptCipher.doFinal(e);
+ }
+
+ public static byte[][] fillRandom(byte[][] data) {
+ Random rnd = new Random();
+ for (byte[] d : data) {
+ rnd.nextBytes(d);
+ }
+ return data;
+ }
+
+ public static byte[] fillRandom(byte[] data) {
+ Random rnd = new Random();
+ rnd.nextBytes(data);
+ return data;
+ }
+
+ public static byte[] fillSecureRandom(byte[] data) {
+ SecureRandom rnd = new SecureRandom();
+ rnd.nextBytes(data);
+ return data;
+ }
+
+ public static byte[][] fillEncrypted(byte[][] data, Cipher encryptCipher)
+ throws IllegalBlockSizeException, BadPaddingException {
+ byte[][] encryptedData = new byte[data.length][];
+ for (int i = 0; i < encryptedData.length; i++) {
+ encryptedData[i] = encryptCipher.doFinal(data[i]);
+ }
+ return encryptedData;
+ }
+}
+
diff --git a/jdk/test/org/openeuler/security/openssl/DHTest.java b/jdk/test/org/openeuler/security/openssl/DHTest.java
new file mode 100644
index 00000000..6eb5e7c9
--- /dev/null
+++ b/jdk/test/org/openeuler/security/openssl/DHTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.*;
+import java.util.Arrays;
+import java.util.Date;
+import javax.crypto.KeyAgreement;
+import javax.crypto.spec.*;
+import org.openeuler.security.openssl.KAEProvider;
+
+/**
+ * This class implements the Diffie-Hellman key exchange algorithm.
+ * D-H means combining your private key with your partners public key to
+ * generate a number. The peer does the same with its private key and our
+ * public key. Through the magic of Diffie-Hellman we both come up with the
+ * same number. This number is secret (discounting MITM attacks) and hence
+ * called the shared secret. It has the same length as the modulus, e.g. 512
+ * or 1024 bit. Man-in-the-middle attacks are typically countered by an
+ * independent authentication step using certificates (RSA, DSA, etc.).
+ *
+ * The thing to note is that the shared secret is constant for two partners
+ * with constant private keys. This is often not what we want, which is why
+ * it is generally a good idea to create a new private key for each session.
+ * Generating a private key involves one modular exponentiation assuming
+ * suitable D-H parameters are available.
+ *
+ * General usage of this class (TLS DHE case):
+ * . if we are server, call DHCrypt(keyLength,random). This generates
+ * an ephemeral keypair of the request length.
+ * . if we are client, call DHCrypt(modulus, base, random). This
+ * generates an ephemeral keypair using the parameters specified by
+ * the server.
+ * . send parameters and public value to remote peer
+ * . receive peers ephemeral public key
+ * . call getAgreedSecret() to calculate the shared secret
+ *
+ * In TLS the server chooses the parameter values itself, the client must use
+ * those sent to it by the server.
+ *
+ * The use of ephemeral keys as described above also achieves what is called
+ * "forward secrecy". This means that even if the authentication keys are
+ * broken at a later date, the shared secret remains secure. The session is
+ * compromised only if the authentication keys are already broken at the
+ * time the key exchange takes place and an active MITM attack is used.
+ * This is in contrast to straightforward encrypting RSA key exchanges.
+ *
+ */
+
+
+/**
+ * @test
+ * @summary Basic test for DH
+ * @run main DHTest
+ */
+
+final class DHTest implements Serializable {
+ private static int bitLength = 8192;
+ private static BigInteger g512;
+ private static BigInteger p512;
+ Throwable t = null;
+
+ private static volatile Provider sunJceProvider;
+ private static volatile Provider kaeProvider;
+ Date d = new Date();
+
+ public static void main(String[] args) throws Exception {
+ Security.addProvider(new KAEProvider());
+ sunJceProvider = Security.getProvider("SunJCE");
+ kaeProvider = Security.getProvider("KAEProvider");
+
+ g512 = new BigInteger("30270326776012916323988175351831539351616124181011347910931933302640902603480679235129557617566480716138395926949700593986872757726720164601940036524221141391913433558162442022339559255078339658108149162251643458301671465579040759659507434340437396584664407572026953757806341363255195983514333141770938654900099033797866272818739547343977583089845850158637618703095710047154252655157633638171416516716598940884520592858762209135010804267830977334033327483815694794951984230264309784679409488441905236794443014066406150649287037909246107758452315504212879842042858577191624250834553614056794526338841821045329189780334");
+
+ p512 = new BigInteger("27672987386729926592037876826877634387173876890702920770064392919138769821035856568775311919542560094764667151024449425954917954337048895981297730855891532066350935045229294626339548842381843985759061682551900379979643117695834175891578650111093016914264824311693147701566019122696621248493126219217339690346346921463135605151471303957324058301097079967414639146647429422884520134312590056632178576758580657240245655739869017244657144448267757255018625514803292549109401806336918448001843022629625467069714240279603204909633404992842479161100500474744098408277938070656334892106100534117209709263785505019003765693651");
+
+ DHTest.bitLength = 0;
+
+ DHParameterSpec dhParams = new DHParameterSpec(p512, g512);
+ KeyPairGenerator SunJCEkeyGen = KeyPairGenerator.getInstance("DH", sunJceProvider);
+ KeyPairGenerator KAEkeyGen = KeyPairGenerator.getInstance("DH", kaeProvider);
+ SunJCEkeyGen.initialize(dhParams, new SecureRandom());
+ KAEkeyGen.initialize(dhParams, new SecureRandom());
+ KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", sunJceProvider);
+ KeyPair aPair = SunJCEkeyGen.generateKeyPair();
+ KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH", kaeProvider);
+ KeyPair bPair = KAEkeyGen.generateKeyPair();
+
+ aKeyAgree.init(aPair.getPrivate());
+ bKeyAgree.init(bPair.getPrivate());
+
+ aKeyAgree.doPhase(bPair.getPublic(), true);
+ bKeyAgree.doPhase(aPair.getPublic(), true);
+
+ MessageDigest hash = MessageDigest.getInstance("MD5");
+ byte[] b1 = hash.digest(aKeyAgree.generateSecret());
+ byte[] b2 = hash.digest(bKeyAgree.generateSecret());
+ if(Arrays.equals(b1, b2)){
+ System.out.println("SUCCESS!");
+ }else{
+ System.out.println("Failed!");
+ throw new RuntimeException("Not Equal DH keyagreement ouput from SunJCE and KAE Provider!");
+ }
+
+ }
+
+}
diff --git a/jdk/test/org/openeuler/security/openssl/ECDHTest.java b/jdk/test/org/openeuler/security/openssl/ECDHTest.java
new file mode 100644
index 00000000..590c3115
--- /dev/null
+++ b/jdk/test/org/openeuler/security/openssl/ECDHTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.openeuler.security.openssl.KAEProvider;
+import sun.security.ec.ECPrivateKeyImpl;
+import sun.security.ec.ECPublicKeyImpl;
+
+import javax.crypto.KeyAgreement;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+import java.util.Arrays;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @test
+ * @summary Basic test for ECDH
+ * @run main ECDHTest
+ */
+
+public class ECDHTest {
+
+ private static KeyPairGenerator keyPairGenerator;
+ private static String algorithm = "EC";
+ private static int[] keyArr = {224, 256, 384, 521};
+
+ public static void main(String[] args) throws Exception {
+ Security.insertProviderAt(new KAEProvider(), 1);
+
+ BigInteger a = new BigInteger("26959946667150639794667015087019630673557916260026308143510066298878");
+ BigInteger b = new BigInteger("18958286285566608000408668544493926415504680968679321075787234672564");
+ BigInteger p = new BigInteger("26959946667150639794667015087019630673557916260026308143510066298881");
+ BigInteger x = new BigInteger("19277929113566293071110308034699488026831934219452440156649784352033");
+ BigInteger y = new BigInteger("19926808758034470970197974370888749184205991990603949537637343198772");
+ EllipticCurve CURVE = new EllipticCurve(new ECFieldFp(p), a, b);
+ ECPoint POINT = new ECPoint(x, y);
+ BigInteger ORDER = new BigInteger("26959946667150639794667015087019625940457807714424391721682722368061");
+ int COFACTOR = 1;
+ ECParameterSpec PARAMS = new ECParameterSpec(CURVE, POINT, ORDER, COFACTOR);
+
+ testKeyPairByParam(PARAMS);
+ for (int keySize : keyArr) {
+ testKeyPairByKeySize(keySize);
+ }
+
+ ECPrivateKeyImpl ecPrivKey = new ECPrivateKeyImpl(new BigInteger("20135071615800221517902437867016717688420688735490569283842831828983"), PARAMS);
+ ECPoint ecPoint = new ECPoint(new BigInteger("9490267631555585552004372465967099662885480699902812460349461311384"), new BigInteger("1974573604976093871117393045089050409882519645527397292712281520811"));
+ ECPublicKeyImpl ecPublicKey = new ECPublicKeyImpl(ecPoint, PARAMS);
+ testKeyAgreement(ecPrivKey, ecPublicKey, new byte[]{-88, -65, 43, -84, 26, 43, 46, 106, 20, 39, -76, 30, -71, 72, -102, 120, 108, -92, -86, -14, -96, -42, 93, -40, -43, -25, 15, -62});
+
+ }
+
+ public static void testKeyPairByParam(ECParameterSpec PARAMS) throws Exception {
+ keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
+ keyPairGenerator.initialize(PARAMS);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ ECPrivateKeyImpl ecPrivKey = (ECPrivateKeyImpl) keyPair.getPrivate();
+ ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl) keyPair.getPublic();
+ }
+
+ public static void testKeyPairByKeySize(int keySize) throws Exception {
+ keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
+ keyPairGenerator.initialize(keySize);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ ECPrivateKeyImpl ecPrivKey = (ECPrivateKeyImpl) keyPair.getPrivate();
+ ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl) keyPair.getPublic();
+ }
+
+ public static void testKeyAgreement(ECPrivateKeyImpl ecPrivKey, ECPublicKeyImpl ecPublicKey, byte[] expectRes) throws Exception {
+ KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
+ keyAgreement.init(ecPrivKey);
+ keyAgreement.doPhase(ecPublicKey, true);
+ byte[] res = keyAgreement.generateSecret();
+ if (!Arrays.equals(res, expectRes)) {
+ throw new RuntimeException("keyagreement failed");
+ }
+ }
+}
diff --git a/jdk/test/org/openeuler/security/openssl/SM3Test.java b/jdk/test/org/openeuler/security/openssl/SM3Test.java
new file mode 100644
index 00000000..181f708f
--- /dev/null
+++ b/jdk/test/org/openeuler/security/openssl/SM3Test.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.openeuler.security.openssl.KAEProvider;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.security.MessageDigest;
+import java.security.Security;
+
+/**
+ * @test
+ * @summary Basic test for sm3
+ * @run main SM3Test
+ */
+
+public class SM3Test {
+
+ private static String plainText = "helloworldhellow";
+
+ public static void main(String[] args) throws Exception {
+ Security.insertProviderAt(new KAEProvider(), 1);
+ test(plainText, "SM3", new byte[]{40, -103, -71, 4, -80, -49, 94, 112, 11, -75, -66, 121, 63, 80, 62, -14, -45, -75, -34, 66, -77, -34, -26, 26, 33, -23, 45, 52, -74, 67, -18, 118});
+ }
+
+ public static void test(String plainText, String algo, byte[] expectRes) throws Exception {
+ MessageDigest md = MessageDigest.getInstance(algo);
+ md.update(plainText.getBytes(StandardCharsets.UTF_8));
+ byte[] res = md.digest();
+ if (!Arrays.equals(res, expectRes)) {
+ throw new RuntimeException("sm3 failed");
+ }
+ }
+
+}
diff --git a/jdk/test/org/openeuler/security/openssl/SM4Test.java b/jdk/test/org/openeuler/security/openssl/SM4Test.java
new file mode 100644
index 00000000..4c28dc5b
--- /dev/null
+++ b/jdk/test/org/openeuler/security/openssl/SM4Test.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.openeuler.security.openssl.KAEProvider;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * @test
+ * @summary Basic test for sm4
+ * @run main SM4Test
+ */
+
+public class SM4Test {
+
+ private static SecretKeySpec ks = new SecretKeySpec("sm4EncryptionKey".getBytes(StandardCharsets.UTF_8), "SM4"); // key has 16 bytes
+ private static IvParameterSpec iv = new IvParameterSpec("abcdefghabcdefgh".getBytes(StandardCharsets.UTF_8)); // iv has 16 bytes
+ private static IvParameterSpec shortIv = new IvParameterSpec("abcdefgh".getBytes(StandardCharsets.UTF_8)); // CTR support >= 8bytes iv
+ private static String plainText = "helloworldhellow"; // 16bytes for NoPadding
+ private static String shortPlainText = "helloworld"; // 5 bytes for padding
+
+ public static void main(String[] args) throws Exception {
+ Security.insertProviderAt(new KAEProvider(), 1);
+ test(plainText, "SM4/CBC/NOPADDING", new byte[]{86, 69, 47, -115, -63, 54, 35, 24, -2, 114, 113, 102, 82, 20, 69, 59});
+ test(shortPlainText, "SM4/CBC/PKCS5Padding", new byte[]{10, 105, 75, -80, -85, -68, 13, -53, 42, 91, -64, 99, 104, 35, -85, 8});
+ test(plainText, "SM4/ECB/NOPADDING", new byte[]{103, 36, -31, -53, -109, -12, -71, -79, -54, 106, 10, -3, -35, -22, -122, -67});
+ test(shortPlainText, "SM4/ECB/PKCS5Padding", new byte[]{-10, 99, -9, 90, 58, -36, -109, 54, -55, -52, 7, -49, 110, -88, 72, 40});
+ test(plainText, "SM4/CTR/NOPADDING", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110, -100, -113, -46, -29, -11, 71});
+ test(plainText, "SM4/OFB/NOPADDING", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110, -100, -113, -46, -29, -11, 71});
+ test(shortPlainText, "SM4/OFB/PKCS5Padding", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110});
+
+ testCtrShortIv(plainText, "SM4/CTR/NOPADDING", new byte[]{-13, 73, 40, -36, -64, -67, 75, -72, 90, 58, 73, -4, -36, 115, 126, -48});
+ }
+
+ public static void test(String plainText, String algo, byte[] expectRes) throws Exception {
+ Cipher encryptCipher = Cipher.getInstance(algo);
+ if (algo.contains("ECB")) {
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks);
+ } else {
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks, iv);
+ }
+ byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
+ if (!Arrays.equals(cipherText, expectRes)) {
+ throw new RuntimeException("sm4 encryption failed, algo = " + algo);
+ }
+
+ Cipher decryptCipher = Cipher.getInstance(algo);
+ decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters());
+ String decryptPlainText = new String(decryptCipher.doFinal(cipherText));
+ if (!plainText.equals(decryptPlainText)) {
+ throw new RuntimeException("sm4 decryption failed, algo = " + algo);
+ }
+ }
+
+ public static void testCtrShortIv(String plainText, String algo, byte[] expectRes) throws Exception {
+ Cipher encryptCipher = Cipher.getInstance(algo);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, ks, shortIv);
+ byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
+ if (!Arrays.equals(cipherText, expectRes)) {
+ throw new RuntimeException("sm4 encryption failed, algo = " + algo);
+ }
+
+ Cipher decryptCipher = Cipher.getInstance(algo);
+ decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters());
+ String decryptPlainText = new String(decryptCipher.doFinal(cipherText));
+ if (!plainText.equals(decryptPlainText)) {
+ throw new RuntimeException("sm4 decryption failed, algo = " + algo);
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ssl/SSLSocketImpl/NotifyHandshakeTest.policy b/jdk/test/sun/security/ssl/SSLSocketImpl/NotifyHandshakeTest.policy
index b426b173..6f65e48a 100644
--- a/jdk/test/sun/security/ssl/SSLSocketImpl/NotifyHandshakeTest.policy
+++ b/jdk/test/sun/security/ssl/SSLSocketImpl/NotifyHandshakeTest.policy
@@ -33,5 +33,7 @@ grant codeBase "file:com.jar" {
"javax.net.ssl.trustStore", "write";
permission java.util.PropertyPermission
"javax.net.ssl.trustStorePassword", "write";
+ permission java.util.PropertyPermission
+ "kae.disableKaeDispose", "read";
};
1
https://gitee.com/src-openeuler/openjdk-1.8.0.git
git@gitee.com:src-openeuler/openjdk-1.8.0.git
src-openeuler
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助