1
0

ocf.patch 723 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661
  1. diff -Nur linux-2.6.27.10.orig/crypto/Kconfig linux-2.6.27.10/crypto/Kconfig
  2. --- linux-2.6.27.10.orig/crypto/Kconfig 2008-12-18 18:13:59.000000000 +0100
  3. +++ linux-2.6.27.10/crypto/Kconfig 2008-12-23 19:31:44.000000000 +0100
  4. @@ -669,3 +669,5 @@
  5. source "drivers/crypto/Kconfig"
  6. endif # if CRYPTO
  7. +
  8. +source "crypto/ocf/Kconfig"
  9. diff -Nur linux-2.6.27.10.orig/crypto/Makefile linux-2.6.27.10/crypto/Makefile
  10. --- linux-2.6.27.10.orig/crypto/Makefile 2008-12-18 18:13:59.000000000 +0100
  11. +++ linux-2.6.27.10/crypto/Makefile 2008-12-23 19:31:44.000000000 +0100
  12. @@ -72,6 +72,8 @@
  13. obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
  14. +obj-$(CONFIG_OCF_OCF) += ocf/
  15. +
  16. #
  17. # generic algorithms and the async_tx api
  18. #
  19. diff -Nur linux-2.6.27.10.orig/crypto/ocf/Config.in linux-2.6.27.10/crypto/ocf/Config.in
  20. --- linux-2.6.27.10.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
  21. +++ linux-2.6.27.10/crypto/ocf/Config.in 2008-12-23 19:31:44.000000000 +0100
  22. @@ -0,0 +1,34 @@
  23. +#############################################################################
  24. +
  25. +mainmenu_option next_comment
  26. +comment 'OCF Configuration'
  27. +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
  28. +dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
  29. + CONFIG_OCF_FIPS $CONFIG_OCF_OCF
  30. +dep_mbool ' enable harvesting entropy for /dev/random' \
  31. + CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
  32. +dep_tristate ' cryptodev (user space support)' \
  33. + CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
  34. +dep_tristate ' cryptosoft (software crypto engine)' \
  35. + CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
  36. +dep_tristate ' safenet (HW crypto engine)' \
  37. + CONFIG_OCF_SAFE $CONFIG_OCF_OCF
  38. +dep_tristate ' IXP4xx (HW crypto engine)' \
  39. + CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
  40. +dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
  41. + CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
  42. +dep_tristate ' hifn (HW crypto engine)' \
  43. + CONFIG_OCF_HIFN $CONFIG_OCF_OCF
  44. +dep_tristate ' talitos (HW crypto engine)' \
  45. + CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
  46. +dep_tristate ' pasemi (HW crypto engine)' \
  47. + CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
  48. +dep_tristate ' ep80579 (HW crypto engine)' \
  49. + CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
  50. +dep_tristate ' ocfnull (does no crypto)' \
  51. + CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
  52. +dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
  53. + CONFIG_OCF_BENCH $CONFIG_OCF_OCF
  54. +endmenu
  55. +
  56. +#############################################################################
  57. diff -Nur linux-2.6.27.10.orig/crypto/ocf/criov.c linux-2.6.27.10/crypto/ocf/criov.c
  58. --- linux-2.6.27.10.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
  59. +++ linux-2.6.27.10/crypto/ocf/criov.c 2008-12-23 19:31:44.000000000 +0100
  60. @@ -0,0 +1,215 @@
  61. +/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
  62. +
  63. +/*
  64. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  65. + * Copyright (C) 2006-2007 David McCullough
  66. + * Copyright (C) 2004-2005 Intel Corporation.
  67. + * The license and original author are listed below.
  68. + *
  69. + * Copyright (c) 1999 Theo de Raadt
  70. + *
  71. + * Redistribution and use in source and binary forms, with or without
  72. + * modification, are permitted provided that the following conditions
  73. + * are met:
  74. + *
  75. + * 1. Redistributions of source code must retain the above copyright
  76. + * notice, this list of conditions and the following disclaimer.
  77. + * 2. Redistributions in binary form must reproduce the above copyright
  78. + * notice, this list of conditions and the following disclaimer in the
  79. + * documentation and/or other materials provided with the distribution.
  80. + * 3. The name of the author may not be used to endorse or promote products
  81. + * derived from this software without specific prior written permission.
  82. + *
  83. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  84. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  85. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  86. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  87. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  88. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  89. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  90. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  91. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  92. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  93. + *
  94. +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
  95. + */
  96. +
  97. +#ifndef AUTOCONF_INCLUDED
  98. +#include <linux/config.h>
  99. +#endif
  100. +#include <linux/module.h>
  101. +#include <linux/init.h>
  102. +#include <linux/slab.h>
  103. +#include <linux/uio.h>
  104. +#include <linux/skbuff.h>
  105. +#include <linux/kernel.h>
  106. +#include <linux/mm.h>
  107. +#include <asm/io.h>
  108. +
  109. +#include <uio.h>
  110. +#include <cryptodev.h>
  111. +
  112. +/*
  113. + * This macro is only for avoiding code duplication, as we need to skip
  114. + * given number of bytes in the same way in three functions below.
  115. + */
  116. +#define CUIO_SKIP() do { \
  117. + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
  118. + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
  119. + while (off > 0) { \
  120. + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
  121. + if (off < iov->iov_len) \
  122. + break; \
  123. + off -= iov->iov_len; \
  124. + iol--; \
  125. + iov++; \
  126. + } \
  127. +} while (0)
  128. +
  129. +void
  130. +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
  131. +{
  132. + struct iovec *iov = uio->uio_iov;
  133. + int iol = uio->uio_iovcnt;
  134. + unsigned count;
  135. +
  136. + CUIO_SKIP();
  137. + while (len > 0) {
  138. + KASSERT(iol >= 0, ("%s: empty", __func__));
  139. + count = min((int)(iov->iov_len - off), len);
  140. + memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
  141. + len -= count;
  142. + cp += count;
  143. + off = 0;
  144. + iol--;
  145. + iov++;
  146. + }
  147. +}
  148. +
  149. +void
  150. +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
  151. +{
  152. + struct iovec *iov = uio->uio_iov;
  153. + int iol = uio->uio_iovcnt;
  154. + unsigned count;
  155. +
  156. + CUIO_SKIP();
  157. + while (len > 0) {
  158. + KASSERT(iol >= 0, ("%s: empty", __func__));
  159. + count = min((int)(iov->iov_len - off), len);
  160. + memcpy(((caddr_t)iov->iov_base) + off, cp, count);
  161. + len -= count;
  162. + cp += count;
  163. + off = 0;
  164. + iol--;
  165. + iov++;
  166. + }
  167. +}
  168. +
  169. +/*
  170. + * Return a pointer to iov/offset of location in iovec list.
  171. + */
  172. +struct iovec *
  173. +cuio_getptr(struct uio *uio, int loc, int *off)
  174. +{
  175. + struct iovec *iov = uio->uio_iov;
  176. + int iol = uio->uio_iovcnt;
  177. +
  178. + while (loc >= 0) {
  179. + /* Normal end of search */
  180. + if (loc < iov->iov_len) {
  181. + *off = loc;
  182. + return (iov);
  183. + }
  184. +
  185. + loc -= iov->iov_len;
  186. + if (iol == 0) {
  187. + if (loc == 0) {
  188. + /* Point at the end of valid data */
  189. + *off = iov->iov_len;
  190. + return (iov);
  191. + } else
  192. + return (NULL);
  193. + } else {
  194. + iov++, iol--;
  195. + }
  196. + }
  197. +
  198. + return (NULL);
  199. +}
  200. +
  201. +EXPORT_SYMBOL(cuio_copyback);
  202. +EXPORT_SYMBOL(cuio_copydata);
  203. +EXPORT_SYMBOL(cuio_getptr);
  204. +
  205. +
  206. +static void
  207. +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
  208. +{
  209. + int i;
  210. + if (offset < skb_headlen(skb)) {
  211. + memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
  212. + len -= skb_headlen(skb);
  213. + cp += skb_headlen(skb);
  214. + }
  215. + offset -= skb_headlen(skb);
  216. + for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
  217. + if (offset < skb_shinfo(skb)->frags[i].size) {
  218. + memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
  219. + skb_shinfo(skb)->frags[i].page_offset,
  220. + cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
  221. + len -= skb_shinfo(skb)->frags[i].size;
  222. + cp += skb_shinfo(skb)->frags[i].size;
  223. + }
  224. + offset -= skb_shinfo(skb)->frags[i].size;
  225. + }
  226. +}
  227. +
  228. +void
  229. +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
  230. +{
  231. +
  232. + if ((flags & CRYPTO_F_SKBUF) != 0)
  233. + skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
  234. + else if ((flags & CRYPTO_F_IOV) != 0)
  235. + cuio_copyback((struct uio *)buf, off, size, in);
  236. + else
  237. + bcopy(in, buf + off, size);
  238. +}
  239. +
  240. +void
  241. +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
  242. +{
  243. +
  244. + if ((flags & CRYPTO_F_SKBUF) != 0)
  245. + skb_copy_bits((struct sk_buff *)buf, off, out, size);
  246. + else if ((flags & CRYPTO_F_IOV) != 0)
  247. + cuio_copydata((struct uio *)buf, off, size, out);
  248. + else
  249. + bcopy(buf + off, out, size);
  250. +}
  251. +
  252. +int
  253. +crypto_apply(int flags, caddr_t buf, int off, int len,
  254. + int (*f)(void *, void *, u_int), void *arg)
  255. +{
  256. +#if 0
  257. + int error;
  258. +
  259. + if ((flags & CRYPTO_F_SKBUF) != 0)
  260. + error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
  261. + else if ((flags & CRYPTO_F_IOV) != 0)
  262. + error = cuio_apply((struct uio *)buf, off, len, f, arg);
  263. + else
  264. + error = (*f)(arg, buf + off, len);
  265. + return (error);
  266. +#else
  267. + KASSERT(0, ("crypto_apply not implemented!\n"));
  268. +#endif
  269. + return 0;
  270. +}
  271. +
  272. +EXPORT_SYMBOL(crypto_copyback);
  273. +EXPORT_SYMBOL(crypto_copydata);
  274. +EXPORT_SYMBOL(crypto_apply);
  275. +
  276. diff -Nur linux-2.6.27.10.orig/crypto/ocf/crypto.c linux-2.6.27.10/crypto/ocf/crypto.c
  277. --- linux-2.6.27.10.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
  278. +++ linux-2.6.27.10/crypto/ocf/crypto.c 2008-12-23 19:31:44.000000000 +0100
  279. @@ -0,0 +1,1741 @@
  280. +/*-
  281. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  282. + * Copyright (C) 2006-2007 David McCullough
  283. + * Copyright (C) 2004-2005 Intel Corporation.
  284. + * The license and original author are listed below.
  285. + *
  286. + * Redistribution and use in source and binary forms, with or without
  287. + * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
  288. + *
  289. + * modification, are permitted provided that the following conditions
  290. + * are met:
  291. + * 1. Redistributions of source code must retain the above copyright
  292. + * notice, this list of conditions and the following disclaimer.
  293. + * 2. Redistributions in binary form must reproduce the above copyright
  294. + * notice, this list of conditions and the following disclaimer in the
  295. + * documentation and/or other materials provided with the distribution.
  296. + *
  297. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  298. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  299. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  300. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  301. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  302. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  303. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  304. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  305. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  306. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  307. + */
  308. +
  309. +#if 0
  310. +#include <sys/cdefs.h>
  311. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
  312. +#endif
  313. +
  314. +/*
  315. + * Cryptographic Subsystem.
  316. + *
  317. + * This code is derived from the Openbsd Cryptographic Framework (OCF)
  318. + * that has the copyright shown below. Very little of the original
  319. + * code remains.
  320. + */
  321. +/*-
  322. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  323. + *
  324. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  325. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  326. + * supported the development of this code.
  327. + *
  328. + * Copyright (c) 2000, 2001 Angelos D. Keromytis
  329. + *
  330. + * Permission to use, copy, and modify this software with or without fee
  331. + * is hereby granted, provided that this entire notice is included in
  332. + * all source code copies of any software which is or includes a copy or
  333. + * modification of this software.
  334. + *
  335. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  336. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  337. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  338. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  339. + * PURPOSE.
  340. + *
  341. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
  342. + */
  343. +
  344. +
  345. +#ifndef AUTOCONF_INCLUDED
  346. +#include <linux/config.h>
  347. +#endif
  348. +#include <linux/module.h>
  349. +#include <linux/init.h>
  350. +#include <linux/list.h>
  351. +#include <linux/slab.h>
  352. +#include <linux/wait.h>
  353. +#include <linux/sched.h>
  354. +#include <linux/spinlock.h>
  355. +#include <linux/version.h>
  356. +#include <cryptodev.h>
  357. +
  358. +/*
  359. + * keep track of whether or not we have been initialised, a big
  360. + * issue if we are linked into the kernel and a driver gets started before
  361. + * us
  362. + */
  363. +static int crypto_initted = 0;
  364. +
  365. +/*
  366. + * Crypto drivers register themselves by allocating a slot in the
  367. + * crypto_drivers table with crypto_get_driverid() and then registering
  368. + * each algorithm they support with crypto_register() and crypto_kregister().
  369. + */
  370. +
  371. +/*
  372. + * lock on driver table
  373. + * we track its state as spin_is_locked does not do anything on non-SMP boxes
  374. + */
  375. +static spinlock_t crypto_drivers_lock;
  376. +static int crypto_drivers_locked; /* for non-SMP boxes */
  377. +
  378. +#define CRYPTO_DRIVER_LOCK() \
  379. + ({ \
  380. + spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
  381. + crypto_drivers_locked = 1; \
  382. + dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
  383. + })
  384. +#define CRYPTO_DRIVER_UNLOCK() \
  385. + ({ \
  386. + dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
  387. + crypto_drivers_locked = 0; \
  388. + spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
  389. + })
  390. +#define CRYPTO_DRIVER_ASSERT() \
  391. + ({ \
  392. + if (!crypto_drivers_locked) { \
  393. + dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
  394. + } \
  395. + })
  396. +
  397. +/*
  398. + * Crypto device/driver capabilities structure.
  399. + *
  400. + * Synchronization:
  401. + * (d) - protected by CRYPTO_DRIVER_LOCK()
  402. + * (q) - protected by CRYPTO_Q_LOCK()
  403. + * Not tagged fields are read-only.
  404. + */
  405. +struct cryptocap {
  406. + device_t cc_dev; /* (d) device/driver */
  407. + u_int32_t cc_sessions; /* (d) # of sessions */
  408. + u_int32_t cc_koperations; /* (d) # os asym operations */
  409. + /*
  410. + * Largest possible operator length (in bits) for each type of
  411. + * encryption algorithm. XXX not used
  412. + */
  413. + u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
  414. + u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
  415. + u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
  416. +
  417. + int cc_flags; /* (d) flags */
  418. +#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
  419. + int cc_qblocked; /* (q) symmetric q blocked */
  420. + int cc_kqblocked; /* (q) asymmetric q blocked */
  421. +};
  422. +static struct cryptocap *crypto_drivers = NULL;
  423. +static int crypto_drivers_num = 0;
  424. +
  425. +/*
  426. + * There are two queues for crypto requests; one for symmetric (e.g.
  427. + * cipher) operations and one for asymmetric (e.g. MOD)operations.
  428. + * A single mutex is used to lock access to both queues. We could
  429. + * have one per-queue but having one simplifies handling of block/unblock
  430. + * operations.
  431. + */
  432. +static int crp_sleep = 0;
  433. +static LIST_HEAD(crp_q); /* request queues */
  434. +static LIST_HEAD(crp_kq);
  435. +
  436. +static spinlock_t crypto_q_lock;
  437. +
  438. +int crypto_all_qblocked = 0; /* protect with Q_LOCK */
  439. +module_param(crypto_all_qblocked, int, 0444);
  440. +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
  441. +
  442. +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
  443. +module_param(crypto_all_kqblocked, int, 0444);
  444. +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
  445. +
  446. +#define CRYPTO_Q_LOCK() \
  447. + ({ \
  448. + spin_lock_irqsave(&crypto_q_lock, q_flags); \
  449. + dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
  450. + })
  451. +#define CRYPTO_Q_UNLOCK() \
  452. + ({ \
  453. + dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
  454. + spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
  455. + })
  456. +
  457. +/*
  458. + * There are two queues for processing completed crypto requests; one
  459. + * for the symmetric and one for the asymmetric ops. We only need one
  460. + * but have two to avoid type futzing (cryptop vs. cryptkop). A single
  461. + * mutex is used to lock access to both queues. Note that this lock
  462. + * must be separate from the lock on request queues to insure driver
  463. + * callbacks don't generate lock order reversals.
  464. + */
  465. +static LIST_HEAD(crp_ret_q); /* callback queues */
  466. +static LIST_HEAD(crp_ret_kq);
  467. +
  468. +static spinlock_t crypto_ret_q_lock;
  469. +#define CRYPTO_RETQ_LOCK() \
  470. + ({ \
  471. + spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
  472. + dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
  473. + })
  474. +#define CRYPTO_RETQ_UNLOCK() \
  475. + ({ \
  476. + dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
  477. + spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
  478. + })
  479. +#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
  480. +
  481. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  482. +static kmem_cache_t *cryptop_zone;
  483. +static kmem_cache_t *cryptodesc_zone;
  484. +#else
  485. +static struct kmem_cache *cryptop_zone;
  486. +static struct kmem_cache *cryptodesc_zone;
  487. +#endif
  488. +
  489. +#define debug crypto_debug
  490. +int crypto_debug = 0;
  491. +module_param(crypto_debug, int, 0644);
  492. +MODULE_PARM_DESC(crypto_debug, "Enable debug");
  493. +EXPORT_SYMBOL(crypto_debug);
  494. +
  495. +/*
  496. + * Maximum number of outstanding crypto requests before we start
  497. + * failing requests. We need this to prevent DOS when too many
  498. + * requests are arriving for us to keep up. Otherwise we will
  499. + * run the system out of memory. Since crypto is slow, we are
  500. + * usually the bottleneck that needs to say, enough is enough.
  501. + *
  502. + * We cannot print errors when this condition occurs, we are already too
  503. + * slow, printing anything will just kill us
  504. + */
  505. +
  506. +static int crypto_q_cnt = 0;
  507. +module_param(crypto_q_cnt, int, 0444);
  508. +MODULE_PARM_DESC(crypto_q_cnt,
  509. + "Current number of outstanding crypto requests");
  510. +
  511. +static int crypto_q_max = 1000;
  512. +module_param(crypto_q_max, int, 0644);
  513. +MODULE_PARM_DESC(crypto_q_max,
  514. + "Maximum number of outstanding crypto requests");
  515. +
  516. +#define bootverbose crypto_verbose
  517. +static int crypto_verbose = 0;
  518. +module_param(crypto_verbose, int, 0644);
  519. +MODULE_PARM_DESC(crypto_verbose,
  520. + "Enable verbose crypto startup");
  521. +
  522. +int crypto_usercrypto = 1; /* userland may do crypto reqs */
  523. +module_param(crypto_usercrypto, int, 0644);
  524. +MODULE_PARM_DESC(crypto_usercrypto,
  525. + "Enable/disable user-mode access to crypto support");
  526. +
  527. +int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
  528. +module_param(crypto_userasymcrypto, int, 0644);
  529. +MODULE_PARM_DESC(crypto_userasymcrypto,
  530. + "Enable/disable user-mode access to asymmetric crypto support");
  531. +
  532. +int crypto_devallowsoft = 0; /* only use hardware crypto */
  533. +module_param(crypto_devallowsoft, int, 0644);
  534. +MODULE_PARM_DESC(crypto_devallowsoft,
  535. + "Enable/disable use of software crypto support");
  536. +
  537. +static pid_t cryptoproc = (pid_t) -1;
  538. +static struct completion cryptoproc_exited;
  539. +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
  540. +static pid_t cryptoretproc = (pid_t) -1;
  541. +static struct completion cryptoretproc_exited;
  542. +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
  543. +
  544. +static int crypto_proc(void *arg);
  545. +static int crypto_ret_proc(void *arg);
  546. +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
  547. +static int crypto_kinvoke(struct cryptkop *krp, int flags);
  548. +static void crypto_exit(void);
  549. +static int crypto_init(void);
  550. +
  551. +static struct cryptostats cryptostats;
  552. +
  553. +static struct cryptocap *
  554. +crypto_checkdriver(u_int32_t hid)
  555. +{
  556. + if (crypto_drivers == NULL)
  557. + return NULL;
  558. + return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
  559. +}
  560. +
  561. +/*
  562. + * Compare a driver's list of supported algorithms against another
  563. + * list; return non-zero if all algorithms are supported.
  564. + */
  565. +static int
  566. +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
  567. +{
  568. + const struct cryptoini *cr;
  569. +
  570. + /* See if all the algorithms are supported. */
  571. + for (cr = cri; cr; cr = cr->cri_next)
  572. + if (cap->cc_alg[cr->cri_alg] == 0)
  573. + return 0;
  574. + return 1;
  575. +}
  576. +
  577. +/*
  578. + * Select a driver for a new session that supports the specified
  579. + * algorithms and, optionally, is constrained according to the flags.
  580. + * The algorithm we use here is pretty stupid; just use the
  581. + * first driver that supports all the algorithms we need. If there
  582. + * are multiple drivers we choose the driver with the fewest active
  583. + * sessions. We prefer hardware-backed drivers to software ones.
  584. + *
  585. + * XXX We need more smarts here (in real life too, but that's
  586. + * XXX another story altogether).
  587. + */
  588. +static struct cryptocap *
  589. +crypto_select_driver(const struct cryptoini *cri, int flags)
  590. +{
  591. + struct cryptocap *cap, *best;
  592. + int match, hid;
  593. +
  594. + CRYPTO_DRIVER_ASSERT();
  595. +
  596. + /*
  597. + * Look first for hardware crypto devices if permitted.
  598. + */
  599. + if (flags & CRYPTOCAP_F_HARDWARE)
  600. + match = CRYPTOCAP_F_HARDWARE;
  601. + else
  602. + match = CRYPTOCAP_F_SOFTWARE;
  603. + best = NULL;
  604. +again:
  605. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  606. + cap = &crypto_drivers[hid];
  607. + /*
  608. + * If it's not initialized, is in the process of
  609. + * going away, or is not appropriate (hardware
  610. + * or software based on match), then skip.
  611. + */
  612. + if (cap->cc_dev == NULL ||
  613. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  614. + (cap->cc_flags & match) == 0)
  615. + continue;
  616. +
  617. + /* verify all the algorithms are supported. */
  618. + if (driver_suitable(cap, cri)) {
  619. + if (best == NULL ||
  620. + cap->cc_sessions < best->cc_sessions)
  621. + best = cap;
  622. + }
  623. + }
  624. + if (best != NULL)
  625. + return best;
  626. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  627. + /* sort of an Algol 68-style for loop */
  628. + match = CRYPTOCAP_F_SOFTWARE;
  629. + goto again;
  630. + }
  631. + return best;
  632. +}
  633. +
  634. +/*
  635. + * Create a new session. The crid argument specifies a crypto
  636. + * driver to use or constraints on a driver to select (hardware
  637. + * only, software only, either). Whatever driver is selected
  638. + * must be capable of the requested crypto algorithms.
  639. + */
  640. +int
  641. +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
  642. +{
  643. + struct cryptocap *cap;
  644. + u_int32_t hid, lid;
  645. + int err;
  646. + unsigned long d_flags;
  647. +
  648. + CRYPTO_DRIVER_LOCK();
  649. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  650. + /*
  651. + * Use specified driver; verify it is capable.
  652. + */
  653. + cap = crypto_checkdriver(crid);
  654. + if (cap != NULL && !driver_suitable(cap, cri))
  655. + cap = NULL;
  656. + } else {
  657. + /*
  658. + * No requested driver; select based on crid flags.
  659. + */
  660. + cap = crypto_select_driver(cri, crid);
  661. + /*
  662. + * if NULL then can't do everything in one session.
  663. + * XXX Fix this. We need to inject a "virtual" session
  664. + * XXX layer right about here.
  665. + */
  666. + }
  667. + if (cap != NULL) {
  668. + /* Call the driver initialization routine. */
  669. + hid = cap - crypto_drivers;
  670. + lid = hid; /* Pass the driver ID. */
  671. + cap->cc_sessions++;
  672. + CRYPTO_DRIVER_UNLOCK();
  673. + err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
  674. + CRYPTO_DRIVER_LOCK();
  675. + if (err == 0) {
  676. + (*sid) = (cap->cc_flags & 0xff000000)
  677. + | (hid & 0x00ffffff);
  678. + (*sid) <<= 32;
  679. + (*sid) |= (lid & 0xffffffff);
  680. + } else
  681. + cap->cc_sessions--;
  682. + } else
  683. + err = EINVAL;
  684. + CRYPTO_DRIVER_UNLOCK();
  685. + return err;
  686. +}
  687. +
  688. +static void
  689. +crypto_remove(struct cryptocap *cap)
  690. +{
  691. + CRYPTO_DRIVER_ASSERT();
  692. + if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
  693. + bzero(cap, sizeof(*cap));
  694. +}
  695. +
  696. +/*
  697. + * Delete an existing session (or a reserved session on an unregistered
  698. + * driver).
  699. + */
  700. +int
  701. +crypto_freesession(u_int64_t sid)
  702. +{
  703. + struct cryptocap *cap;
  704. + u_int32_t hid;
  705. + int err = 0;
  706. + unsigned long d_flags;
  707. +
  708. + dprintk("%s()\n", __FUNCTION__);
  709. + CRYPTO_DRIVER_LOCK();
  710. +
  711. + if (crypto_drivers == NULL) {
  712. + err = EINVAL;
  713. + goto done;
  714. + }
  715. +
  716. + /* Determine two IDs. */
  717. + hid = CRYPTO_SESID2HID(sid);
  718. +
  719. + if (hid >= crypto_drivers_num) {
  720. + dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
  721. + err = ENOENT;
  722. + goto done;
  723. + }
  724. + cap = &crypto_drivers[hid];
  725. +
  726. + if (cap->cc_dev) {
  727. + CRYPTO_DRIVER_UNLOCK();
  728. + /* Call the driver cleanup routine, if available, unlocked. */
  729. + err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
  730. + CRYPTO_DRIVER_LOCK();
  731. + }
  732. +
  733. + if (cap->cc_sessions)
  734. + cap->cc_sessions--;
  735. +
  736. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  737. + crypto_remove(cap);
  738. +
  739. +done:
  740. + CRYPTO_DRIVER_UNLOCK();
  741. + return err;
  742. +}
  743. +
  744. +/*
  745. + * Return an unused driver id. Used by drivers prior to registering
  746. + * support for the algorithms they handle.
  747. + */
  748. +int32_t
  749. +crypto_get_driverid(device_t dev, int flags)
  750. +{
  751. + struct cryptocap *newdrv;
  752. + int i;
  753. + unsigned long d_flags;
  754. +
  755. + if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  756. + printf("%s: no flags specified when registering driver\n",
  757. + device_get_nameunit(dev));
  758. + return -1;
  759. + }
  760. +
  761. + CRYPTO_DRIVER_LOCK();
  762. +
  763. + for (i = 0; i < crypto_drivers_num; i++) {
  764. + if (crypto_drivers[i].cc_dev == NULL &&
  765. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
  766. + break;
  767. + }
  768. + }
  769. +
  770. + /* Out of entries, allocate some more. */
  771. + if (i == crypto_drivers_num) {
  772. + /* Be careful about wrap-around. */
  773. + if (2 * crypto_drivers_num <= crypto_drivers_num) {
  774. + CRYPTO_DRIVER_UNLOCK();
  775. + printk("crypto: driver count wraparound!\n");
  776. + return -1;
  777. + }
  778. +
  779. + newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
  780. + GFP_KERNEL);
  781. + if (newdrv == NULL) {
  782. + CRYPTO_DRIVER_UNLOCK();
  783. + printk("crypto: no space to expand driver table!\n");
  784. + return -1;
  785. + }
  786. +
  787. + memcpy(newdrv, crypto_drivers,
  788. + crypto_drivers_num * sizeof(struct cryptocap));
  789. + memset(&newdrv[crypto_drivers_num], 0,
  790. + crypto_drivers_num * sizeof(struct cryptocap));
  791. +
  792. + crypto_drivers_num *= 2;
  793. +
  794. + kfree(crypto_drivers);
  795. + crypto_drivers = newdrv;
  796. + }
  797. +
  798. + /* NB: state is zero'd on free */
  799. + crypto_drivers[i].cc_sessions = 1; /* Mark */
  800. + crypto_drivers[i].cc_dev = dev;
  801. + crypto_drivers[i].cc_flags = flags;
  802. + if (bootverbose)
  803. + printf("crypto: assign %s driver id %u, flags %u\n",
  804. + device_get_nameunit(dev), i, flags);
  805. +
  806. + CRYPTO_DRIVER_UNLOCK();
  807. +
  808. + return i;
  809. +}
  810. +
  811. +/*
  812. + * Lookup a driver by name. We match against the full device
  813. + * name and unit, and against just the name. The latter gives
  814. + * us a simple widlcarding by device name. On success return the
  815. + * driver/hardware identifier; otherwise return -1.
  816. + */
  817. +int
  818. +crypto_find_driver(const char *match)
  819. +{
  820. + int i, len = strlen(match);
  821. + unsigned long d_flags;
  822. +
  823. + CRYPTO_DRIVER_LOCK();
  824. + for (i = 0; i < crypto_drivers_num; i++) {
  825. + device_t dev = crypto_drivers[i].cc_dev;
  826. + if (dev == NULL ||
  827. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
  828. + continue;
  829. + if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
  830. + strncmp(match, device_get_name(dev), len) == 0)
  831. + break;
  832. + }
  833. + CRYPTO_DRIVER_UNLOCK();
  834. + return i < crypto_drivers_num ? i : -1;
  835. +}
  836. +
  837. +/*
  838. + * Return the device_t for the specified driver or NULL
  839. + * if the driver identifier is invalid.
  840. + */
  841. +device_t
  842. +crypto_find_device_byhid(int hid)
  843. +{
  844. + struct cryptocap *cap = crypto_checkdriver(hid);
  845. + return cap != NULL ? cap->cc_dev : NULL;
  846. +}
  847. +
  848. +/*
  849. + * Return the device/driver capabilities.
  850. + */
  851. +int
  852. +crypto_getcaps(int hid)
  853. +{
  854. + struct cryptocap *cap = crypto_checkdriver(hid);
  855. + return cap != NULL ? cap->cc_flags : 0;
  856. +}
  857. +
  858. +/*
  859. + * Register support for a key-related algorithm. This routine
  860. + * is called once for each algorithm supported a driver.
  861. + */
  862. +int
  863. +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
  864. +{
  865. + struct cryptocap *cap;
  866. + int err;
  867. + unsigned long d_flags;
  868. +
  869. + dprintk("%s()\n", __FUNCTION__);
  870. + CRYPTO_DRIVER_LOCK();
  871. +
  872. + cap = crypto_checkdriver(driverid);
  873. + if (cap != NULL &&
  874. + (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
  875. + /*
  876. + * XXX Do some performance testing to determine placing.
  877. + * XXX We probably need an auxiliary data structure that
  878. + * XXX describes relative performances.
  879. + */
  880. +
  881. + cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  882. + if (bootverbose)
  883. + printf("crypto: %s registers key alg %u flags %u\n"
  884. + , device_get_nameunit(cap->cc_dev)
  885. + , kalg
  886. + , flags
  887. + );
  888. + err = 0;
  889. + } else
  890. + err = EINVAL;
  891. +
  892. + CRYPTO_DRIVER_UNLOCK();
  893. + return err;
  894. +}
  895. +
  896. +/*
  897. + * Register support for a non-key-related algorithm. This routine
  898. + * is called once for each such algorithm supported by a driver.
  899. + */
  900. +int
  901. +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  902. + u_int32_t flags)
  903. +{
  904. + struct cryptocap *cap;
  905. + int err;
  906. + unsigned long d_flags;
  907. +
  908. + dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
  909. + driverid, alg, maxoplen, flags);
  910. +
  911. + CRYPTO_DRIVER_LOCK();
  912. +
  913. + cap = crypto_checkdriver(driverid);
  914. + /* NB: algorithms are in the range [1..max] */
  915. + if (cap != NULL &&
  916. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
  917. + /*
  918. + * XXX Do some performance testing to determine placing.
  919. + * XXX We probably need an auxiliary data structure that
  920. + * XXX describes relative performances.
  921. + */
  922. +
  923. + cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  924. + cap->cc_max_op_len[alg] = maxoplen;
  925. + if (bootverbose)
  926. + printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
  927. + , device_get_nameunit(cap->cc_dev)
  928. + , alg
  929. + , flags
  930. + , maxoplen
  931. + );
  932. + cap->cc_sessions = 0; /* Unmark */
  933. + err = 0;
  934. + } else
  935. + err = EINVAL;
  936. +
  937. + CRYPTO_DRIVER_UNLOCK();
  938. + return err;
  939. +}
  940. +
  941. +static void
  942. +driver_finis(struct cryptocap *cap)
  943. +{
  944. + u_int32_t ses, kops;
  945. +
  946. + CRYPTO_DRIVER_ASSERT();
  947. +
  948. + ses = cap->cc_sessions;
  949. + kops = cap->cc_koperations;
  950. + bzero(cap, sizeof(*cap));
  951. + if (ses != 0 || kops != 0) {
  952. + /*
  953. + * If there are pending sessions,
  954. + * just mark as invalid.
  955. + */
  956. + cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  957. + cap->cc_sessions = ses;
  958. + cap->cc_koperations = kops;
  959. + }
  960. +}
  961. +
  962. +/*
  963. + * Unregister a crypto driver. If there are pending sessions using it,
  964. + * leave enough information around so that subsequent calls using those
  965. + * sessions will correctly detect the driver has been unregistered and
  966. + * reroute requests.
  967. + */
  968. +int
  969. +crypto_unregister(u_int32_t driverid, int alg)
  970. +{
  971. + struct cryptocap *cap;
  972. + int i, err;
  973. + unsigned long d_flags;
  974. +
  975. + dprintk("%s()\n", __FUNCTION__);
  976. + CRYPTO_DRIVER_LOCK();
  977. +
  978. + cap = crypto_checkdriver(driverid);
  979. + if (cap != NULL &&
  980. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
  981. + cap->cc_alg[alg] != 0) {
  982. + cap->cc_alg[alg] = 0;
  983. + cap->cc_max_op_len[alg] = 0;
  984. +
  985. + /* Was this the last algorithm ? */
  986. + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
  987. + if (cap->cc_alg[i] != 0)
  988. + break;
  989. +
  990. + if (i == CRYPTO_ALGORITHM_MAX + 1)
  991. + driver_finis(cap);
  992. + err = 0;
  993. + } else
  994. + err = EINVAL;
  995. + CRYPTO_DRIVER_UNLOCK();
  996. + return err;
  997. +}
  998. +
  999. +/*
  1000. + * Unregister all algorithms associated with a crypto driver.
  1001. + * If there are pending sessions using it, leave enough information
  1002. + * around so that subsequent calls using those sessions will
  1003. + * correctly detect the driver has been unregistered and reroute
  1004. + * requests.
  1005. + */
  1006. +int
  1007. +crypto_unregister_all(u_int32_t driverid)
  1008. +{
  1009. + struct cryptocap *cap;
  1010. + int err;
  1011. + unsigned long d_flags;
  1012. +
  1013. + dprintk("%s()\n", __FUNCTION__);
  1014. + CRYPTO_DRIVER_LOCK();
  1015. + cap = crypto_checkdriver(driverid);
  1016. + if (cap != NULL) {
  1017. + driver_finis(cap);
  1018. + err = 0;
  1019. + } else
  1020. + err = EINVAL;
  1021. + CRYPTO_DRIVER_UNLOCK();
  1022. +
  1023. + return err;
  1024. +}
  1025. +
  1026. +/*
  1027. + * Clear blockage on a driver. The what parameter indicates whether
  1028. + * the driver is now ready for cryptop's and/or cryptokop's.
  1029. + */
  1030. +int
  1031. +crypto_unblock(u_int32_t driverid, int what)
  1032. +{
  1033. + struct cryptocap *cap;
  1034. + int err;
  1035. + unsigned long q_flags;
  1036. +
  1037. + CRYPTO_Q_LOCK();
  1038. + cap = crypto_checkdriver(driverid);
  1039. + if (cap != NULL) {
  1040. + if (what & CRYPTO_SYMQ) {
  1041. + cap->cc_qblocked = 0;
  1042. + crypto_all_qblocked = 0;
  1043. + }
  1044. + if (what & CRYPTO_ASYMQ) {
  1045. + cap->cc_kqblocked = 0;
  1046. + crypto_all_kqblocked = 0;
  1047. + }
  1048. + if (crp_sleep)
  1049. + wake_up_interruptible(&cryptoproc_wait);
  1050. + err = 0;
  1051. + } else
  1052. + err = EINVAL;
  1053. + CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
  1054. +
  1055. + return err;
  1056. +}
  1057. +
  1058. +/*
  1059. + * Add a crypto request to a queue, to be processed by the kernel thread.
  1060. + */
  1061. +int
  1062. +crypto_dispatch(struct cryptop *crp)
  1063. +{
  1064. + struct cryptocap *cap;
  1065. + int result = -1;
  1066. + unsigned long q_flags;
  1067. +
  1068. + dprintk("%s()\n", __FUNCTION__);
  1069. +
  1070. + cryptostats.cs_ops++;
  1071. +
  1072. + CRYPTO_Q_LOCK();
  1073. + if (crypto_q_cnt >= crypto_q_max) {
  1074. + CRYPTO_Q_UNLOCK();
  1075. + cryptostats.cs_drops++;
  1076. + return ENOMEM;
  1077. + }
  1078. + crypto_q_cnt++;
  1079. +
  1080. + /*
  1081. + * Caller marked the request to be processed immediately; dispatch
  1082. + * it directly to the driver unless the driver is currently blocked.
  1083. + */
  1084. + if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
  1085. + int hid = CRYPTO_SESID2HID(crp->crp_sid);
  1086. + cap = crypto_checkdriver(hid);
  1087. + /* Driver cannot disappear when there is an active session. */
  1088. + KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
  1089. + if (!cap->cc_qblocked) {
  1090. + crypto_all_qblocked = 0;
  1091. + crypto_drivers[hid].cc_qblocked = 1;
  1092. + CRYPTO_Q_UNLOCK();
  1093. + result = crypto_invoke(cap, crp, 0);
  1094. + CRYPTO_Q_LOCK();
  1095. + if (result != ERESTART)
  1096. + crypto_drivers[hid].cc_qblocked = 0;
  1097. + }
  1098. + }
  1099. + if (result == ERESTART) {
  1100. + /*
  1101. + * The driver ran out of resources, mark the
  1102. + * driver ``blocked'' for cryptop's and put
  1103. + * the request back in the queue. It would
  1104. + * best to put the request back where we got
  1105. + * it but that's hard so for now we put it
  1106. + * at the front. This should be ok; putting
  1107. + * it at the end does not work.
  1108. + */
  1109. + list_add(&crp->crp_next, &crp_q);
  1110. + cryptostats.cs_blocks++;
  1111. + } else if (result == -1) {
  1112. + TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  1113. + }
  1114. + if (crp_sleep)
  1115. + wake_up_interruptible(&cryptoproc_wait);
  1116. + CRYPTO_Q_UNLOCK();
  1117. + return 0;
  1118. +}
  1119. +
  1120. +/*
  1121. + * Add an asymetric crypto request to a queue,
  1122. + * to be processed by the kernel thread.
  1123. + */
  1124. +int
  1125. +crypto_kdispatch(struct cryptkop *krp)
  1126. +{
  1127. + int error;
  1128. + unsigned long q_flags;
  1129. +
  1130. + cryptostats.cs_kops++;
  1131. +
  1132. + error = crypto_kinvoke(krp, krp->krp_crid);
  1133. + if (error == ERESTART) {
  1134. + CRYPTO_Q_LOCK();
  1135. + TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  1136. + if (crp_sleep)
  1137. + wake_up_interruptible(&cryptoproc_wait);
  1138. + CRYPTO_Q_UNLOCK();
  1139. + error = 0;
  1140. + }
  1141. + return error;
  1142. +}
  1143. +
  1144. +/*
  1145. + * Verify a driver is suitable for the specified operation.
  1146. + */
  1147. +static __inline int
  1148. +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
  1149. +{
  1150. + return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
  1151. +}
  1152. +
  1153. +/*
  1154. + * Select a driver for an asym operation. The driver must
  1155. + * support the necessary algorithm. The caller can constrain
  1156. + * which device is selected with the flags parameter. The
  1157. + * algorithm we use here is pretty stupid; just use the first
  1158. + * driver that supports the algorithms we need. If there are
  1159. + * multiple suitable drivers we choose the driver with the
  1160. + * fewest active operations. We prefer hardware-backed
  1161. + * drivers to software ones when either may be used.
  1162. + */
  1163. +static struct cryptocap *
  1164. +crypto_select_kdriver(const struct cryptkop *krp, int flags)
  1165. +{
  1166. + struct cryptocap *cap, *best, *blocked;
  1167. + int match, hid;
  1168. +
  1169. + CRYPTO_DRIVER_ASSERT();
  1170. +
  1171. + /*
  1172. + * Look first for hardware crypto devices if permitted.
  1173. + */
  1174. + if (flags & CRYPTOCAP_F_HARDWARE)
  1175. + match = CRYPTOCAP_F_HARDWARE;
  1176. + else
  1177. + match = CRYPTOCAP_F_SOFTWARE;
  1178. + best = NULL;
  1179. + blocked = NULL;
  1180. +again:
  1181. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1182. + cap = &crypto_drivers[hid];
  1183. + /*
  1184. + * If it's not initialized, is in the process of
  1185. + * going away, or is not appropriate (hardware
  1186. + * or software based on match), then skip.
  1187. + */
  1188. + if (cap->cc_dev == NULL ||
  1189. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  1190. + (cap->cc_flags & match) == 0)
  1191. + continue;
  1192. +
  1193. + /* verify all the algorithms are supported. */
  1194. + if (kdriver_suitable(cap, krp)) {
  1195. + if (best == NULL ||
  1196. + cap->cc_koperations < best->cc_koperations)
  1197. + best = cap;
  1198. + }
  1199. + }
  1200. + if (best != NULL)
  1201. + return best;
  1202. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  1203. + /* sort of an Algol 68-style for loop */
  1204. + match = CRYPTOCAP_F_SOFTWARE;
  1205. + goto again;
  1206. + }
  1207. + return best;
  1208. +}
  1209. +
  1210. +/*
  1211. + * Dispatch an assymetric crypto request.
  1212. + */
  1213. +static int
  1214. +crypto_kinvoke(struct cryptkop *krp, int crid)
  1215. +{
  1216. + struct cryptocap *cap = NULL;
  1217. + int error;
  1218. + unsigned long d_flags;
  1219. +
  1220. + KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
  1221. + KASSERT(krp->krp_callback != NULL,
  1222. + ("%s: krp->crp_callback == NULL", __func__));
  1223. +
  1224. + CRYPTO_DRIVER_LOCK();
  1225. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  1226. + cap = crypto_checkdriver(crid);
  1227. + if (cap != NULL) {
  1228. + /*
  1229. + * Driver present, it must support the necessary
  1230. + * algorithm and, if s/w drivers are excluded,
  1231. + * it must be registered as hardware-backed.
  1232. + */
  1233. + if (!kdriver_suitable(cap, krp) ||
  1234. + (!crypto_devallowsoft &&
  1235. + (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
  1236. + cap = NULL;
  1237. + }
  1238. + } else {
  1239. + /*
  1240. + * No requested driver; select based on crid flags.
  1241. + */
  1242. + if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
  1243. + crid &= ~CRYPTOCAP_F_SOFTWARE;
  1244. + cap = crypto_select_kdriver(krp, crid);
  1245. + }
  1246. + if (cap != NULL && !cap->cc_kqblocked) {
  1247. + krp->krp_hid = cap - crypto_drivers;
  1248. + cap->cc_koperations++;
  1249. + CRYPTO_DRIVER_UNLOCK();
  1250. + error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
  1251. + CRYPTO_DRIVER_LOCK();
  1252. + if (error == ERESTART) {
  1253. + cap->cc_koperations--;
  1254. + CRYPTO_DRIVER_UNLOCK();
  1255. + return (error);
  1256. + }
  1257. + /* return the actual device used */
  1258. + krp->krp_crid = krp->krp_hid;
  1259. + } else {
  1260. + /*
  1261. + * NB: cap is !NULL if device is blocked; in
  1262. + * that case return ERESTART so the operation
  1263. + * is resubmitted if possible.
  1264. + */
  1265. + error = (cap == NULL) ? ENODEV : ERESTART;
  1266. + }
  1267. + CRYPTO_DRIVER_UNLOCK();
  1268. +
  1269. + if (error) {
  1270. + krp->krp_status = error;
  1271. + crypto_kdone(krp);
  1272. + }
  1273. + return 0;
  1274. +}
  1275. +
  1276. +
  1277. +/*
  1278. + * Dispatch a crypto request to the appropriate crypto devices.
  1279. + */
  1280. +static int
  1281. +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
  1282. +{
  1283. + KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
  1284. + KASSERT(crp->crp_callback != NULL,
  1285. + ("%s: crp->crp_callback == NULL", __func__));
  1286. + KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
  1287. +
  1288. + dprintk("%s()\n", __FUNCTION__);
  1289. +
  1290. +#ifdef CRYPTO_TIMING
  1291. + if (crypto_timing)
  1292. + crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
  1293. +#endif
  1294. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
  1295. + struct cryptodesc *crd;
  1296. + u_int64_t nid;
  1297. +
  1298. + /*
  1299. + * Driver has unregistered; migrate the session and return
  1300. + * an error to the caller so they'll resubmit the op.
  1301. + *
  1302. + * XXX: What if there are more already queued requests for this
  1303. + * session?
  1304. + */
  1305. + crypto_freesession(crp->crp_sid);
  1306. +
  1307. + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
  1308. + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
  1309. +
  1310. + /* XXX propagate flags from initial session? */
  1311. + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
  1312. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
  1313. + crp->crp_sid = nid;
  1314. +
  1315. + crp->crp_etype = EAGAIN;
  1316. + crypto_done(crp);
  1317. + return 0;
  1318. + } else {
  1319. + /*
  1320. + * Invoke the driver to process the request.
  1321. + */
  1322. + return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
  1323. + }
  1324. +}
  1325. +
  1326. +/*
  1327. + * Release a set of crypto descriptors.
  1328. + */
  1329. +void
  1330. +crypto_freereq(struct cryptop *crp)
  1331. +{
  1332. + struct cryptodesc *crd;
  1333. +
  1334. + if (crp == NULL)
  1335. + return;
  1336. +
  1337. +#ifdef DIAGNOSTIC
  1338. + {
  1339. + struct cryptop *crp2;
  1340. + unsigned long q_flags;
  1341. +
  1342. + CRYPTO_Q_LOCK();
  1343. + TAILQ_FOREACH(crp2, &crp_q, crp_next) {
  1344. + KASSERT(crp2 != crp,
  1345. + ("Freeing cryptop from the crypto queue (%p).",
  1346. + crp));
  1347. + }
  1348. + CRYPTO_Q_UNLOCK();
  1349. + CRYPTO_RETQ_LOCK();
  1350. + TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
  1351. + KASSERT(crp2 != crp,
  1352. + ("Freeing cryptop from the return queue (%p).",
  1353. + crp));
  1354. + }
  1355. + CRYPTO_RETQ_UNLOCK();
  1356. + }
  1357. +#endif
  1358. +
  1359. + while ((crd = crp->crp_desc) != NULL) {
  1360. + crp->crp_desc = crd->crd_next;
  1361. + kmem_cache_free(cryptodesc_zone, crd);
  1362. + }
  1363. + kmem_cache_free(cryptop_zone, crp);
  1364. +}
  1365. +
  1366. +/*
  1367. + * Acquire a set of crypto descriptors.
  1368. + */
  1369. +struct cryptop *
  1370. +crypto_getreq(int num)
  1371. +{
  1372. + struct cryptodesc *crd;
  1373. + struct cryptop *crp;
  1374. +
  1375. + crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
  1376. + if (crp != NULL) {
  1377. + memset(crp, 0, sizeof(*crp));
  1378. + INIT_LIST_HEAD(&crp->crp_next);
  1379. + init_waitqueue_head(&crp->crp_waitq);
  1380. + while (num--) {
  1381. + crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
  1382. + if (crd == NULL) {
  1383. + crypto_freereq(crp);
  1384. + return NULL;
  1385. + }
  1386. + memset(crd, 0, sizeof(*crd));
  1387. + crd->crd_next = crp->crp_desc;
  1388. + crp->crp_desc = crd;
  1389. + }
  1390. + }
  1391. + return crp;
  1392. +}
  1393. +
  1394. +/*
  1395. + * Invoke the callback on behalf of the driver.
  1396. + */
  1397. +void
  1398. +crypto_done(struct cryptop *crp)
  1399. +{
  1400. + unsigned long q_flags;
  1401. +
  1402. + dprintk("%s()\n", __FUNCTION__);
  1403. + if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
  1404. + crp->crp_flags |= CRYPTO_F_DONE;
  1405. + CRYPTO_Q_LOCK();
  1406. + crypto_q_cnt--;
  1407. + CRYPTO_Q_UNLOCK();
  1408. + } else
  1409. + printk("crypto: crypto_done op already done, flags 0x%x",
  1410. + crp->crp_flags);
  1411. + if (crp->crp_etype != 0)
  1412. + cryptostats.cs_errs++;
  1413. + /*
  1414. + * CBIMM means unconditionally do the callback immediately;
  1415. + * CBIFSYNC means do the callback immediately only if the
  1416. + * operation was done synchronously. Both are used to avoid
  1417. + * doing extraneous context switches; the latter is mostly
  1418. + * used with the software crypto driver.
  1419. + */
  1420. + if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
  1421. + ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
  1422. + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
  1423. + /*
  1424. + * Do the callback directly. This is ok when the
  1425. + * callback routine does very little (e.g. the
  1426. + * /dev/crypto callback method just does a wakeup).
  1427. + */
  1428. + crp->crp_callback(crp);
  1429. + } else {
  1430. + unsigned long r_flags;
  1431. + /*
  1432. + * Normal case; queue the callback for the thread.
  1433. + */
  1434. + CRYPTO_RETQ_LOCK();
  1435. + if (CRYPTO_RETQ_EMPTY())
  1436. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  1437. + TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
  1438. + CRYPTO_RETQ_UNLOCK();
  1439. + }
  1440. +}
  1441. +
  1442. +/*
  1443. + * Invoke the callback on behalf of the driver.
  1444. + */
  1445. +void
  1446. +crypto_kdone(struct cryptkop *krp)
  1447. +{
  1448. + struct cryptocap *cap;
  1449. + unsigned long d_flags;
  1450. +
  1451. + if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
  1452. + printk("crypto: crypto_kdone op already done, flags 0x%x",
  1453. + krp->krp_flags);
  1454. + krp->krp_flags |= CRYPTO_KF_DONE;
  1455. + if (krp->krp_status != 0)
  1456. + cryptostats.cs_kerrs++;
  1457. +
  1458. + CRYPTO_DRIVER_LOCK();
  1459. + /* XXX: What if driver is loaded in the meantime? */
  1460. + if (krp->krp_hid < crypto_drivers_num) {
  1461. + cap = &crypto_drivers[krp->krp_hid];
  1462. + cap->cc_koperations--;
  1463. + KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
  1464. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  1465. + crypto_remove(cap);
  1466. + }
  1467. + CRYPTO_DRIVER_UNLOCK();
  1468. +
  1469. + /*
  1470. + * CBIMM means unconditionally do the callback immediately;
  1471. + * This is used to avoid doing extraneous context switches
  1472. + */
  1473. + if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
  1474. + /*
  1475. + * Do the callback directly. This is ok when the
  1476. + * callback routine does very little (e.g. the
  1477. + * /dev/crypto callback method just does a wakeup).
  1478. + */
  1479. + krp->krp_callback(krp);
  1480. + } else {
  1481. + unsigned long r_flags;
  1482. + /*
  1483. + * Normal case; queue the callback for the thread.
  1484. + */
  1485. + CRYPTO_RETQ_LOCK();
  1486. + if (CRYPTO_RETQ_EMPTY())
  1487. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  1488. + TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
  1489. + CRYPTO_RETQ_UNLOCK();
  1490. + }
  1491. +}
  1492. +
  1493. +int
  1494. +crypto_getfeat(int *featp)
  1495. +{
  1496. + int hid, kalg, feat = 0;
  1497. + unsigned long d_flags;
  1498. +
  1499. + CRYPTO_DRIVER_LOCK();
  1500. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1501. + const struct cryptocap *cap = &crypto_drivers[hid];
  1502. +
  1503. + if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
  1504. + !crypto_devallowsoft) {
  1505. + continue;
  1506. + }
  1507. + for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
  1508. + if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
  1509. + feat |= 1 << kalg;
  1510. + }
  1511. + CRYPTO_DRIVER_UNLOCK();
  1512. + *featp = feat;
  1513. + return (0);
  1514. +}
  1515. +
  1516. +/*
  1517. + * Crypto thread, dispatches crypto requests.
  1518. + */
  1519. +static int
  1520. +crypto_proc(void *arg)
  1521. +{
  1522. + struct cryptop *crp, *submit;
  1523. + struct cryptkop *krp, *krpp;
  1524. + struct cryptocap *cap;
  1525. + u_int32_t hid;
  1526. + int result, hint;
  1527. + unsigned long q_flags;
  1528. +
  1529. + ocf_daemonize("crypto");
  1530. +
  1531. + CRYPTO_Q_LOCK();
  1532. + for (;;) {
  1533. + /*
  1534. + * we need to make sure we don't get into a busy loop with nothing
  1535. + * to do, the two crypto_all_*blocked vars help us find out when
  1536. + * we are all full and can do nothing on any driver or Q. If so we
  1537. + * wait for an unblock.
  1538. + */
  1539. + crypto_all_qblocked = !list_empty(&crp_q);
  1540. +
  1541. + /*
  1542. + * Find the first element in the queue that can be
  1543. + * processed and look-ahead to see if multiple ops
  1544. + * are ready for the same driver.
  1545. + */
  1546. + submit = NULL;
  1547. + hint = 0;
  1548. + list_for_each_entry(crp, &crp_q, crp_next) {
  1549. + hid = CRYPTO_SESID2HID(crp->crp_sid);
  1550. + cap = crypto_checkdriver(hid);
  1551. + /*
  1552. + * Driver cannot disappear when there is an active
  1553. + * session.
  1554. + */
  1555. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  1556. + __func__, __LINE__));
  1557. + if (cap == NULL || cap->cc_dev == NULL) {
  1558. + /* Op needs to be migrated, process it. */
  1559. + if (submit == NULL)
  1560. + submit = crp;
  1561. + break;
  1562. + }
  1563. + if (!cap->cc_qblocked) {
  1564. + if (submit != NULL) {
  1565. + /*
  1566. + * We stop on finding another op,
  1567. + * regardless whether its for the same
  1568. + * driver or not. We could keep
  1569. + * searching the queue but it might be
  1570. + * better to just use a per-driver
  1571. + * queue instead.
  1572. + */
  1573. + if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
  1574. + hint = CRYPTO_HINT_MORE;
  1575. + break;
  1576. + } else {
  1577. + submit = crp;
  1578. + if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
  1579. + break;
  1580. + /* keep scanning for more are q'd */
  1581. + }
  1582. + }
  1583. + }
  1584. + if (submit != NULL) {
  1585. + hid = CRYPTO_SESID2HID(submit->crp_sid);
  1586. + crypto_all_qblocked = 0;
  1587. + list_del(&submit->crp_next);
  1588. + crypto_drivers[hid].cc_qblocked = 1;
  1589. + cap = crypto_checkdriver(hid);
  1590. + CRYPTO_Q_UNLOCK();
  1591. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  1592. + __func__, __LINE__));
  1593. + result = crypto_invoke(cap, submit, hint);
  1594. + CRYPTO_Q_LOCK();
  1595. + if (result == ERESTART) {
  1596. + /*
  1597. + * The driver ran out of resources, mark the
  1598. + * driver ``blocked'' for cryptop's and put
  1599. + * the request back in the queue. It would
  1600. + * best to put the request back where we got
  1601. + * it but that's hard so for now we put it
  1602. + * at the front. This should be ok; putting
  1603. + * it at the end does not work.
  1604. + */
  1605. + /* XXX validate sid again? */
  1606. + list_add(&submit->crp_next, &crp_q);
  1607. + cryptostats.cs_blocks++;
  1608. + } else
  1609. + crypto_drivers[hid].cc_qblocked=0;
  1610. + }
  1611. +
  1612. + crypto_all_kqblocked = !list_empty(&crp_kq);
  1613. +
  1614. + /* As above, but for key ops */
  1615. + krp = NULL;
  1616. + list_for_each_entry(krpp, &crp_kq, krp_next) {
  1617. + cap = crypto_checkdriver(krpp->krp_hid);
  1618. + if (cap == NULL || cap->cc_dev == NULL) {
  1619. + /*
  1620. + * Operation needs to be migrated, invalidate
  1621. + * the assigned device so it will reselect a
  1622. + * new one below. Propagate the original
  1623. + * crid selection flags if supplied.
  1624. + */
  1625. + krp->krp_hid = krp->krp_crid &
  1626. + (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
  1627. + if (krp->krp_hid == 0)
  1628. + krp->krp_hid =
  1629. + CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
  1630. + break;
  1631. + }
  1632. + if (!cap->cc_kqblocked) {
  1633. + krp = krpp;
  1634. + break;
  1635. + }
  1636. + }
  1637. + if (krp != NULL) {
  1638. + crypto_all_kqblocked = 0;
  1639. + list_del(&krp->krp_next);
  1640. + crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
  1641. + CRYPTO_Q_UNLOCK();
  1642. + result = crypto_kinvoke(krp, krp->krp_hid);
  1643. + CRYPTO_Q_LOCK();
  1644. + if (result == ERESTART) {
  1645. + /*
  1646. + * The driver ran out of resources, mark the
  1647. + * driver ``blocked'' for cryptkop's and put
  1648. + * the request back in the queue. It would
  1649. + * best to put the request back where we got
  1650. + * it but that's hard so for now we put it
  1651. + * at the front. This should be ok; putting
  1652. + * it at the end does not work.
  1653. + */
  1654. + /* XXX validate sid again? */
  1655. + list_add(&krp->krp_next, &crp_kq);
  1656. + cryptostats.cs_kblocks++;
  1657. + } else
  1658. + crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
  1659. + }
  1660. +
  1661. + if (submit == NULL && krp == NULL) {
  1662. + /*
  1663. + * Nothing more to be processed. Sleep until we're
  1664. + * woken because there are more ops to process.
  1665. + * This happens either by submission or by a driver
  1666. + * becoming unblocked and notifying us through
  1667. + * crypto_unblock. Note that when we wakeup we
  1668. + * start processing each queue again from the
  1669. + * front. It's not clear that it's important to
  1670. + * preserve this ordering since ops may finish
  1671. + * out of order if dispatched to different devices
  1672. + * and some become blocked while others do not.
  1673. + */
  1674. + dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
  1675. + __FUNCTION__,
  1676. + list_empty(&crp_q), crypto_all_qblocked,
  1677. + list_empty(&crp_kq), crypto_all_kqblocked);
  1678. + CRYPTO_Q_UNLOCK();
  1679. + crp_sleep = 1;
  1680. + wait_event_interruptible(cryptoproc_wait,
  1681. + !(list_empty(&crp_q) || crypto_all_qblocked) ||
  1682. + !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
  1683. + cryptoproc == (pid_t) -1);
  1684. + crp_sleep = 0;
  1685. + if (signal_pending (current)) {
  1686. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  1687. + spin_lock_irq(&current->sigmask_lock);
  1688. +#endif
  1689. + flush_signals(current);
  1690. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  1691. + spin_unlock_irq(&current->sigmask_lock);
  1692. +#endif
  1693. + }
  1694. + CRYPTO_Q_LOCK();
  1695. + dprintk("%s - awake\n", __FUNCTION__);
  1696. + if (cryptoproc == (pid_t) -1)
  1697. + break;
  1698. + cryptostats.cs_intrs++;
  1699. + }
  1700. + }
  1701. + CRYPTO_Q_UNLOCK();
  1702. + complete_and_exit(&cryptoproc_exited, 0);
  1703. +}
  1704. +
  1705. +/*
  1706. + * Crypto returns thread, does callbacks for processed crypto requests.
  1707. + * Callbacks are done here, rather than in the crypto drivers, because
  1708. + * callbacks typically are expensive and would slow interrupt handling.
  1709. + */
  1710. +static int
  1711. +crypto_ret_proc(void *arg)
  1712. +{
  1713. + struct cryptop *crpt;
  1714. + struct cryptkop *krpt;
  1715. + unsigned long r_flags;
  1716. +
  1717. + ocf_daemonize("crypto_ret");
  1718. +
  1719. + CRYPTO_RETQ_LOCK();
  1720. + for (;;) {
  1721. + /* Harvest return q's for completed ops */
  1722. + crpt = NULL;
  1723. + if (!list_empty(&crp_ret_q))
  1724. + crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
  1725. + if (crpt != NULL)
  1726. + list_del(&crpt->crp_next);
  1727. +
  1728. + krpt = NULL;
  1729. + if (!list_empty(&crp_ret_kq))
  1730. + krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
  1731. + if (krpt != NULL)
  1732. + list_del(&krpt->krp_next);
  1733. +
  1734. + if (crpt != NULL || krpt != NULL) {
  1735. + CRYPTO_RETQ_UNLOCK();
  1736. + /*
  1737. + * Run callbacks unlocked.
  1738. + */
  1739. + if (crpt != NULL)
  1740. + crpt->crp_callback(crpt);
  1741. + if (krpt != NULL)
  1742. + krpt->krp_callback(krpt);
  1743. + CRYPTO_RETQ_LOCK();
  1744. + } else {
  1745. + /*
  1746. + * Nothing more to be processed. Sleep until we're
  1747. + * woken because there are more returns to process.
  1748. + */
  1749. + dprintk("%s - sleeping\n", __FUNCTION__);
  1750. + CRYPTO_RETQ_UNLOCK();
  1751. + wait_event_interruptible(cryptoretproc_wait,
  1752. + cryptoretproc == (pid_t) -1 ||
  1753. + !list_empty(&crp_ret_q) ||
  1754. + !list_empty(&crp_ret_kq));
  1755. + if (signal_pending (current)) {
  1756. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  1757. + spin_lock_irq(&current->sigmask_lock);
  1758. +#endif
  1759. + flush_signals(current);
  1760. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  1761. + spin_unlock_irq(&current->sigmask_lock);
  1762. +#endif
  1763. + }
  1764. + CRYPTO_RETQ_LOCK();
  1765. + dprintk("%s - awake\n", __FUNCTION__);
  1766. + if (cryptoretproc == (pid_t) -1) {
  1767. + dprintk("%s - EXITING!\n", __FUNCTION__);
  1768. + break;
  1769. + }
  1770. + cryptostats.cs_rets++;
  1771. + }
  1772. + }
  1773. + CRYPTO_RETQ_UNLOCK();
  1774. + complete_and_exit(&cryptoretproc_exited, 0);
  1775. +}
  1776. +
  1777. +
  1778. +#if 0 /* should put this into /proc or something */
  1779. +static void
  1780. +db_show_drivers(void)
  1781. +{
  1782. + int hid;
  1783. +
  1784. + db_printf("%12s %4s %4s %8s %2s %2s\n"
  1785. + , "Device"
  1786. + , "Ses"
  1787. + , "Kops"
  1788. + , "Flags"
  1789. + , "QB"
  1790. + , "KB"
  1791. + );
  1792. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1793. + const struct cryptocap *cap = &crypto_drivers[hid];
  1794. + if (cap->cc_dev == NULL)
  1795. + continue;
  1796. + db_printf("%-12s %4u %4u %08x %2u %2u\n"
  1797. + , device_get_nameunit(cap->cc_dev)
  1798. + , cap->cc_sessions
  1799. + , cap->cc_koperations
  1800. + , cap->cc_flags
  1801. + , cap->cc_qblocked
  1802. + , cap->cc_kqblocked
  1803. + );
  1804. + }
  1805. +}
  1806. +
  1807. +DB_SHOW_COMMAND(crypto, db_show_crypto)
  1808. +{
  1809. + struct cryptop *crp;
  1810. +
  1811. + db_show_drivers();
  1812. + db_printf("\n");
  1813. +
  1814. + db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
  1815. + "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
  1816. + "Desc", "Callback");
  1817. + TAILQ_FOREACH(crp, &crp_q, crp_next) {
  1818. + db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
  1819. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  1820. + , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
  1821. + , crp->crp_ilen, crp->crp_olen
  1822. + , crp->crp_etype
  1823. + , crp->crp_flags
  1824. + , crp->crp_desc
  1825. + , crp->crp_callback
  1826. + );
  1827. + }
  1828. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  1829. + db_printf("\n%4s %4s %4s %8s\n",
  1830. + "HID", "Etype", "Flags", "Callback");
  1831. + TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
  1832. + db_printf("%4u %4u %04x %8p\n"
  1833. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  1834. + , crp->crp_etype
  1835. + , crp->crp_flags
  1836. + , crp->crp_callback
  1837. + );
  1838. + }
  1839. + }
  1840. +}
  1841. +
  1842. +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
  1843. +{
  1844. + struct cryptkop *krp;
  1845. +
  1846. + db_show_drivers();
  1847. + db_printf("\n");
  1848. +
  1849. + db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
  1850. + "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
  1851. + TAILQ_FOREACH(krp, &crp_kq, krp_next) {
  1852. + db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
  1853. + , krp->krp_op
  1854. + , krp->krp_status
  1855. + , krp->krp_iparams, krp->krp_oparams
  1856. + , krp->krp_crid, krp->krp_hid
  1857. + , krp->krp_callback
  1858. + );
  1859. + }
  1860. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  1861. + db_printf("%4s %5s %8s %4s %8s\n",
  1862. + "Op", "Status", "CRID", "HID", "Callback");
  1863. + TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
  1864. + db_printf("%4u %5u %08x %4u %8p\n"
  1865. + , krp->krp_op
  1866. + , krp->krp_status
  1867. + , krp->krp_crid, krp->krp_hid
  1868. + , krp->krp_callback
  1869. + );
  1870. + }
  1871. + }
  1872. +}
  1873. +#endif
  1874. +
  1875. +
  1876. +static int
  1877. +crypto_init(void)
  1878. +{
  1879. + int error;
  1880. +
  1881. + dprintk("%s(0x%x)\n", __FUNCTION__, (int) crypto_init);
  1882. +
  1883. + if (crypto_initted)
  1884. + return 0;
  1885. + crypto_initted = 1;
  1886. +
  1887. + spin_lock_init(&crypto_drivers_lock);
  1888. + spin_lock_init(&crypto_q_lock);
  1889. + spin_lock_init(&crypto_ret_q_lock);
  1890. +
  1891. + cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
  1892. + 0, SLAB_HWCACHE_ALIGN, NULL
  1893. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  1894. + , NULL
  1895. +#endif
  1896. + );
  1897. +
  1898. + cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
  1899. + 0, SLAB_HWCACHE_ALIGN, NULL
  1900. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  1901. + , NULL
  1902. +#endif
  1903. + );
  1904. +
  1905. + if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
  1906. + printk("crypto: crypto_init cannot setup crypto zones\n");
  1907. + error = ENOMEM;
  1908. + goto bad;
  1909. + }
  1910. +
  1911. + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
  1912. + crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
  1913. + GFP_KERNEL);
  1914. + if (crypto_drivers == NULL) {
  1915. + printk("crypto: crypto_init cannot setup crypto drivers\n");
  1916. + error = ENOMEM;
  1917. + goto bad;
  1918. + }
  1919. +
  1920. + memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
  1921. +
  1922. + init_completion(&cryptoproc_exited);
  1923. + init_completion(&cryptoretproc_exited);
  1924. +
  1925. + cryptoproc = 0; /* to avoid race condition where proc runs first */
  1926. + cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
  1927. + if (cryptoproc < 0) {
  1928. + error = cryptoproc;
  1929. + printk("crypto: crypto_init cannot start crypto thread; error %d",
  1930. + error);
  1931. + goto bad;
  1932. + }
  1933. +
  1934. + cryptoretproc = 0; /* to avoid race condition where proc runs first */
  1935. + cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
  1936. + if (cryptoretproc < 0) {
  1937. + error = cryptoretproc;
  1938. + printk("crypto: crypto_init cannot start cryptoret thread; error %d",
  1939. + error);
  1940. + goto bad;
  1941. + }
  1942. +
  1943. + return 0;
  1944. +bad:
  1945. + crypto_exit();
  1946. + return error;
  1947. +}
  1948. +
  1949. +
  1950. +static void
  1951. +crypto_exit(void)
  1952. +{
  1953. + pid_t p;
  1954. + unsigned long d_flags;
  1955. +
  1956. + dprintk("%s()\n", __FUNCTION__);
  1957. +
  1958. + /*
  1959. + * Terminate any crypto threads.
  1960. + */
  1961. +
  1962. + CRYPTO_DRIVER_LOCK();
  1963. + p = cryptoproc;
  1964. + cryptoproc = (pid_t) -1;
  1965. + kill_pid(p, SIGTERM, 1);
  1966. + wake_up_interruptible(&cryptoproc_wait);
  1967. + CRYPTO_DRIVER_UNLOCK();
  1968. +
  1969. + wait_for_completion(&cryptoproc_exited);
  1970. +
  1971. + CRYPTO_DRIVER_LOCK();
  1972. + p = cryptoretproc;
  1973. + cryptoretproc = (pid_t) -1;
  1974. + kill_pid(p, SIGTERM, 1);
  1975. + wake_up_interruptible(&cryptoretproc_wait);
  1976. + CRYPTO_DRIVER_UNLOCK();
  1977. +
  1978. + wait_for_completion(&cryptoretproc_exited);
  1979. +
  1980. + /* XXX flush queues??? */
  1981. +
  1982. + /*
  1983. + * Reclaim dynamically allocated resources.
  1984. + */
  1985. + if (crypto_drivers != NULL)
  1986. + kfree(crypto_drivers);
  1987. +
  1988. + if (cryptodesc_zone != NULL)
  1989. + kmem_cache_destroy(cryptodesc_zone);
  1990. + if (cryptop_zone != NULL)
  1991. + kmem_cache_destroy(cryptop_zone);
  1992. +}
  1993. +
  1994. +
  1995. +EXPORT_SYMBOL(crypto_newsession);
  1996. +EXPORT_SYMBOL(crypto_freesession);
  1997. +EXPORT_SYMBOL(crypto_get_driverid);
  1998. +EXPORT_SYMBOL(crypto_kregister);
  1999. +EXPORT_SYMBOL(crypto_register);
  2000. +EXPORT_SYMBOL(crypto_unregister);
  2001. +EXPORT_SYMBOL(crypto_unregister_all);
  2002. +EXPORT_SYMBOL(crypto_unblock);
  2003. +EXPORT_SYMBOL(crypto_dispatch);
  2004. +EXPORT_SYMBOL(crypto_kdispatch);
  2005. +EXPORT_SYMBOL(crypto_freereq);
  2006. +EXPORT_SYMBOL(crypto_getreq);
  2007. +EXPORT_SYMBOL(crypto_done);
  2008. +EXPORT_SYMBOL(crypto_kdone);
  2009. +EXPORT_SYMBOL(crypto_getfeat);
  2010. +EXPORT_SYMBOL(crypto_userasymcrypto);
  2011. +EXPORT_SYMBOL(crypto_getcaps);
  2012. +EXPORT_SYMBOL(crypto_find_driver);
  2013. +EXPORT_SYMBOL(crypto_find_device_byhid);
  2014. +
  2015. +module_init(crypto_init);
  2016. +module_exit(crypto_exit);
  2017. +
  2018. +MODULE_LICENSE("BSD");
  2019. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  2020. +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
  2021. diff -Nur linux-2.6.27.10.orig/crypto/ocf/cryptodev.c linux-2.6.27.10/crypto/ocf/cryptodev.c
  2022. --- linux-2.6.27.10.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
  2023. +++ linux-2.6.27.10/crypto/ocf/cryptodev.c 2008-12-23 19:31:44.000000000 +0100
  2024. @@ -0,0 +1,1048 @@
  2025. +/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
  2026. +
  2027. +/*-
  2028. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  2029. + * Copyright (C) 2006-2007 David McCullough
  2030. + * Copyright (C) 2004-2005 Intel Corporation.
  2031. + * The license and original author are listed below.
  2032. + *
  2033. + * Copyright (c) 2001 Theo de Raadt
  2034. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  2035. + *
  2036. + * Redistribution and use in source and binary forms, with or without
  2037. + * modification, are permitted provided that the following conditions
  2038. + * are met:
  2039. + *
  2040. + * 1. Redistributions of source code must retain the above copyright
  2041. + * notice, this list of conditions and the following disclaimer.
  2042. + * 2. Redistributions in binary form must reproduce the above copyright
  2043. + * notice, this list of conditions and the following disclaimer in the
  2044. + * documentation and/or other materials provided with the distribution.
  2045. + * 3. The name of the author may not be used to endorse or promote products
  2046. + * derived from this software without specific prior written permission.
  2047. + *
  2048. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2049. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2050. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2051. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2052. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2053. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2054. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2055. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2056. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2057. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2058. + *
  2059. + * Effort sponsored in part by the Defense Advanced Research Projects
  2060. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  2061. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  2062. + *
  2063. +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
  2064. + */
  2065. +
  2066. +#ifndef AUTOCONF_INCLUDED
  2067. +#include <linux/config.h>
  2068. +#endif
  2069. +#include <linux/types.h>
  2070. +#include <linux/time.h>
  2071. +#include <linux/delay.h>
  2072. +#include <linux/list.h>
  2073. +#include <linux/init.h>
  2074. +#include <linux/sched.h>
  2075. +#include <linux/unistd.h>
  2076. +#include <linux/module.h>
  2077. +#include <linux/wait.h>
  2078. +#include <linux/slab.h>
  2079. +#include <linux/fs.h>
  2080. +#include <linux/dcache.h>
  2081. +#include <linux/file.h>
  2082. +#include <linux/mount.h>
  2083. +#include <linux/miscdevice.h>
  2084. +#include <linux/version.h>
  2085. +#include <asm/uaccess.h>
  2086. +
  2087. +#include <cryptodev.h>
  2088. +#include <uio.h>
  2089. +
  2090. +extern asmlinkage long sys_dup(unsigned int fildes);
  2091. +
  2092. +#define debug cryptodev_debug
  2093. +int cryptodev_debug = 0;
  2094. +module_param(cryptodev_debug, int, 0644);
  2095. +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
  2096. +
  2097. +struct csession_info {
  2098. + u_int16_t blocksize;
  2099. + u_int16_t minkey, maxkey;
  2100. +
  2101. + u_int16_t keysize;
  2102. + /* u_int16_t hashsize; */
  2103. + u_int16_t authsize;
  2104. + /* u_int16_t ctxsize; */
  2105. +};
  2106. +
  2107. +struct csession {
  2108. + struct list_head list;
  2109. + u_int64_t sid;
  2110. + u_int32_t ses;
  2111. +
  2112. + wait_queue_head_t waitq;
  2113. +
  2114. + u_int32_t cipher;
  2115. +
  2116. + u_int32_t mac;
  2117. +
  2118. + caddr_t key;
  2119. + int keylen;
  2120. + u_char tmp_iv[EALG_MAX_BLOCK_LEN];
  2121. +
  2122. + caddr_t mackey;
  2123. + int mackeylen;
  2124. +
  2125. + struct csession_info info;
  2126. +
  2127. + struct iovec iovec;
  2128. + struct uio uio;
  2129. + int error;
  2130. +};
  2131. +
  2132. +struct fcrypt {
  2133. + struct list_head csessions;
  2134. + int sesn;
  2135. +};
  2136. +
  2137. +static struct csession *csefind(struct fcrypt *, u_int);
  2138. +static int csedelete(struct fcrypt *, struct csession *);
  2139. +static struct csession *cseadd(struct fcrypt *, struct csession *);
  2140. +static struct csession *csecreate(struct fcrypt *, u_int64_t,
  2141. + struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
  2142. +static int csefree(struct csession *);
  2143. +
  2144. +static int cryptodev_op(struct csession *, struct crypt_op *);
  2145. +static int cryptodev_key(struct crypt_kop *);
  2146. +static int cryptodev_find(struct crypt_find_op *);
  2147. +
  2148. +static int cryptodev_cb(void *);
  2149. +static int cryptodev_open(struct inode *inode, struct file *filp);
  2150. +
  2151. +/*
  2152. + * Check a crypto identifier to see if it requested
  2153. + * a valid crid and it's capabilities match.
  2154. + */
  2155. +static int
  2156. +checkcrid(int crid)
  2157. +{
  2158. + int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  2159. + int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  2160. + int caps = 0;
  2161. +
  2162. + /* if the user hasn't selected a driver, then just call newsession */
  2163. + if (hid == 0 && typ != 0)
  2164. + return 0;
  2165. +
  2166. + caps = crypto_getcaps(hid);
  2167. +
  2168. + /* didn't find anything with capabilities */
  2169. + if (caps == 0) {
  2170. + dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
  2171. + return EINVAL;
  2172. + }
  2173. +
  2174. + /* the user didn't specify SW or HW, so the driver is ok */
  2175. + if (typ == 0)
  2176. + return 0;
  2177. +
  2178. + /* if the type specified didn't match */
  2179. + if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
  2180. + dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
  2181. + hid, typ, caps);
  2182. + return EINVAL;
  2183. + }
  2184. +
  2185. + return 0;
  2186. +}
  2187. +
  2188. +static int
  2189. +cryptodev_op(struct csession *cse, struct crypt_op *cop)
  2190. +{
  2191. + struct cryptop *crp = NULL;
  2192. + struct cryptodesc *crde = NULL, *crda = NULL;
  2193. + int error = 0;
  2194. +
  2195. + dprintk("%s()\n", __FUNCTION__);
  2196. + if (cop->len > CRYPTO_MAX_DATA_LEN) {
  2197. + dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
  2198. + return (E2BIG);
  2199. + }
  2200. +
  2201. + if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
  2202. + dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
  2203. + cop->len);
  2204. + return (EINVAL);
  2205. + }
  2206. +
  2207. + cse->uio.uio_iov = &cse->iovec;
  2208. + cse->uio.uio_iovcnt = 1;
  2209. + cse->uio.uio_offset = 0;
  2210. +#if 0
  2211. + cse->uio.uio_resid = cop->len;
  2212. + cse->uio.uio_segflg = UIO_SYSSPACE;
  2213. + cse->uio.uio_rw = UIO_WRITE;
  2214. + cse->uio.uio_td = td;
  2215. +#endif
  2216. + cse->uio.uio_iov[0].iov_len = cop->len;
  2217. + if (cse->info.authsize)
  2218. + cse->uio.uio_iov[0].iov_len += cse->info.authsize;
  2219. + cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
  2220. + GFP_KERNEL);
  2221. +
  2222. + if (cse->uio.uio_iov[0].iov_base == NULL) {
  2223. + dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
  2224. + cse->uio.uio_iov[0].iov_len);
  2225. + return (ENOMEM);
  2226. + }
  2227. +
  2228. + crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
  2229. + if (crp == NULL) {
  2230. + dprintk("%s: ENOMEM\n", __FUNCTION__);
  2231. + error = ENOMEM;
  2232. + goto bail;
  2233. + }
  2234. +
  2235. + if (cse->info.authsize) {
  2236. + crda = crp->crp_desc;
  2237. + if (cse->info.blocksize)
  2238. + crde = crda->crd_next;
  2239. + } else {
  2240. + if (cse->info.blocksize)
  2241. + crde = crp->crp_desc;
  2242. + else {
  2243. + dprintk("%s: bad request\n", __FUNCTION__);
  2244. + error = EINVAL;
  2245. + goto bail;
  2246. + }
  2247. + }
  2248. +
  2249. + if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
  2250. + cop->len))) {
  2251. + dprintk("%s: bad copy\n", __FUNCTION__);
  2252. + goto bail;
  2253. + }
  2254. +
  2255. + if (crda) {
  2256. + crda->crd_skip = 0;
  2257. + crda->crd_len = cop->len;
  2258. + crda->crd_inject = cop->len;
  2259. +
  2260. + crda->crd_alg = cse->mac;
  2261. + crda->crd_key = cse->mackey;
  2262. + crda->crd_klen = cse->mackeylen * 8;
  2263. + }
  2264. +
  2265. + if (crde) {
  2266. + if (cop->op == COP_ENCRYPT)
  2267. + crde->crd_flags |= CRD_F_ENCRYPT;
  2268. + else
  2269. + crde->crd_flags &= ~CRD_F_ENCRYPT;
  2270. + crde->crd_len = cop->len;
  2271. + crde->crd_inject = 0;
  2272. +
  2273. + crde->crd_alg = cse->cipher;
  2274. + crde->crd_key = cse->key;
  2275. + crde->crd_klen = cse->keylen * 8;
  2276. + }
  2277. +
  2278. + crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
  2279. + crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
  2280. + | (cop->flags & COP_F_BATCH);
  2281. + crp->crp_buf = (caddr_t)&cse->uio;
  2282. + crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
  2283. + crp->crp_sid = cse->sid;
  2284. + crp->crp_opaque = (void *)cse;
  2285. +
  2286. + if (cop->iv) {
  2287. + if (crde == NULL) {
  2288. + error = EINVAL;
  2289. + dprintk("%s no crde\n", __FUNCTION__);
  2290. + goto bail;
  2291. + }
  2292. + if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  2293. + error = EINVAL;
  2294. + dprintk("%s arc4 with IV\n", __FUNCTION__);
  2295. + goto bail;
  2296. + }
  2297. + if ((error = copy_from_user(cse->tmp_iv, cop->iv,
  2298. + cse->info.blocksize))) {
  2299. + dprintk("%s bad iv copy\n", __FUNCTION__);
  2300. + goto bail;
  2301. + }
  2302. + memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
  2303. + crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  2304. + crde->crd_skip = 0;
  2305. + } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  2306. + crde->crd_skip = 0;
  2307. + } else if (crde) {
  2308. + crde->crd_flags |= CRD_F_IV_PRESENT;
  2309. + crde->crd_skip = cse->info.blocksize;
  2310. + crde->crd_len -= cse->info.blocksize;
  2311. + }
  2312. +
  2313. + if (cop->mac && crda == NULL) {
  2314. + error = EINVAL;
  2315. + dprintk("%s no crda\n", __FUNCTION__);
  2316. + goto bail;
  2317. + }
  2318. +
  2319. + /*
  2320. + * Let the dispatch run unlocked, then, interlock against the
  2321. + * callback before checking if the operation completed and going
  2322. + * to sleep. This insures drivers don't inherit our lock which
  2323. + * results in a lock order reversal between crypto_dispatch forced
  2324. + * entry and the crypto_done callback into us.
  2325. + */
  2326. + error = crypto_dispatch(crp);
  2327. + if (error == 0) {
  2328. + dprintk("%s about to WAIT\n", __FUNCTION__);
  2329. + /*
  2330. + * we really need to wait for driver to complete to maintain
  2331. + * state, luckily interrupts will be remembered
  2332. + */
  2333. + do {
  2334. + error = wait_event_interruptible(crp->crp_waitq,
  2335. + ((crp->crp_flags & CRYPTO_F_DONE) != 0));
  2336. + /*
  2337. + * we can't break out of this loop or we will leave behind
  2338. + * a huge mess, however, staying here means if your driver
  2339. + * is broken user applications can hang and not be killed.
  2340. + * The solution, fix your driver :-)
  2341. + */
  2342. + if (error) {
  2343. + schedule();
  2344. + error = 0;
  2345. + }
  2346. + } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
  2347. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  2348. + }
  2349. +
  2350. + if (crp->crp_etype != 0) {
  2351. + error = crp->crp_etype;
  2352. + dprintk("%s error in crp processing\n", __FUNCTION__);
  2353. + goto bail;
  2354. + }
  2355. +
  2356. + if (cse->error) {
  2357. + error = cse->error;
  2358. + dprintk("%s error in cse processing\n", __FUNCTION__);
  2359. + goto bail;
  2360. + }
  2361. +
  2362. + if (cop->dst && (error = copy_to_user(cop->dst,
  2363. + cse->uio.uio_iov[0].iov_base, cop->len))) {
  2364. + dprintk("%s bad dst copy\n", __FUNCTION__);
  2365. + goto bail;
  2366. + }
  2367. +
  2368. + if (cop->mac &&
  2369. + (error=copy_to_user(cop->mac,
  2370. + (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
  2371. + cse->info.authsize))) {
  2372. + dprintk("%s bad mac copy\n", __FUNCTION__);
  2373. + goto bail;
  2374. + }
  2375. +
  2376. +bail:
  2377. + if (crp)
  2378. + crypto_freereq(crp);
  2379. + if (cse->uio.uio_iov[0].iov_base)
  2380. + kfree(cse->uio.uio_iov[0].iov_base);
  2381. +
  2382. + return (error);
  2383. +}
  2384. +
  2385. +static int
  2386. +cryptodev_cb(void *op)
  2387. +{
  2388. + struct cryptop *crp = (struct cryptop *) op;
  2389. + struct csession *cse = (struct csession *)crp->crp_opaque;
  2390. + int error;
  2391. +
  2392. + dprintk("%s()\n", __FUNCTION__);
  2393. + error = crp->crp_etype;
  2394. + if (error == EAGAIN) {
  2395. + crp->crp_flags &= ~CRYPTO_F_DONE;
  2396. +#ifdef NOTYET
  2397. + /*
  2398. + * DAVIDM I am fairly sure that we should turn this into a batch
  2399. + * request to stop bad karma/lockup, revisit
  2400. + */
  2401. + crp->crp_flags |= CRYPTO_F_BATCH;
  2402. +#endif
  2403. + return crypto_dispatch(crp);
  2404. + }
  2405. + if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
  2406. + cse->error = error;
  2407. + wake_up_interruptible(&crp->crp_waitq);
  2408. + }
  2409. + return (0);
  2410. +}
  2411. +
  2412. +static int
  2413. +cryptodevkey_cb(void *op)
  2414. +{
  2415. + struct cryptkop *krp = (struct cryptkop *) op;
  2416. + dprintk("%s()\n", __FUNCTION__);
  2417. + wake_up_interruptible(&krp->krp_waitq);
  2418. + return (0);
  2419. +}
  2420. +
  2421. +static int
  2422. +cryptodev_key(struct crypt_kop *kop)
  2423. +{
  2424. + struct cryptkop *krp = NULL;
  2425. + int error = EINVAL;
  2426. + int in, out, size, i;
  2427. +
  2428. + dprintk("%s()\n", __FUNCTION__);
  2429. + if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
  2430. + dprintk("%s params too big\n", __FUNCTION__);
  2431. + return (EFBIG);
  2432. + }
  2433. +
  2434. + in = kop->crk_iparams;
  2435. + out = kop->crk_oparams;
  2436. + switch (kop->crk_op) {
  2437. + case CRK_MOD_EXP:
  2438. + if (in == 3 && out == 1)
  2439. + break;
  2440. + return (EINVAL);
  2441. + case CRK_MOD_EXP_CRT:
  2442. + if (in == 6 && out == 1)
  2443. + break;
  2444. + return (EINVAL);
  2445. + case CRK_DSA_SIGN:
  2446. + if (in == 5 && out == 2)
  2447. + break;
  2448. + return (EINVAL);
  2449. + case CRK_DSA_VERIFY:
  2450. + if (in == 7 && out == 0)
  2451. + break;
  2452. + return (EINVAL);
  2453. + case CRK_DH_COMPUTE_KEY:
  2454. + if (in == 3 && out == 1)
  2455. + break;
  2456. + return (EINVAL);
  2457. + default:
  2458. + return (EINVAL);
  2459. + }
  2460. +
  2461. + krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
  2462. + if (!krp)
  2463. + return (ENOMEM);
  2464. + bzero(krp, sizeof *krp);
  2465. + krp->krp_op = kop->crk_op;
  2466. + krp->krp_status = kop->crk_status;
  2467. + krp->krp_iparams = kop->crk_iparams;
  2468. + krp->krp_oparams = kop->crk_oparams;
  2469. + krp->krp_crid = kop->crk_crid;
  2470. + krp->krp_status = 0;
  2471. + krp->krp_flags = CRYPTO_KF_CBIMM;
  2472. + krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
  2473. + init_waitqueue_head(&krp->krp_waitq);
  2474. +
  2475. + for (i = 0; i < CRK_MAXPARAM; i++)
  2476. + krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
  2477. + for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
  2478. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  2479. + if (size == 0)
  2480. + continue;
  2481. + krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
  2482. + if (i >= krp->krp_iparams)
  2483. + continue;
  2484. + error = copy_from_user(krp->krp_param[i].crp_p,
  2485. + kop->crk_param[i].crp_p, size);
  2486. + if (error)
  2487. + goto fail;
  2488. + }
  2489. +
  2490. + error = crypto_kdispatch(krp);
  2491. + if (error)
  2492. + goto fail;
  2493. +
  2494. + do {
  2495. + error = wait_event_interruptible(krp->krp_waitq,
  2496. + ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
  2497. + /*
  2498. + * we can't break out of this loop or we will leave behind
  2499. + * a huge mess, however, staying here means if your driver
  2500. + * is broken user applications can hang and not be killed.
  2501. + * The solution, fix your driver :-)
  2502. + */
  2503. + if (error) {
  2504. + schedule();
  2505. + error = 0;
  2506. + }
  2507. + } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
  2508. +
  2509. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  2510. +
  2511. + kop->crk_crid = krp->krp_crid; /* device that did the work */
  2512. + if (krp->krp_status != 0) {
  2513. + error = krp->krp_status;
  2514. + goto fail;
  2515. + }
  2516. +
  2517. + for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
  2518. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  2519. + if (size == 0)
  2520. + continue;
  2521. + error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
  2522. + size);
  2523. + if (error)
  2524. + goto fail;
  2525. + }
  2526. +
  2527. +fail:
  2528. + if (krp) {
  2529. + kop->crk_status = krp->krp_status;
  2530. + for (i = 0; i < CRK_MAXPARAM; i++) {
  2531. + if (krp->krp_param[i].crp_p)
  2532. + kfree(krp->krp_param[i].crp_p);
  2533. + }
  2534. + kfree(krp);
  2535. + }
  2536. + return (error);
  2537. +}
  2538. +
  2539. +static int
  2540. +cryptodev_find(struct crypt_find_op *find)
  2541. +{
  2542. + device_t dev;
  2543. +
  2544. + if (find->crid != -1) {
  2545. + dev = crypto_find_device_byhid(find->crid);
  2546. + if (dev == NULL)
  2547. + return (ENOENT);
  2548. + strlcpy(find->name, device_get_nameunit(dev),
  2549. + sizeof(find->name));
  2550. + } else {
  2551. + find->crid = crypto_find_driver(find->name);
  2552. + if (find->crid == -1)
  2553. + return (ENOENT);
  2554. + }
  2555. + return (0);
  2556. +}
  2557. +
  2558. +static struct csession *
  2559. +csefind(struct fcrypt *fcr, u_int ses)
  2560. +{
  2561. + struct csession *cse;
  2562. +
  2563. + dprintk("%s()\n", __FUNCTION__);
  2564. + list_for_each_entry(cse, &fcr->csessions, list)
  2565. + if (cse->ses == ses)
  2566. + return (cse);
  2567. + return (NULL);
  2568. +}
  2569. +
  2570. +static int
  2571. +csedelete(struct fcrypt *fcr, struct csession *cse_del)
  2572. +{
  2573. + struct csession *cse;
  2574. +
  2575. + dprintk("%s()\n", __FUNCTION__);
  2576. + list_for_each_entry(cse, &fcr->csessions, list) {
  2577. + if (cse == cse_del) {
  2578. + list_del(&cse->list);
  2579. + return (1);
  2580. + }
  2581. + }
  2582. + return (0);
  2583. +}
  2584. +
  2585. +static struct csession *
  2586. +cseadd(struct fcrypt *fcr, struct csession *cse)
  2587. +{
  2588. + dprintk("%s()\n", __FUNCTION__);
  2589. + list_add_tail(&cse->list, &fcr->csessions);
  2590. + cse->ses = fcr->sesn++;
  2591. + return (cse);
  2592. +}
  2593. +
  2594. +static struct csession *
  2595. +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
  2596. + struct cryptoini *cria, struct csession_info *info)
  2597. +{
  2598. + struct csession *cse;
  2599. +
  2600. + dprintk("%s()\n", __FUNCTION__);
  2601. + cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
  2602. + if (cse == NULL)
  2603. + return NULL;
  2604. + memset(cse, 0, sizeof(struct csession));
  2605. +
  2606. + INIT_LIST_HEAD(&cse->list);
  2607. + init_waitqueue_head(&cse->waitq);
  2608. +
  2609. + cse->key = crie->cri_key;
  2610. + cse->keylen = crie->cri_klen/8;
  2611. + cse->mackey = cria->cri_key;
  2612. + cse->mackeylen = cria->cri_klen/8;
  2613. + cse->sid = sid;
  2614. + cse->cipher = crie->cri_alg;
  2615. + cse->mac = cria->cri_alg;
  2616. + cse->info = *info;
  2617. + cseadd(fcr, cse);
  2618. + return (cse);
  2619. +}
  2620. +
  2621. +static int
  2622. +csefree(struct csession *cse)
  2623. +{
  2624. + int error;
  2625. +
  2626. + dprintk("%s()\n", __FUNCTION__);
  2627. + error = crypto_freesession(cse->sid);
  2628. + if (cse->key)
  2629. + kfree(cse->key);
  2630. + if (cse->mackey)
  2631. + kfree(cse->mackey);
  2632. + kfree(cse);
  2633. + return(error);
  2634. +}
  2635. +
  2636. +static int
  2637. +cryptodev_ioctl(
  2638. + struct inode *inode,
  2639. + struct file *filp,
  2640. + unsigned int cmd,
  2641. + unsigned long arg)
  2642. +{
  2643. + struct cryptoini cria, crie;
  2644. + struct fcrypt *fcr = filp->private_data;
  2645. + struct csession *cse;
  2646. + struct csession_info info;
  2647. + struct session2_op sop;
  2648. + struct crypt_op cop;
  2649. + struct crypt_kop kop;
  2650. + struct crypt_find_op fop;
  2651. + u_int64_t sid;
  2652. + u_int32_t ses;
  2653. + int feat, fd, error = 0, crid;
  2654. + mm_segment_t fs;
  2655. +
  2656. + dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
  2657. +
  2658. + switch (cmd) {
  2659. +
  2660. + case CRIOGET: {
  2661. + dprintk("%s(CRIOGET)\n", __FUNCTION__);
  2662. + fs = get_fs();
  2663. + set_fs(get_ds());
  2664. + for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
  2665. + if (files_fdtable(current->files)->fd[fd] == filp)
  2666. + break;
  2667. + fd = sys_dup(fd);
  2668. + set_fs(fs);
  2669. + put_user(fd, (int *) arg);
  2670. + return IS_ERR_VALUE(fd) ? fd : 0;
  2671. + }
  2672. +
  2673. +#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
  2674. + case CIOCGSESSION:
  2675. + case CIOCGSESSION2:
  2676. + dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
  2677. + memset(&crie, 0, sizeof(crie));
  2678. + memset(&cria, 0, sizeof(cria));
  2679. + memset(&info, 0, sizeof(info));
  2680. + memset(&sop, 0, sizeof(sop));
  2681. +
  2682. + if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
  2683. + sizeof(struct session_op) : sizeof(sop))) {
  2684. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  2685. + error = EFAULT;
  2686. + goto bail;
  2687. + }
  2688. +
  2689. + switch (sop.cipher) {
  2690. + case 0:
  2691. + dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
  2692. + break;
  2693. + case CRYPTO_NULL_CBC:
  2694. + info.blocksize = NULL_BLOCK_LEN;
  2695. + info.minkey = NULL_MIN_KEY_LEN;
  2696. + info.maxkey = NULL_MAX_KEY_LEN;
  2697. + break;
  2698. + case CRYPTO_DES_CBC:
  2699. + info.blocksize = DES_BLOCK_LEN;
  2700. + info.minkey = DES_MIN_KEY_LEN;
  2701. + info.maxkey = DES_MAX_KEY_LEN;
  2702. + break;
  2703. + case CRYPTO_3DES_CBC:
  2704. + info.blocksize = DES3_BLOCK_LEN;
  2705. + info.minkey = DES3_MIN_KEY_LEN;
  2706. + info.maxkey = DES3_MAX_KEY_LEN;
  2707. + break;
  2708. + case CRYPTO_BLF_CBC:
  2709. + info.blocksize = BLOWFISH_BLOCK_LEN;
  2710. + info.minkey = BLOWFISH_MIN_KEY_LEN;
  2711. + info.maxkey = BLOWFISH_MAX_KEY_LEN;
  2712. + break;
  2713. + case CRYPTO_CAST_CBC:
  2714. + info.blocksize = CAST128_BLOCK_LEN;
  2715. + info.minkey = CAST128_MIN_KEY_LEN;
  2716. + info.maxkey = CAST128_MAX_KEY_LEN;
  2717. + break;
  2718. + case CRYPTO_SKIPJACK_CBC:
  2719. + info.blocksize = SKIPJACK_BLOCK_LEN;
  2720. + info.minkey = SKIPJACK_MIN_KEY_LEN;
  2721. + info.maxkey = SKIPJACK_MAX_KEY_LEN;
  2722. + break;
  2723. + case CRYPTO_AES_CBC:
  2724. + info.blocksize = AES_BLOCK_LEN;
  2725. + info.minkey = AES_MIN_KEY_LEN;
  2726. + info.maxkey = AES_MAX_KEY_LEN;
  2727. + break;
  2728. + case CRYPTO_ARC4:
  2729. + info.blocksize = ARC4_BLOCK_LEN;
  2730. + info.minkey = ARC4_MIN_KEY_LEN;
  2731. + info.maxkey = ARC4_MAX_KEY_LEN;
  2732. + break;
  2733. + case CRYPTO_CAMELLIA_CBC:
  2734. + info.blocksize = CAMELLIA_BLOCK_LEN;
  2735. + info.minkey = CAMELLIA_MIN_KEY_LEN;
  2736. + info.maxkey = CAMELLIA_MAX_KEY_LEN;
  2737. + break;
  2738. + default:
  2739. + dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
  2740. + error = EINVAL;
  2741. + goto bail;
  2742. + }
  2743. +
  2744. + switch (sop.mac) {
  2745. + case 0:
  2746. + dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
  2747. + break;
  2748. + case CRYPTO_NULL_HMAC:
  2749. + info.authsize = NULL_HASH_LEN;
  2750. + break;
  2751. + case CRYPTO_MD5:
  2752. + info.authsize = MD5_HASH_LEN;
  2753. + break;
  2754. + case CRYPTO_SHA1:
  2755. + info.authsize = SHA1_HASH_LEN;
  2756. + break;
  2757. + case CRYPTO_SHA2_256:
  2758. + info.authsize = SHA2_256_HASH_LEN;
  2759. + break;
  2760. + case CRYPTO_SHA2_384:
  2761. + info.authsize = SHA2_384_HASH_LEN;
  2762. + break;
  2763. + case CRYPTO_SHA2_512:
  2764. + info.authsize = SHA2_512_HASH_LEN;
  2765. + break;
  2766. + case CRYPTO_RIPEMD160:
  2767. + info.authsize = RIPEMD160_HASH_LEN;
  2768. + break;
  2769. + case CRYPTO_MD5_HMAC:
  2770. + info.authsize = MD5_HASH_LEN;
  2771. + break;
  2772. + case CRYPTO_SHA1_HMAC:
  2773. + info.authsize = SHA1_HASH_LEN;
  2774. + break;
  2775. + case CRYPTO_SHA2_256_HMAC:
  2776. + info.authsize = SHA2_256_HASH_LEN;
  2777. + break;
  2778. + case CRYPTO_SHA2_384_HMAC:
  2779. + info.authsize = SHA2_384_HASH_LEN;
  2780. + break;
  2781. + case CRYPTO_SHA2_512_HMAC:
  2782. + info.authsize = SHA2_512_HASH_LEN;
  2783. + break;
  2784. + case CRYPTO_RIPEMD160_HMAC:
  2785. + info.authsize = RIPEMD160_HASH_LEN;
  2786. + break;
  2787. + default:
  2788. + dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
  2789. + error = EINVAL;
  2790. + goto bail;
  2791. + }
  2792. +
  2793. + if (info.blocksize) {
  2794. + crie.cri_alg = sop.cipher;
  2795. + crie.cri_klen = sop.keylen * 8;
  2796. + if ((info.maxkey && sop.keylen > info.maxkey) ||
  2797. + sop.keylen < info.minkey) {
  2798. + dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
  2799. + error = EINVAL;
  2800. + goto bail;
  2801. + }
  2802. +
  2803. + crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
  2804. + if (copy_from_user(crie.cri_key, sop.key,
  2805. + crie.cri_klen/8)) {
  2806. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  2807. + error = EFAULT;
  2808. + goto bail;
  2809. + }
  2810. + if (info.authsize)
  2811. + crie.cri_next = &cria;
  2812. + }
  2813. +
  2814. + if (info.authsize) {
  2815. + cria.cri_alg = sop.mac;
  2816. + cria.cri_klen = sop.mackeylen * 8;
  2817. + if ((info.maxkey && sop.mackeylen > info.maxkey) ||
  2818. + sop.keylen < info.minkey) {
  2819. + dprintk("%s(%s) - mackeylen %d\n", __FUNCTION__, CIOCGSESSSTR,
  2820. + sop.mackeylen);
  2821. + error = EINVAL;
  2822. + goto bail;
  2823. + }
  2824. +
  2825. + if (cria.cri_klen) {
  2826. + cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
  2827. + if (copy_from_user(cria.cri_key, sop.mackey,
  2828. + cria.cri_klen / 8)) {
  2829. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  2830. + error = EFAULT;
  2831. + goto bail;
  2832. + }
  2833. + }
  2834. + }
  2835. +
  2836. + /* NB: CIOGSESSION2 has the crid */
  2837. + if (cmd == CIOCGSESSION2) {
  2838. + crid = sop.crid;
  2839. + error = checkcrid(crid);
  2840. + if (error) {
  2841. + dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
  2842. + CIOCGSESSSTR, error);
  2843. + goto bail;
  2844. + }
  2845. + } else {
  2846. + /* allow either HW or SW to be used */
  2847. + crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  2848. + }
  2849. + error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
  2850. + if (error) {
  2851. + dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
  2852. + goto bail;
  2853. + }
  2854. +
  2855. + cse = csecreate(fcr, sid, &crie, &cria, &info);
  2856. + if (cse == NULL) {
  2857. + crypto_freesession(sid);
  2858. + error = EINVAL;
  2859. + dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
  2860. + goto bail;
  2861. + }
  2862. + sop.ses = cse->ses;
  2863. +
  2864. + if (cmd == CIOCGSESSION2) {
  2865. + /* return hardware/driver id */
  2866. + sop.crid = CRYPTO_SESID2HID(cse->sid);
  2867. + }
  2868. +
  2869. + if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
  2870. + sizeof(struct session_op) : sizeof(sop))) {
  2871. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  2872. + error = EFAULT;
  2873. + }
  2874. +bail:
  2875. + if (error) {
  2876. + dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
  2877. + if (crie.cri_key)
  2878. + kfree(crie.cri_key);
  2879. + if (cria.cri_key)
  2880. + kfree(cria.cri_key);
  2881. + }
  2882. + break;
  2883. + case CIOCFSESSION:
  2884. + dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
  2885. + get_user(ses, (uint32_t*)arg);
  2886. + cse = csefind(fcr, ses);
  2887. + if (cse == NULL) {
  2888. + error = EINVAL;
  2889. + dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
  2890. + break;
  2891. + }
  2892. + csedelete(fcr, cse);
  2893. + error = csefree(cse);
  2894. + break;
  2895. + case CIOCCRYPT:
  2896. + dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
  2897. + if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
  2898. + dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
  2899. + error = EFAULT;
  2900. + goto bail;
  2901. + }
  2902. + cse = csefind(fcr, cop.ses);
  2903. + if (cse == NULL) {
  2904. + error = EINVAL;
  2905. + dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
  2906. + break;
  2907. + }
  2908. + error = cryptodev_op(cse, &cop);
  2909. + if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
  2910. + dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
  2911. + error = EFAULT;
  2912. + goto bail;
  2913. + }
  2914. + break;
  2915. + case CIOCKEY:
  2916. + case CIOCKEY2:
  2917. + dprintk("%s(CIOCKEY)\n", __FUNCTION__);
  2918. + if (!crypto_userasymcrypto)
  2919. + return (EPERM); /* XXX compat? */
  2920. + if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
  2921. + dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
  2922. + error = EFAULT;
  2923. + goto bail;
  2924. + }
  2925. + if (cmd == CIOCKEY) {
  2926. + /* NB: crypto core enforces s/w driver use */
  2927. + kop.crk_crid =
  2928. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  2929. + }
  2930. + error = cryptodev_key(&kop);
  2931. + if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
  2932. + dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
  2933. + error = EFAULT;
  2934. + goto bail;
  2935. + }
  2936. + break;
  2937. + case CIOCASYMFEAT:
  2938. + dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
  2939. + if (!crypto_userasymcrypto) {
  2940. + /*
  2941. + * NB: if user asym crypto operations are
  2942. + * not permitted return "no algorithms"
  2943. + * so well-behaved applications will just
  2944. + * fallback to doing them in software.
  2945. + */
  2946. + feat = 0;
  2947. + } else
  2948. + error = crypto_getfeat(&feat);
  2949. + if (!error) {
  2950. + error = copy_to_user((void*)arg, &feat, sizeof(feat));
  2951. + }
  2952. + break;
  2953. + case CIOCFINDDEV:
  2954. + if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
  2955. + dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
  2956. + error = EFAULT;
  2957. + goto bail;
  2958. + }
  2959. + error = cryptodev_find(&fop);
  2960. + if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
  2961. + dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
  2962. + error = EFAULT;
  2963. + goto bail;
  2964. + }
  2965. + break;
  2966. + default:
  2967. + dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
  2968. + error = EINVAL;
  2969. + break;
  2970. + }
  2971. + return(-error);
  2972. +}
  2973. +
  2974. +#ifdef HAVE_UNLOCKED_IOCTL
  2975. +static long
  2976. +cryptodev_unlocked_ioctl(
  2977. + struct file *filp,
  2978. + unsigned int cmd,
  2979. + unsigned long arg)
  2980. +{
  2981. + return cryptodev_ioctl(NULL, filp, cmd, arg);
  2982. +}
  2983. +#endif
  2984. +
  2985. +static int
  2986. +cryptodev_open(struct inode *inode, struct file *filp)
  2987. +{
  2988. + struct fcrypt *fcr;
  2989. +
  2990. + dprintk("%s()\n", __FUNCTION__);
  2991. + if (filp->private_data) {
  2992. + printk("cryptodev: Private data already exists !\n");
  2993. + return(0);
  2994. + }
  2995. +
  2996. + fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
  2997. + if (!fcr) {
  2998. + dprintk("%s() - malloc failed\n", __FUNCTION__);
  2999. + return(-ENOMEM);
  3000. + }
  3001. + memset(fcr, 0, sizeof(*fcr));
  3002. +
  3003. + INIT_LIST_HEAD(&fcr->csessions);
  3004. + filp->private_data = fcr;
  3005. + return(0);
  3006. +}
  3007. +
  3008. +static int
  3009. +cryptodev_release(struct inode *inode, struct file *filp)
  3010. +{
  3011. + struct fcrypt *fcr = filp->private_data;
  3012. + struct csession *cse, *tmp;
  3013. +
  3014. + dprintk("%s()\n", __FUNCTION__);
  3015. + if (!filp) {
  3016. + printk("cryptodev: No private data on release\n");
  3017. + return(0);
  3018. + }
  3019. +
  3020. + list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
  3021. + list_del(&cse->list);
  3022. + (void)csefree(cse);
  3023. + }
  3024. + filp->private_data = NULL;
  3025. + kfree(fcr);
  3026. + return(0);
  3027. +}
  3028. +
  3029. +static struct file_operations cryptodev_fops = {
  3030. + .owner = THIS_MODULE,
  3031. + .open = cryptodev_open,
  3032. + .release = cryptodev_release,
  3033. + .ioctl = cryptodev_ioctl,
  3034. +#ifdef HAVE_UNLOCKED_IOCTL
  3035. + .unlocked_ioctl = cryptodev_unlocked_ioctl,
  3036. +#endif
  3037. +};
  3038. +
  3039. +static struct miscdevice cryptodev = {
  3040. + .minor = CRYPTODEV_MINOR,
  3041. + .name = "crypto",
  3042. + .fops = &cryptodev_fops,
  3043. +};
  3044. +
  3045. +static int __init
  3046. +cryptodev_init(void)
  3047. +{
  3048. + int rc;
  3049. +
  3050. + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
  3051. + rc = misc_register(&cryptodev);
  3052. + if (rc) {
  3053. + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
  3054. + return(rc);
  3055. + }
  3056. +
  3057. + return(0);
  3058. +}
  3059. +
  3060. +static void __exit
  3061. +cryptodev_exit(void)
  3062. +{
  3063. + dprintk("%s()\n", __FUNCTION__);
  3064. + misc_deregister(&cryptodev);
  3065. +}
  3066. +
  3067. +module_init(cryptodev_init);
  3068. +module_exit(cryptodev_exit);
  3069. +
  3070. +MODULE_LICENSE("BSD");
  3071. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  3072. +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
  3073. diff -Nur linux-2.6.27.10.orig/crypto/ocf/cryptodev.h linux-2.6.27.10/crypto/ocf/cryptodev.h
  3074. --- linux-2.6.27.10.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
  3075. +++ linux-2.6.27.10/crypto/ocf/cryptodev.h 2008-12-23 19:31:44.000000000 +0100
  3076. @@ -0,0 +1,478 @@
  3077. +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
  3078. +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
  3079. +
  3080. +/*-
  3081. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  3082. + * Copyright (C) 2006-2007 David McCullough
  3083. + * Copyright (C) 2004-2005 Intel Corporation.
  3084. + * The license and original author are listed below.
  3085. + *
  3086. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  3087. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  3088. + *
  3089. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  3090. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  3091. + * supported the development of this code.
  3092. + *
  3093. + * Copyright (c) 2000 Angelos D. Keromytis
  3094. + *
  3095. + * Permission to use, copy, and modify this software with or without fee
  3096. + * is hereby granted, provided that this entire notice is included in
  3097. + * all source code copies of any software which is or includes a copy or
  3098. + * modification of this software.
  3099. + *
  3100. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  3101. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  3102. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  3103. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  3104. + * PURPOSE.
  3105. + *
  3106. + * Copyright (c) 2001 Theo de Raadt
  3107. + *
  3108. + * Redistribution and use in source and binary forms, with or without
  3109. + * modification, are permitted provided that the following conditions
  3110. + * are met:
  3111. + *
  3112. + * 1. Redistributions of source code must retain the above copyright
  3113. + * notice, this list of conditions and the following disclaimer.
  3114. + * 2. Redistributions in binary form must reproduce the above copyright
  3115. + * notice, this list of conditions and the following disclaimer in the
  3116. + * documentation and/or other materials provided with the distribution.
  3117. + * 3. The name of the author may not be used to endorse or promote products
  3118. + * derived from this software without specific prior written permission.
  3119. + *
  3120. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  3121. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  3122. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  3123. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  3124. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  3125. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  3126. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  3127. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  3128. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  3129. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3130. + *
  3131. + * Effort sponsored in part by the Defense Advanced Research Projects
  3132. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  3133. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  3134. + *
  3135. + */
  3136. +
  3137. +#ifndef _CRYPTO_CRYPTO_H_
  3138. +#define _CRYPTO_CRYPTO_H_
  3139. +
  3140. +/* Some initial values */
  3141. +#define CRYPTO_DRIVERS_INITIAL 4
  3142. +#define CRYPTO_SW_SESSIONS 32
  3143. +
  3144. +/* Hash values */
  3145. +#define NULL_HASH_LEN 0
  3146. +#define MD5_HASH_LEN 16
  3147. +#define SHA1_HASH_LEN 20
  3148. +#define RIPEMD160_HASH_LEN 20
  3149. +#define SHA2_256_HASH_LEN 32
  3150. +#define SHA2_384_HASH_LEN 48
  3151. +#define SHA2_512_HASH_LEN 64
  3152. +#define MD5_KPDK_HASH_LEN 16
  3153. +#define SHA1_KPDK_HASH_LEN 20
  3154. +/* Maximum hash algorithm result length */
  3155. +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
  3156. +
  3157. +/* HMAC values */
  3158. +#define NULL_HMAC_BLOCK_LEN 1
  3159. +#define MD5_HMAC_BLOCK_LEN 64
  3160. +#define SHA1_HMAC_BLOCK_LEN 64
  3161. +#define RIPEMD160_HMAC_BLOCK_LEN 64
  3162. +#define SHA2_256_HMAC_BLOCK_LEN 64
  3163. +#define SHA2_384_HMAC_BLOCK_LEN 128
  3164. +#define SHA2_512_HMAC_BLOCK_LEN 128
  3165. +/* Maximum HMAC block length */
  3166. +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
  3167. +#define HMAC_IPAD_VAL 0x36
  3168. +#define HMAC_OPAD_VAL 0x5C
  3169. +
  3170. +/* Encryption algorithm block sizes */
  3171. +#define NULL_BLOCK_LEN 1
  3172. +#define DES_BLOCK_LEN 8
  3173. +#define DES3_BLOCK_LEN 8
  3174. +#define BLOWFISH_BLOCK_LEN 8
  3175. +#define SKIPJACK_BLOCK_LEN 8
  3176. +#define CAST128_BLOCK_LEN 8
  3177. +#define RIJNDAEL128_BLOCK_LEN 16
  3178. +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
  3179. +#define CAMELLIA_BLOCK_LEN 16
  3180. +#define ARC4_BLOCK_LEN 1
  3181. +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
  3182. +
  3183. +/* Encryption algorithm min and max key sizes */
  3184. +#define NULL_MIN_KEY_LEN 0
  3185. +#define NULL_MAX_KEY_LEN 0
  3186. +#define DES_MIN_KEY_LEN 8
  3187. +#define DES_MAX_KEY_LEN 8
  3188. +#define DES3_MIN_KEY_LEN 24
  3189. +#define DES3_MAX_KEY_LEN 24
  3190. +#define BLOWFISH_MIN_KEY_LEN 4
  3191. +#define BLOWFISH_MAX_KEY_LEN 56
  3192. +#define SKIPJACK_MIN_KEY_LEN 10
  3193. +#define SKIPJACK_MAX_KEY_LEN 10
  3194. +#define CAST128_MIN_KEY_LEN 5
  3195. +#define CAST128_MAX_KEY_LEN 16
  3196. +#define RIJNDAEL128_MIN_KEY_LEN 16
  3197. +#define RIJNDAEL128_MAX_KEY_LEN 32
  3198. +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
  3199. +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
  3200. +#define CAMELLIA_MIN_KEY_LEN 16
  3201. +#define CAMELLIA_MAX_KEY_LEN 32
  3202. +#define ARC4_MIN_KEY_LEN 1
  3203. +#define ARC4_MAX_KEY_LEN 256
  3204. +
  3205. +/* Max size of data that can be processed */
  3206. +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
  3207. +
  3208. +#define CRYPTO_ALGORITHM_MIN 1
  3209. +#define CRYPTO_DES_CBC 1
  3210. +#define CRYPTO_3DES_CBC 2
  3211. +#define CRYPTO_BLF_CBC 3
  3212. +#define CRYPTO_CAST_CBC 4
  3213. +#define CRYPTO_SKIPJACK_CBC 5
  3214. +#define CRYPTO_MD5_HMAC 6
  3215. +#define CRYPTO_SHA1_HMAC 7
  3216. +#define CRYPTO_RIPEMD160_HMAC 8
  3217. +#define CRYPTO_MD5_KPDK 9
  3218. +#define CRYPTO_SHA1_KPDK 10
  3219. +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
  3220. +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
  3221. +#define CRYPTO_ARC4 12
  3222. +#define CRYPTO_MD5 13
  3223. +#define CRYPTO_SHA1 14
  3224. +#define CRYPTO_NULL_HMAC 15
  3225. +#define CRYPTO_NULL_CBC 16
  3226. +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
  3227. +#define CRYPTO_SHA2_256_HMAC 18
  3228. +#define CRYPTO_SHA2_384_HMAC 19
  3229. +#define CRYPTO_SHA2_512_HMAC 20
  3230. +#define CRYPTO_CAMELLIA_CBC 21
  3231. +#define CRYPTO_SHA2_256 22
  3232. +#define CRYPTO_SHA2_384 23
  3233. +#define CRYPTO_SHA2_512 24
  3234. +#define CRYPTO_RIPEMD160 25
  3235. +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
  3236. +
  3237. +/* Algorithm flags */
  3238. +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
  3239. +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
  3240. +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
  3241. +
  3242. +/*
  3243. + * Crypto driver/device flags. They can set in the crid
  3244. + * parameter when creating a session or submitting a key
  3245. + * op to affect the device/driver assigned. If neither
  3246. + * of these are specified then the crid is assumed to hold
  3247. + * the driver id of an existing (and suitable) device that
  3248. + * must be used to satisfy the request.
  3249. + */
  3250. +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
  3251. +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
  3252. +
  3253. +/* NB: deprecated */
  3254. +struct session_op {
  3255. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  3256. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  3257. +
  3258. + u_int32_t keylen; /* cipher key */
  3259. + caddr_t key;
  3260. + int mackeylen; /* mac key */
  3261. + caddr_t mackey;
  3262. +
  3263. + u_int32_t ses; /* returns: session # */
  3264. +};
  3265. +
  3266. +struct session2_op {
  3267. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  3268. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  3269. +
  3270. + u_int32_t keylen; /* cipher key */
  3271. + caddr_t key;
  3272. + int mackeylen; /* mac key */
  3273. + caddr_t mackey;
  3274. +
  3275. + u_int32_t ses; /* returns: session # */
  3276. + int crid; /* driver id + flags (rw) */
  3277. + int pad[4]; /* for future expansion */
  3278. +};
  3279. +
  3280. +struct crypt_op {
  3281. + u_int32_t ses;
  3282. + u_int16_t op; /* i.e. COP_ENCRYPT */
  3283. +#define COP_NONE 0
  3284. +#define COP_ENCRYPT 1
  3285. +#define COP_DECRYPT 2
  3286. + u_int16_t flags;
  3287. +#define COP_F_BATCH 0x0008 /* Batch op if possible */
  3288. + u_int len;
  3289. + caddr_t src, dst; /* become iov[] inside kernel */
  3290. + caddr_t mac; /* must be big enough for chosen MAC */
  3291. + caddr_t iv;
  3292. +};
  3293. +
  3294. +/*
  3295. + * Parameters for looking up a crypto driver/device by
  3296. + * device name or by id. The latter are returned for
  3297. + * created sessions (crid) and completed key operations.
  3298. + */
  3299. +struct crypt_find_op {
  3300. + int crid; /* driver id + flags */
  3301. + char name[32]; /* device/driver name */
  3302. +};
  3303. +
  3304. +/* bignum parameter, in packed bytes, ... */
  3305. +struct crparam {
  3306. + caddr_t crp_p;
  3307. + u_int crp_nbits;
  3308. +};
  3309. +
  3310. +#define CRK_MAXPARAM 8
  3311. +
  3312. +struct crypt_kop {
  3313. + u_int crk_op; /* ie. CRK_MOD_EXP or other */
  3314. + u_int crk_status; /* return status */
  3315. + u_short crk_iparams; /* # of input parameters */
  3316. + u_short crk_oparams; /* # of output parameters */
  3317. + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
  3318. + struct crparam crk_param[CRK_MAXPARAM];
  3319. +};
  3320. +#define CRK_ALGORITM_MIN 0
  3321. +#define CRK_MOD_EXP 0
  3322. +#define CRK_MOD_EXP_CRT 1
  3323. +#define CRK_DSA_SIGN 2
  3324. +#define CRK_DSA_VERIFY 3
  3325. +#define CRK_DH_COMPUTE_KEY 4
  3326. +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
  3327. +
  3328. +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
  3329. +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
  3330. +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
  3331. +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
  3332. +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
  3333. +
  3334. +/*
  3335. + * done against open of /dev/crypto, to get a cloned descriptor.
  3336. + * Please use F_SETFD against the cloned descriptor.
  3337. + */
  3338. +#define CRIOGET _IOWR('c', 100, u_int32_t)
  3339. +#define CRIOASYMFEAT CIOCASYMFEAT
  3340. +#define CRIOFINDDEV CIOCFINDDEV
  3341. +
  3342. +/* the following are done against the cloned descriptor */
  3343. +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
  3344. +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
  3345. +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
  3346. +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
  3347. +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
  3348. +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
  3349. +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
  3350. +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
  3351. +
  3352. +struct cryptotstat {
  3353. + struct timespec acc; /* total accumulated time */
  3354. + struct timespec min; /* min time */
  3355. + struct timespec max; /* max time */
  3356. + u_int32_t count; /* number of observations */
  3357. +};
  3358. +
  3359. +struct cryptostats {
  3360. + u_int32_t cs_ops; /* symmetric crypto ops submitted */
  3361. + u_int32_t cs_errs; /* symmetric crypto ops that failed */
  3362. + u_int32_t cs_kops; /* asymetric/key ops submitted */
  3363. + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
  3364. + u_int32_t cs_intrs; /* crypto swi thread activations */
  3365. + u_int32_t cs_rets; /* crypto return thread activations */
  3366. + u_int32_t cs_blocks; /* symmetric op driver block */
  3367. + u_int32_t cs_kblocks; /* symmetric op driver block */
  3368. + /*
  3369. + * When CRYPTO_TIMING is defined at compile time and the
  3370. + * sysctl debug.crypto is set to 1, the crypto system will
  3371. + * accumulate statistics about how long it takes to process
  3372. + * crypto requests at various points during processing.
  3373. + */
  3374. + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
  3375. + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
  3376. + struct cryptotstat cs_cb; /* crypto_done -> callback */
  3377. + struct cryptotstat cs_finis; /* callback -> callback return */
  3378. +
  3379. + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
  3380. +};
  3381. +
  3382. +#ifdef __KERNEL__
  3383. +
  3384. +/* Standard initialization structure beginning */
  3385. +struct cryptoini {
  3386. + int cri_alg; /* Algorithm to use */
  3387. + int cri_klen; /* Key length, in bits */
  3388. + int cri_mlen; /* Number of bytes we want from the
  3389. + entire hash. 0 means all. */
  3390. + caddr_t cri_key; /* key to use */
  3391. + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
  3392. + struct cryptoini *cri_next;
  3393. +};
  3394. +
  3395. +/* Describe boundaries of a single crypto operation */
  3396. +struct cryptodesc {
  3397. + int crd_skip; /* How many bytes to ignore from start */
  3398. + int crd_len; /* How many bytes to process */
  3399. + int crd_inject; /* Where to inject results, if applicable */
  3400. + int crd_flags;
  3401. +
  3402. +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
  3403. +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
  3404. + place, so don't copy. */
  3405. +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
  3406. +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
  3407. +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
  3408. +#define CRD_F_COMP 0x0f /* Set when doing compression */
  3409. +
  3410. + struct cryptoini CRD_INI; /* Initialization/context data */
  3411. +#define crd_iv CRD_INI.cri_iv
  3412. +#define crd_key CRD_INI.cri_key
  3413. +#define crd_alg CRD_INI.cri_alg
  3414. +#define crd_klen CRD_INI.cri_klen
  3415. +
  3416. + struct cryptodesc *crd_next;
  3417. +};
  3418. +
  3419. +/* Structure describing complete operation */
  3420. +struct cryptop {
  3421. + struct list_head crp_next;
  3422. + wait_queue_head_t crp_waitq;
  3423. +
  3424. + u_int64_t crp_sid; /* Session ID */
  3425. + int crp_ilen; /* Input data total length */
  3426. + int crp_olen; /* Result total length */
  3427. +
  3428. + int crp_etype; /*
  3429. + * Error type (zero means no error).
  3430. + * All error codes except EAGAIN
  3431. + * indicate possible data corruption (as in,
  3432. + * the data have been touched). On all
  3433. + * errors, the crp_sid may have changed
  3434. + * (reset to a new one), so the caller
  3435. + * should always check and use the new
  3436. + * value on future requests.
  3437. + */
  3438. + int crp_flags;
  3439. +
  3440. +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
  3441. +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
  3442. +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
  3443. +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
  3444. +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
  3445. +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
  3446. +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
  3447. +
  3448. + caddr_t crp_buf; /* Data to be processed */
  3449. + caddr_t crp_opaque; /* Opaque pointer, passed along */
  3450. + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
  3451. +
  3452. + int (*crp_callback)(struct cryptop *); /* Callback function */
  3453. +};
  3454. +
  3455. +#define CRYPTO_BUF_CONTIG 0x0
  3456. +#define CRYPTO_BUF_IOV 0x1
  3457. +#define CRYPTO_BUF_SKBUF 0x2
  3458. +
  3459. +#define CRYPTO_OP_DECRYPT 0x0
  3460. +#define CRYPTO_OP_ENCRYPT 0x1
  3461. +
  3462. +/*
  3463. + * Hints passed to process methods.
  3464. + */
  3465. +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
  3466. +
  3467. +struct cryptkop {
  3468. + struct list_head krp_next;
  3469. + wait_queue_head_t krp_waitq;
  3470. +
  3471. + int krp_flags;
  3472. +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
  3473. +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
  3474. +
  3475. + u_int krp_op; /* ie. CRK_MOD_EXP or other */
  3476. + u_int krp_status; /* return status */
  3477. + u_short krp_iparams; /* # of input parameters */
  3478. + u_short krp_oparams; /* # of output parameters */
  3479. + u_int krp_crid; /* desired device, etc. */
  3480. + u_int32_t krp_hid;
  3481. + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
  3482. + int (*krp_callback)(struct cryptkop *);
  3483. +};
  3484. +
  3485. +#include <ocf-compat.h>
  3486. +
  3487. +/*
  3488. + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
  3489. + * is a driver-private session identifier. The upper 32 bits contain a
  3490. + * "hardware id" used by the core crypto code to identify the driver and
  3491. + * a copy of the driver's capabilities that can be used by client code to
  3492. + * optimize operation.
  3493. + */
  3494. +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
  3495. +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
  3496. +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
  3497. +
  3498. +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
  3499. +extern int crypto_freesession(u_int64_t sid);
  3500. +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
  3501. +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
  3502. +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
  3503. +extern int32_t crypto_get_driverid(device_t dev, int flags);
  3504. +extern int crypto_find_driver(const char *);
  3505. +extern device_t crypto_find_device_byhid(int hid);
  3506. +extern int crypto_getcaps(int hid);
  3507. +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  3508. + u_int32_t flags);
  3509. +extern int crypto_kregister(u_int32_t, int, u_int32_t);
  3510. +extern int crypto_unregister(u_int32_t driverid, int alg);
  3511. +extern int crypto_unregister_all(u_int32_t driverid);
  3512. +extern int crypto_dispatch(struct cryptop *crp);
  3513. +extern int crypto_kdispatch(struct cryptkop *);
  3514. +#define CRYPTO_SYMQ 0x1
  3515. +#define CRYPTO_ASYMQ 0x2
  3516. +extern int crypto_unblock(u_int32_t, int);
  3517. +extern void crypto_done(struct cryptop *crp);
  3518. +extern void crypto_kdone(struct cryptkop *);
  3519. +extern int crypto_getfeat(int *);
  3520. +
  3521. +extern void crypto_freereq(struct cryptop *crp);
  3522. +extern struct cryptop *crypto_getreq(int num);
  3523. +
  3524. +extern int crypto_usercrypto; /* userland may do crypto requests */
  3525. +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
  3526. +extern int crypto_devallowsoft; /* only use hardware crypto */
  3527. +
  3528. +/*
  3529. + * random number support, crypto_unregister_all will unregister
  3530. + */
  3531. +extern int crypto_rregister(u_int32_t driverid,
  3532. + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
  3533. +extern int crypto_runregister_all(u_int32_t driverid);
  3534. +
  3535. +/*
  3536. + * Crypto-related utility routines used mainly by drivers.
  3537. + *
  3538. + * XXX these don't really belong here; but for now they're
  3539. + * kept apart from the rest of the system.
  3540. + */
  3541. +struct uio;
  3542. +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
  3543. +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
  3544. +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
  3545. +
  3546. +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
  3547. + caddr_t in);
  3548. +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
  3549. + caddr_t out);
  3550. +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
  3551. + int (*f)(void *, void *, u_int), void *arg);
  3552. +
  3553. +#endif /* __KERNEL__ */
  3554. +#endif /* _CRYPTO_CRYPTO_H_ */
  3555. diff -Nur linux-2.6.27.10.orig/crypto/ocf/cryptosoft.c linux-2.6.27.10/crypto/ocf/cryptosoft.c
  3556. --- linux-2.6.27.10.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
  3557. +++ linux-2.6.27.10/crypto/ocf/cryptosoft.c 2008-12-23 19:31:44.000000000 +0100
  3558. @@ -0,0 +1,898 @@
  3559. +/*
  3560. + * An OCF module that uses the linux kernel cryptoapi, based on the
  3561. + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
  3562. + * but is mostly unrecognisable,
  3563. + *
  3564. + * Written by David McCullough <david_mccullough@securecomputing.com>
  3565. + * Copyright (C) 2004-2007 David McCullough
  3566. + * Copyright (C) 2004-2005 Intel Corporation.
  3567. + *
  3568. + * LICENSE TERMS
  3569. + *
  3570. + * The free distribution and use of this software in both source and binary
  3571. + * form is allowed (with or without changes) provided that:
  3572. + *
  3573. + * 1. distributions of this source code include the above copyright
  3574. + * notice, this list of conditions and the following disclaimer;
  3575. + *
  3576. + * 2. distributions in binary form include the above copyright
  3577. + * notice, this list of conditions and the following disclaimer
  3578. + * in the documentation and/or other associated materials;
  3579. + *
  3580. + * 3. the copyright holder's name is not used to endorse products
  3581. + * built using this software without specific written permission.
  3582. + *
  3583. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  3584. + * may be distributed under the terms of the GNU General Public License (GPL),
  3585. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  3586. + *
  3587. + * DISCLAIMER
  3588. + *
  3589. + * This software is provided 'as is' with no explicit or implied warranties
  3590. + * in respect of its properties, including, but not limited to, correctness
  3591. + * and/or fitness for purpose.
  3592. + * ---------------------------------------------------------------------------
  3593. + */
  3594. +
  3595. +#ifndef AUTOCONF_INCLUDED
  3596. +#include <linux/config.h>
  3597. +#endif
  3598. +#include <linux/module.h>
  3599. +#include <linux/init.h>
  3600. +#include <linux/list.h>
  3601. +#include <linux/slab.h>
  3602. +#include <linux/sched.h>
  3603. +#include <linux/wait.h>
  3604. +#include <linux/crypto.h>
  3605. +#include <linux/mm.h>
  3606. +#include <linux/skbuff.h>
  3607. +#include <linux/random.h>
  3608. +#include <linux/scatterlist.h>
  3609. +
  3610. +#include <cryptodev.h>
  3611. +#include <uio.h>
  3612. +
  3613. +struct {
  3614. + softc_device_decl sc_dev;
  3615. +} swcr_softc;
  3616. +
  3617. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  3618. +
  3619. +/* Software session entry */
  3620. +
  3621. +#define SW_TYPE_CIPHER 0
  3622. +#define SW_TYPE_HMAC 1
  3623. +#define SW_TYPE_AUTH2 2
  3624. +#define SW_TYPE_HASH 3
  3625. +#define SW_TYPE_COMP 4
  3626. +#define SW_TYPE_BLKCIPHER 5
  3627. +
  3628. +struct swcr_data {
  3629. + int sw_type;
  3630. + int sw_alg;
  3631. + struct crypto_tfm *sw_tfm;
  3632. + union {
  3633. + struct {
  3634. + char *sw_key;
  3635. + int sw_klen;
  3636. + int sw_mlen;
  3637. + } hmac;
  3638. + void *sw_comp_buf;
  3639. + } u;
  3640. + struct swcr_data *sw_next;
  3641. +};
  3642. +
  3643. +#ifndef CRYPTO_TFM_MODE_CBC
  3644. +/*
  3645. + * As of linux-2.6.21 this is no longer defined, and presumably no longer
  3646. + * needed to be passed into the crypto core code.
  3647. + */
  3648. +#define CRYPTO_TFM_MODE_CBC 0
  3649. +#define CRYPTO_TFM_MODE_ECB 0
  3650. +#endif
  3651. +
  3652. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  3653. + /*
  3654. + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
  3655. + * API into old API.
  3656. + */
  3657. +
  3658. + /* Symmetric/Block Cipher */
  3659. + struct blkcipher_desc
  3660. + {
  3661. + struct crypto_tfm *tfm;
  3662. + void *info;
  3663. + };
  3664. + #define ecb(X) #X
  3665. + #define cbc(X) #X
  3666. + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
  3667. + #define crypto_blkcipher_cast(X) X
  3668. + #define crypto_blkcipher_tfm(X) X
  3669. + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
  3670. + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
  3671. + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
  3672. + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
  3673. + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
  3674. + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  3675. + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
  3676. + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  3677. +
  3678. + /* Hash/HMAC/Digest */
  3679. + struct hash_desc
  3680. + {
  3681. + struct crypto_tfm *tfm;
  3682. + };
  3683. + #define hmac(X) #X
  3684. + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
  3685. + #define crypto_hash_cast(X) X
  3686. + #define crypto_hash_tfm(X) X
  3687. + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
  3688. + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
  3689. + #define crypto_hash_digest(W, X, Y, Z) \
  3690. + crypto_digest_digest((W)->tfm, X, sg_num, Z)
  3691. +
  3692. + /* Asymmetric Cipher */
  3693. + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
  3694. +
  3695. + /* Compression */
  3696. + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
  3697. + #define crypto_comp_tfm(X) X
  3698. + #define crypto_comp_cast(X) X
  3699. + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
  3700. +#else
  3701. + #define ecb(X) "ecb(" #X ")"
  3702. + #define cbc(X) "cbc(" #X ")"
  3703. + #define hmac(X) "hmac(" #X ")"
  3704. +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  3705. +
  3706. +struct crypto_details
  3707. +{
  3708. + char *alg_name;
  3709. + int mode;
  3710. + int sw_type;
  3711. +};
  3712. +
  3713. +/*
  3714. + * This needs to be kept updated with CRYPTO_xxx list (cryptodev.h).
  3715. + * If the Algorithm is not supported, then insert a {NULL, 0, 0} entry.
  3716. + *
  3717. + * IMPORTANT: The index to the array IS CRYPTO_xxx.
  3718. + */
  3719. +static struct crypto_details crypto_details[CRYPTO_ALGORITHM_MAX + 1] = {
  3720. + { NULL, 0, 0 },
  3721. + /* CRYPTO_xxx index starts at 1 */
  3722. + { cbc(des), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3723. + { cbc(des3_ede), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3724. + { cbc(blowfish), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3725. + { cbc(cast5), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3726. + { cbc(skipjack), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3727. + { hmac(md5), 0, SW_TYPE_HMAC },
  3728. + { hmac(sha1), 0, SW_TYPE_HMAC },
  3729. + { hmac(ripemd160), 0, SW_TYPE_HMAC },
  3730. + { "md5-kpdk??", 0, SW_TYPE_HASH },
  3731. + { "sha1-kpdk??", 0, SW_TYPE_HASH },
  3732. + { cbc(aes), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3733. + { ecb(arc4), CRYPTO_TFM_MODE_ECB, SW_TYPE_BLKCIPHER },
  3734. + { "md5", 0, SW_TYPE_HASH },
  3735. + { "sha1", 0, SW_TYPE_HASH },
  3736. + { hmac(digest_null), 0, SW_TYPE_HMAC },
  3737. + { cbc(cipher_null), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3738. + { "deflate", 0, SW_TYPE_COMP },
  3739. + { hmac(sha256), 0, SW_TYPE_HMAC },
  3740. + { hmac(sha384), 0, SW_TYPE_HMAC },
  3741. + { hmac(sha512), 0, SW_TYPE_HMAC },
  3742. + { cbc(camellia), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  3743. + { "sha256", 0, SW_TYPE_HASH },
  3744. + { "sha384", 0, SW_TYPE_HASH },
  3745. + { "sha512", 0, SW_TYPE_HASH },
  3746. + { "ripemd160", 0, SW_TYPE_HASH },
  3747. +};
  3748. +
  3749. +int32_t swcr_id = -1;
  3750. +module_param(swcr_id, int, 0444);
  3751. +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
  3752. +
  3753. +int swcr_fail_if_compression_grows = 1;
  3754. +module_param(swcr_fail_if_compression_grows, int, 0644);
  3755. +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
  3756. + "Treat compression that results in more data as a failure");
  3757. +
  3758. +static struct swcr_data **swcr_sessions = NULL;
  3759. +static u_int32_t swcr_sesnum = 0;
  3760. +
  3761. +static int swcr_process(device_t, struct cryptop *, int);
  3762. +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
  3763. +static int swcr_freesession(device_t, u_int64_t);
  3764. +
  3765. +static device_method_t swcr_methods = {
  3766. + /* crypto device methods */
  3767. + DEVMETHOD(cryptodev_newsession, swcr_newsession),
  3768. + DEVMETHOD(cryptodev_freesession,swcr_freesession),
  3769. + DEVMETHOD(cryptodev_process, swcr_process),
  3770. +};
  3771. +
  3772. +#define debug swcr_debug
  3773. +int swcr_debug = 0;
  3774. +module_param(swcr_debug, int, 0644);
  3775. +MODULE_PARM_DESC(swcr_debug, "Enable debug");
  3776. +
  3777. +/*
  3778. + * Generate a new software session.
  3779. + */
  3780. +static int
  3781. +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  3782. +{
  3783. + struct swcr_data **swd;
  3784. + u_int32_t i;
  3785. + int error;
  3786. + char *algo;
  3787. + int mode, sw_type;
  3788. +
  3789. + dprintk("%s()\n", __FUNCTION__);
  3790. + if (sid == NULL || cri == NULL) {
  3791. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  3792. + return EINVAL;
  3793. + }
  3794. +
  3795. + if (swcr_sessions) {
  3796. + for (i = 1; i < swcr_sesnum; i++)
  3797. + if (swcr_sessions[i] == NULL)
  3798. + break;
  3799. + } else
  3800. + i = 1; /* NB: to silence compiler warning */
  3801. +
  3802. + if (swcr_sessions == NULL || i == swcr_sesnum) {
  3803. + if (swcr_sessions == NULL) {
  3804. + i = 1; /* We leave swcr_sessions[0] empty */
  3805. + swcr_sesnum = CRYPTO_SW_SESSIONS;
  3806. + } else
  3807. + swcr_sesnum *= 2;
  3808. +
  3809. + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
  3810. + if (swd == NULL) {
  3811. + /* Reset session number */
  3812. + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  3813. + swcr_sesnum = 0;
  3814. + else
  3815. + swcr_sesnum /= 2;
  3816. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  3817. + return ENOBUFS;
  3818. + }
  3819. + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
  3820. +
  3821. + /* Copy existing sessions */
  3822. + if (swcr_sessions) {
  3823. + memcpy(swd, swcr_sessions,
  3824. + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  3825. + kfree(swcr_sessions);
  3826. + }
  3827. +
  3828. + swcr_sessions = swd;
  3829. + }
  3830. +
  3831. + swd = &swcr_sessions[i];
  3832. + *sid = i;
  3833. +
  3834. + while (cri) {
  3835. + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
  3836. + SLAB_ATOMIC);
  3837. + if (*swd == NULL) {
  3838. + swcr_freesession(NULL, i);
  3839. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  3840. + return ENOBUFS;
  3841. + }
  3842. + memset(*swd, 0, sizeof(struct swcr_data));
  3843. +
  3844. + if (cri->cri_alg > CRYPTO_ALGORITHM_MAX) {
  3845. + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
  3846. + swcr_freesession(NULL, i);
  3847. + return EINVAL;
  3848. + }
  3849. +
  3850. + algo = crypto_details[cri->cri_alg].alg_name;
  3851. + if (!algo || !*algo) {
  3852. + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
  3853. + swcr_freesession(NULL, i);
  3854. + return EINVAL;
  3855. + }
  3856. +
  3857. + mode = crypto_details[cri->cri_alg].mode;
  3858. + sw_type = crypto_details[cri->cri_alg].sw_type;
  3859. +
  3860. + /* Algorithm specific configuration */
  3861. + switch (cri->cri_alg) {
  3862. + case CRYPTO_NULL_CBC:
  3863. + cri->cri_klen = 0; /* make it work with crypto API */
  3864. + break;
  3865. + default:
  3866. + break;
  3867. + }
  3868. +
  3869. + if (sw_type == SW_TYPE_BLKCIPHER) {
  3870. + dprintk("%s crypto_alloc_blkcipher(%s, 0x%x)\n", __FUNCTION__,
  3871. + algo, mode);
  3872. +
  3873. + (*swd)->sw_tfm = crypto_blkcipher_tfm(
  3874. + crypto_alloc_blkcipher(algo, 0,
  3875. + CRYPTO_ALG_ASYNC));
  3876. + if (!(*swd)->sw_tfm) {
  3877. + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s,0x%x)\n",
  3878. + algo,mode);
  3879. + swcr_freesession(NULL, i);
  3880. + return EINVAL;
  3881. + }
  3882. +
  3883. + if (debug) {
  3884. + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
  3885. + __FUNCTION__,cri->cri_klen,(cri->cri_klen + 7)/8);
  3886. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  3887. + {
  3888. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",cri->cri_key[i]);
  3889. + }
  3890. + dprintk("\n");
  3891. + }
  3892. + error = crypto_blkcipher_setkey(
  3893. + crypto_blkcipher_cast((*swd)->sw_tfm), cri->cri_key,
  3894. + (cri->cri_klen + 7) / 8);
  3895. + if (error) {
  3896. + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
  3897. + (*swd)->sw_tfm->crt_flags);
  3898. + swcr_freesession(NULL, i);
  3899. + return error;
  3900. + }
  3901. + } else if (sw_type == SW_TYPE_HMAC || sw_type == SW_TYPE_HASH) {
  3902. + dprintk("%s crypto_alloc_hash(%s, 0x%x)\n", __FUNCTION__,
  3903. + algo, mode);
  3904. +
  3905. + (*swd)->sw_tfm = crypto_hash_tfm(
  3906. + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
  3907. +
  3908. + if (!(*swd)->sw_tfm) {
  3909. + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
  3910. + algo, mode);
  3911. + swcr_freesession(NULL, i);
  3912. + return EINVAL;
  3913. + }
  3914. +
  3915. + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
  3916. + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
  3917. + SLAB_ATOMIC);
  3918. + if ((*swd)->u.hmac.sw_key == NULL) {
  3919. + swcr_freesession(NULL, i);
  3920. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  3921. + return ENOBUFS;
  3922. + }
  3923. + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
  3924. + if (cri->cri_mlen) {
  3925. + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
  3926. + } else {
  3927. + (*swd)->u.hmac.sw_mlen =
  3928. + crypto_hash_digestsize(
  3929. + crypto_hash_cast((*swd)->sw_tfm));
  3930. + }
  3931. + } else if (sw_type == SW_TYPE_COMP) {
  3932. + (*swd)->sw_tfm = crypto_comp_tfm(
  3933. + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
  3934. + if (!(*swd)->sw_tfm) {
  3935. + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
  3936. + algo, mode);
  3937. + swcr_freesession(NULL, i);
  3938. + return EINVAL;
  3939. + }
  3940. + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
  3941. + if ((*swd)->u.sw_comp_buf == NULL) {
  3942. + swcr_freesession(NULL, i);
  3943. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  3944. + return ENOBUFS;
  3945. + }
  3946. + } else {
  3947. + printk("cryptosoft: Unhandled sw_type %d\n", sw_type);
  3948. + swcr_freesession(NULL, i);
  3949. + return EINVAL;
  3950. + }
  3951. +
  3952. + (*swd)->sw_alg = cri->cri_alg;
  3953. + (*swd)->sw_type = sw_type;
  3954. +
  3955. + cri = cri->cri_next;
  3956. + swd = &((*swd)->sw_next);
  3957. + }
  3958. + return 0;
  3959. +}
  3960. +
  3961. +/*
  3962. + * Free a session.
  3963. + */
  3964. +static int
  3965. +swcr_freesession(device_t dev, u_int64_t tid)
  3966. +{
  3967. + struct swcr_data *swd;
  3968. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  3969. +
  3970. + dprintk("%s()\n", __FUNCTION__);
  3971. + if (sid > swcr_sesnum || swcr_sessions == NULL ||
  3972. + swcr_sessions[sid] == NULL) {
  3973. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  3974. + return(EINVAL);
  3975. + }
  3976. +
  3977. + /* Silently accept and return */
  3978. + if (sid == 0)
  3979. + return(0);
  3980. +
  3981. + while ((swd = swcr_sessions[sid]) != NULL) {
  3982. + swcr_sessions[sid] = swd->sw_next;
  3983. + if (swd->sw_tfm)
  3984. + crypto_free_tfm(swd->sw_tfm);
  3985. + if (swd->sw_type == SW_TYPE_COMP) {
  3986. + if (swd->u.sw_comp_buf)
  3987. + kfree(swd->u.sw_comp_buf);
  3988. + } else {
  3989. + if (swd->u.hmac.sw_key)
  3990. + kfree(swd->u.hmac.sw_key);
  3991. + }
  3992. + kfree(swd);
  3993. + }
  3994. + return 0;
  3995. +}
  3996. +
  3997. +/*
  3998. + * Process a software request.
  3999. + */
  4000. +static int
  4001. +swcr_process(device_t dev, struct cryptop *crp, int hint)
  4002. +{
  4003. + struct cryptodesc *crd;
  4004. + struct swcr_data *sw;
  4005. + u_int32_t lid;
  4006. +#define SCATTERLIST_MAX 16
  4007. + struct scatterlist sg[SCATTERLIST_MAX];
  4008. + int sg_num, sg_len, skip;
  4009. + struct sk_buff *skb = NULL;
  4010. + struct uio *uiop = NULL;
  4011. +
  4012. + dprintk("%s()\n", __FUNCTION__);
  4013. + /* Sanity check */
  4014. + if (crp == NULL) {
  4015. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4016. + return EINVAL;
  4017. + }
  4018. +
  4019. + crp->crp_etype = 0;
  4020. +
  4021. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  4022. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4023. + crp->crp_etype = EINVAL;
  4024. + goto done;
  4025. + }
  4026. +
  4027. + lid = crp->crp_sid & 0xffffffff;
  4028. + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
  4029. + swcr_sessions[lid] == NULL) {
  4030. + crp->crp_etype = ENOENT;
  4031. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  4032. + goto done;
  4033. + }
  4034. +
  4035. + /*
  4036. + * do some error checking outside of the loop for SKB and IOV processing
  4037. + * this leaves us with valid skb or uiop pointers for later
  4038. + */
  4039. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  4040. + skb = (struct sk_buff *) crp->crp_buf;
  4041. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  4042. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  4043. + skb_shinfo(skb)->nr_frags);
  4044. + goto done;
  4045. + }
  4046. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  4047. + uiop = (struct uio *) crp->crp_buf;
  4048. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  4049. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  4050. + uiop->uio_iovcnt);
  4051. + goto done;
  4052. + }
  4053. + }
  4054. +
  4055. + /* Go through crypto descriptors, processing as we go */
  4056. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  4057. + /*
  4058. + * Find the crypto context.
  4059. + *
  4060. + * XXX Note that the logic here prevents us from having
  4061. + * XXX the same algorithm multiple times in a session
  4062. + * XXX (or rather, we can but it won't give us the right
  4063. + * XXX results). To do that, we'd need some way of differentiating
  4064. + * XXX between the various instances of an algorithm (so we can
  4065. + * XXX locate the correct crypto context).
  4066. + */
  4067. + for (sw = swcr_sessions[lid]; sw && sw->sw_alg != crd->crd_alg;
  4068. + sw = sw->sw_next)
  4069. + ;
  4070. +
  4071. + /* No such context ? */
  4072. + if (sw == NULL) {
  4073. + crp->crp_etype = EINVAL;
  4074. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4075. + goto done;
  4076. + }
  4077. +
  4078. + skip = crd->crd_skip;
  4079. +
  4080. + /*
  4081. + * setup the SG list skip from the start of the buffer
  4082. + */
  4083. + memset(sg, 0, sizeof(sg));
  4084. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  4085. + int i, len;
  4086. +
  4087. + sg_num = 0;
  4088. + sg_len = 0;
  4089. +
  4090. + if (skip < skb_headlen(skb)) {
  4091. + len = skb_headlen(skb) - skip;
  4092. + if (len + sg_len > crd->crd_len)
  4093. + len = crd->crd_len - sg_len;
  4094. + sg_set_page(&sg[sg_num],
  4095. + virt_to_page(skb->data + skip), len,
  4096. + offset_in_page(skb->data + skip));
  4097. + sg_len += len;
  4098. + sg_num++;
  4099. + skip = 0;
  4100. + } else
  4101. + skip -= skb_headlen(skb);
  4102. +
  4103. + for (i = 0; sg_len < crd->crd_len &&
  4104. + i < skb_shinfo(skb)->nr_frags &&
  4105. + sg_num < SCATTERLIST_MAX; i++) {
  4106. + if (skip < skb_shinfo(skb)->frags[i].size) {
  4107. + len = skb_shinfo(skb)->frags[i].size - skip;
  4108. + if (len + sg_len > crd->crd_len)
  4109. + len = crd->crd_len - sg_len;
  4110. + sg_set_page(&sg[sg_num],
  4111. + skb_shinfo(skb)->frags[i].page,
  4112. + len,
  4113. + skb_shinfo(skb)->frags[i].page_offset + skip);
  4114. + sg_len += len;
  4115. + sg_num++;
  4116. + skip = 0;
  4117. + } else
  4118. + skip -= skb_shinfo(skb)->frags[i].size;
  4119. + }
  4120. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  4121. + int len;
  4122. +
  4123. + sg_len = 0;
  4124. + for (sg_num = 0; sg_len <= crd->crd_len &&
  4125. + sg_num < uiop->uio_iovcnt &&
  4126. + sg_num < SCATTERLIST_MAX; sg_num++) {
  4127. + if (skip <= uiop->uio_iov[sg_num].iov_len) {
  4128. + len = uiop->uio_iov[sg_num].iov_len - skip;
  4129. + if (len + sg_len > crd->crd_len)
  4130. + len = crd->crd_len - sg_len;
  4131. + sg_set_page(&sg[sg_num],
  4132. + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
  4133. + len,
  4134. + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
  4135. + sg_len += len;
  4136. + skip = 0;
  4137. + } else
  4138. + skip -= uiop->uio_iov[sg_num].iov_len;
  4139. + }
  4140. + } else {
  4141. + sg_len = (crp->crp_ilen - skip);
  4142. + if (sg_len > crd->crd_len)
  4143. + sg_len = crd->crd_len;
  4144. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip),
  4145. + sg_len, offset_in_page(crp->crp_buf + skip));
  4146. + sg_num = 1;
  4147. + }
  4148. +
  4149. +
  4150. + switch (sw->sw_type) {
  4151. + case SW_TYPE_BLKCIPHER: {
  4152. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  4153. + unsigned char *ivp = iv;
  4154. + int ivsize =
  4155. + crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
  4156. + struct blkcipher_desc desc;
  4157. +
  4158. + if (sg_len < crypto_blkcipher_blocksize(
  4159. + crypto_blkcipher_cast(sw->sw_tfm))) {
  4160. + crp->crp_etype = EINVAL;
  4161. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  4162. + sg_len, crypto_blkcipher_blocksize(
  4163. + crypto_blkcipher_cast(sw->sw_tfm)));
  4164. + goto done;
  4165. + }
  4166. +
  4167. + if (ivsize > sizeof(iv)) {
  4168. + crp->crp_etype = EINVAL;
  4169. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4170. + goto done;
  4171. + }
  4172. +
  4173. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  4174. + int i, error;
  4175. +
  4176. + if (debug) {
  4177. + dprintk("%s key:", __FUNCTION__);
  4178. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  4179. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  4180. + crd->crd_key[i]);
  4181. + dprintk("\n");
  4182. + }
  4183. + error = crypto_blkcipher_setkey(
  4184. + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
  4185. + (crd->crd_klen + 7) / 8);
  4186. + if (error) {
  4187. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  4188. + error, sw->sw_tfm->crt_flags);
  4189. + crp->crp_etype = -error;
  4190. + }
  4191. + }
  4192. +
  4193. + memset(&desc, 0, sizeof(desc));
  4194. + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
  4195. +
  4196. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  4197. +
  4198. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  4199. + ivp = crd->crd_iv;
  4200. + } else {
  4201. + get_random_bytes(ivp, ivsize);
  4202. + }
  4203. + /*
  4204. + * do we have to copy the IV back to the buffer ?
  4205. + */
  4206. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  4207. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  4208. + crd->crd_inject, ivsize, (caddr_t)ivp);
  4209. + }
  4210. + desc.info = ivp;
  4211. + crypto_blkcipher_encrypt_iv(&desc, sg, sg, sg_len);
  4212. +
  4213. + } else { /*decrypt */
  4214. +
  4215. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  4216. + ivp = crd->crd_iv;
  4217. + } else {
  4218. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  4219. + crd->crd_inject, ivsize, (caddr_t)ivp);
  4220. + }
  4221. + desc.info = ivp;
  4222. + crypto_blkcipher_decrypt_iv(&desc, sg, sg, sg_len);
  4223. + }
  4224. + } break;
  4225. + case SW_TYPE_HMAC:
  4226. + case SW_TYPE_HASH:
  4227. + {
  4228. + char result[HASH_MAX_LEN];
  4229. + struct hash_desc desc;
  4230. +
  4231. + /* check we have room for the result */
  4232. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  4233. + dprintk(
  4234. + "cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d digestsize=%d\n",
  4235. + crp->crp_ilen, crd->crd_skip + sg_len, crd->crd_inject,
  4236. + sw->u.hmac.sw_mlen);
  4237. + crp->crp_etype = EINVAL;
  4238. + goto done;
  4239. + }
  4240. +
  4241. + memset(&desc, 0, sizeof(desc));
  4242. + desc.tfm = crypto_hash_cast(sw->sw_tfm);
  4243. +
  4244. + memset(result, 0, sizeof(result));
  4245. +
  4246. + if (sw->sw_type == SW_TYPE_HMAC) {
  4247. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  4248. + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
  4249. + sg, sg_num, result);
  4250. +#else
  4251. + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
  4252. + sw->u.hmac.sw_klen);
  4253. + crypto_hash_digest(&desc, sg, sg_len, result);
  4254. +#endif /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  4255. +
  4256. + } else { /* SW_TYPE_HASH */
  4257. + crypto_hash_digest(&desc, sg, sg_len, result);
  4258. + }
  4259. +
  4260. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  4261. + crd->crd_inject, sw->u.hmac.sw_mlen, result);
  4262. + }
  4263. + break;
  4264. +
  4265. + case SW_TYPE_COMP: {
  4266. + void *ibuf = NULL;
  4267. + void *obuf = sw->u.sw_comp_buf;
  4268. + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
  4269. + int ret = 0;
  4270. +
  4271. + /*
  4272. + * we need to use an additional copy if there is more than one
  4273. + * input chunk since the kernel comp routines do not handle
  4274. + * SG yet. Otherwise we just use the input buffer as is.
  4275. + * Rather than allocate another buffer we just split the tmp
  4276. + * buffer we already have.
  4277. + * Perhaps we should just use zlib directly ?
  4278. + */
  4279. + if (sg_num > 1) {
  4280. + int blk;
  4281. +
  4282. + ibuf = obuf;
  4283. + for (blk = 0; blk < sg_num; blk++) {
  4284. + memcpy(obuf, sg_virt(&sg[blk]),
  4285. + sg[blk].length);
  4286. + obuf += sg[blk].length;
  4287. + }
  4288. + olen -= sg_len;
  4289. + } else
  4290. + ibuf = sg_virt(&sg[0]);
  4291. +
  4292. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
  4293. + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
  4294. + ibuf, ilen, obuf, &olen);
  4295. + if (!ret && olen > crd->crd_len) {
  4296. + dprintk("cryptosoft: ERANGE compress %d into %d\n",
  4297. + crd->crd_len, olen);
  4298. + if (swcr_fail_if_compression_grows)
  4299. + ret = ERANGE;
  4300. + }
  4301. + } else { /* decompress */
  4302. + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
  4303. + ibuf, ilen, obuf, &olen);
  4304. + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
  4305. + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
  4306. + "space for %d,at offset %d\n",
  4307. + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
  4308. + ret = ETOOSMALL;
  4309. + }
  4310. + }
  4311. + if (ret)
  4312. + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
  4313. +
  4314. + /*
  4315. + * on success copy result back,
  4316. + * linux crpyto API returns -errno, we need to fix that
  4317. + */
  4318. + crp->crp_etype = ret < 0 ? -ret : ret;
  4319. + if (ret == 0) {
  4320. + /* copy back the result and return it's size */
  4321. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  4322. + crd->crd_inject, olen, obuf);
  4323. + crp->crp_olen = olen;
  4324. + }
  4325. +
  4326. +
  4327. + } break;
  4328. +
  4329. + default:
  4330. + /* Unknown/unsupported algorithm */
  4331. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4332. + crp->crp_etype = EINVAL;
  4333. + goto done;
  4334. + }
  4335. + }
  4336. +
  4337. +done:
  4338. + crypto_done(crp);
  4339. + return 0;
  4340. +}
  4341. +
  4342. +static int
  4343. +cryptosoft_init(void)
  4344. +{
  4345. + int i, sw_type, mode;
  4346. + char *algo;
  4347. +
  4348. + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
  4349. +
  4350. + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
  4351. +
  4352. + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
  4353. + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
  4354. + if (swcr_id < 0) {
  4355. + printk("Software crypto device cannot initialize!");
  4356. + return -ENODEV;
  4357. + }
  4358. +
  4359. +#define REGISTER(alg) \
  4360. + crypto_register(swcr_id, alg, 0,0);
  4361. +
  4362. + for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; ++i)
  4363. + {
  4364. +
  4365. + algo = crypto_details[i].alg_name;
  4366. + if (!algo || !*algo)
  4367. + {
  4368. + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
  4369. + continue;
  4370. + }
  4371. +
  4372. + mode = crypto_details[i].mode;
  4373. + sw_type = crypto_details[i].sw_type;
  4374. +
  4375. + switch (sw_type)
  4376. + {
  4377. + case SW_TYPE_CIPHER:
  4378. + if (crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC))
  4379. + {
  4380. + REGISTER(i);
  4381. + }
  4382. + else
  4383. + {
  4384. + dprintk("%s:CIPHER algorithm %d:'%s' not supported\n",
  4385. + __FUNCTION__, i, algo);
  4386. + }
  4387. + break;
  4388. + case SW_TYPE_HMAC:
  4389. + if (crypto_has_hash(algo, 0, CRYPTO_ALG_ASYNC))
  4390. + {
  4391. + REGISTER(i);
  4392. + }
  4393. + else
  4394. + {
  4395. + dprintk("%s:HMAC algorithm %d:'%s' not supported\n",
  4396. + __FUNCTION__, i, algo);
  4397. + }
  4398. + break;
  4399. + case SW_TYPE_HASH:
  4400. + if (crypto_has_hash(algo, 0, CRYPTO_ALG_ASYNC))
  4401. + {
  4402. + REGISTER(i);
  4403. + }
  4404. + else
  4405. + {
  4406. + dprintk("%s:HASH algorithm %d:'%s' not supported\n",
  4407. + __FUNCTION__, i, algo);
  4408. + }
  4409. + break;
  4410. + case SW_TYPE_COMP:
  4411. + if (crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC))
  4412. + {
  4413. + REGISTER(i);
  4414. + }
  4415. + else
  4416. + {
  4417. + dprintk("%s:COMP algorithm %d:'%s' not supported\n",
  4418. + __FUNCTION__, i, algo);
  4419. + }
  4420. + break;
  4421. + case SW_TYPE_BLKCIPHER:
  4422. + if (crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC))
  4423. + {
  4424. + REGISTER(i);
  4425. + }
  4426. + else
  4427. + {
  4428. + dprintk("%s:BLKCIPHER algorithm %d:'%s' not supported\n",
  4429. + __FUNCTION__, i, algo);
  4430. + }
  4431. + break;
  4432. + default:
  4433. + dprintk(
  4434. + "%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
  4435. + __FUNCTION__, sw_type, i, algo);
  4436. + break;
  4437. + }
  4438. + }
  4439. +
  4440. + return(0);
  4441. +}
  4442. +
  4443. +static void
  4444. +cryptosoft_exit(void)
  4445. +{
  4446. + dprintk("%s()\n", __FUNCTION__);
  4447. + crypto_unregister_all(swcr_id);
  4448. + swcr_id = -1;
  4449. +}
  4450. +
  4451. +module_init(cryptosoft_init);
  4452. +module_exit(cryptosoft_exit);
  4453. +
  4454. +MODULE_LICENSE("Dual BSD/GPL");
  4455. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  4456. +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
  4457. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.27.10/crypto/ocf/ep80579/icp_asym.c
  4458. --- linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
  4459. +++ linux-2.6.27.10/crypto/ocf/ep80579/icp_asym.c 2008-12-23 19:31:44.000000000 +0100
  4460. @@ -0,0 +1,1375 @@
  4461. +/***************************************************************************
  4462. + *
  4463. + * This file is provided under a dual BSD/GPLv2 license. When using or
  4464. + * redistributing this file, you may do so under either license.
  4465. + *
  4466. + * GPL LICENSE SUMMARY
  4467. + *
  4468. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  4469. + *
  4470. + * This program is free software; you can redistribute it and/or modify
  4471. + * it under the terms of version 2 of the GNU General Public License as
  4472. + * published by the Free Software Foundation.
  4473. + *
  4474. + * This program is distributed in the hope that it will be useful, but
  4475. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  4476. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  4477. + * General Public License for more details.
  4478. + *
  4479. + * You should have received a copy of the GNU General Public License
  4480. + * along with this program; if not, write to the Free Software
  4481. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  4482. + * The full GNU General Public License is included in this distribution
  4483. + * in the file called LICENSE.GPL.
  4484. + *
  4485. + * Contact Information:
  4486. + * Intel Corporation
  4487. + *
  4488. + * BSD LICENSE
  4489. + *
  4490. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  4491. + * All rights reserved.
  4492. + *
  4493. + * Redistribution and use in source and binary forms, with or without
  4494. + * modification, are permitted provided that the following conditions
  4495. + * are met:
  4496. + *
  4497. + * * Redistributions of source code must retain the above copyright
  4498. + * notice, this list of conditions and the following disclaimer.
  4499. + * * Redistributions in binary form must reproduce the above copyright
  4500. + * notice, this list of conditions and the following disclaimer in
  4501. + * the documentation and/or other materials provided with the
  4502. + * distribution.
  4503. + * * Neither the name of Intel Corporation nor the names of its
  4504. + * contributors may be used to endorse or promote products derived
  4505. + * from this software without specific prior written permission.
  4506. + *
  4507. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4508. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  4509. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  4510. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  4511. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  4512. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  4513. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  4514. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  4515. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4516. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  4517. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4518. + *
  4519. + *
  4520. + * version: Security.L.1.0.130
  4521. + *
  4522. + ***************************************************************************/
  4523. +
  4524. +#include "icp_ocf.h"
  4525. +
  4526. +/*The following define values (containing the word 'INDEX') are used to find
  4527. +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
  4528. +These values were found through analysis of the OCF OpenSSL patch. If the
  4529. +calling program uses different input buffer positions, these defines will have
  4530. +to be changed.*/
  4531. +
  4532. +/*DIFFIE HELLMAN buffer index values*/
  4533. +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
  4534. +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
  4535. +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
  4536. +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
  4537. +
  4538. +/*MOD EXP buffer index values*/
  4539. +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
  4540. +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
  4541. +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
  4542. +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
  4543. +
  4544. +#define SINGLE_BYTE_VALUE (4)
  4545. +
  4546. +/*MOD EXP CRT buffer index values*/
  4547. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
  4548. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
  4549. +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
  4550. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
  4551. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
  4552. +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
  4553. +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
  4554. +
  4555. +/*DSA sign buffer index values*/
  4556. +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
  4557. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
  4558. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
  4559. +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
  4560. +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
  4561. +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
  4562. +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
  4563. +
  4564. +/*DSA verify buffer index values*/
  4565. +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
  4566. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
  4567. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
  4568. +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
  4569. +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
  4570. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
  4571. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
  4572. +
  4573. +/*DSA sign prime Q vs random number K size check values*/
  4574. +#define DONT_RUN_LESS_THAN_CHECK (0)
  4575. +#define FAIL_A_IS_GREATER_THAN_B (1)
  4576. +#define FAIL_A_IS_EQUAL_TO_B (1)
  4577. +#define SUCCESS_A_IS_LESS_THAN_B (0)
  4578. +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
  4579. +
  4580. +/* We need to set a cryptokp success value just in case it is set or allocated
  4581. + and not set to zero outside of this module */
  4582. +#define CRYPTO_OP_SUCCESS (0)
  4583. +
  4584. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
  4585. +
  4586. +static int icp_ocfDrvModExp(struct cryptkop *krp);
  4587. +
  4588. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
  4589. +
  4590. +static int
  4591. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
  4592. +
  4593. +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
  4594. +
  4595. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
  4596. +
  4597. +static void
  4598. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  4599. + CpaStatus status,
  4600. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
  4601. +
  4602. +static void
  4603. +icp_ocfDrvModExpCallBack(void *callbackTag,
  4604. + CpaStatus status,
  4605. + void *pOpData, CpaFlatBuffer * pResult);
  4606. +
  4607. +static void
  4608. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  4609. + CpaStatus status,
  4610. + void *pOpData, CpaFlatBuffer * pOutputData);
  4611. +
  4612. +static void
  4613. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  4614. + CpaStatus status,
  4615. + void *pOpData, CpaBoolean verifyStatus);
  4616. +
  4617. +static void
  4618. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  4619. + CpaStatus status,
  4620. + void *pOpData,
  4621. + CpaBoolean protocolStatus,
  4622. + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
  4623. +
  4624. +/* Name : icp_ocfDrvPkeProcess
  4625. + *
  4626. + * Description : This function will choose which PKE process to follow
  4627. + * based on the input arguments
  4628. + */
  4629. +int icp_ocfDrvPkeProcess(device_t dev, struct cryptkop *krp, int hint)
  4630. +{
  4631. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  4632. +
  4633. + if (NULL == krp) {
  4634. + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
  4635. + __FUNCTION__, krp);
  4636. + return EINVAL;
  4637. + }
  4638. +
  4639. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  4640. + krp->krp_status = ECANCELED;
  4641. + return ECANCELED;
  4642. + }
  4643. +
  4644. + switch (krp->krp_op) {
  4645. + case CRK_DH_COMPUTE_KEY:
  4646. + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
  4647. + lacStatus = icp_ocfDrvDHComputeKey(krp);
  4648. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4649. + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
  4650. + "(%d).\n", __FUNCTION__, lacStatus);
  4651. + krp->krp_status = ECANCELED;
  4652. + return ECANCELED;
  4653. + }
  4654. +
  4655. + break;
  4656. +
  4657. + case CRK_MOD_EXP:
  4658. + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
  4659. + lacStatus = icp_ocfDrvModExp(krp);
  4660. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4661. + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
  4662. + __FUNCTION__, lacStatus);
  4663. + krp->krp_status = ECANCELED;
  4664. + return ECANCELED;
  4665. + }
  4666. +
  4667. + break;
  4668. +
  4669. + case CRK_MOD_EXP_CRT:
  4670. + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
  4671. + lacStatus = icp_ocfDrvModExpCRT(krp);
  4672. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4673. + EPRINTK("%s(): icp_ocfDrvModExpCRT "
  4674. + "failed (%d).\n", __FUNCTION__, lacStatus);
  4675. + krp->krp_status = ECANCELED;
  4676. + return ECANCELED;
  4677. + }
  4678. +
  4679. + break;
  4680. +
  4681. + case CRK_DSA_SIGN:
  4682. + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
  4683. + lacStatus = icp_ocfDrvDsaSign(krp);
  4684. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4685. + EPRINTK("%s(): icp_ocfDrvDsaSign "
  4686. + "failed (%d).\n", __FUNCTION__, lacStatus);
  4687. + krp->krp_status = ECANCELED;
  4688. + return ECANCELED;
  4689. + }
  4690. +
  4691. + break;
  4692. +
  4693. + case CRK_DSA_VERIFY:
  4694. + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
  4695. + lacStatus = icp_ocfDrvDsaVerify(krp);
  4696. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4697. + EPRINTK("%s(): icp_ocfDrvDsaVerify "
  4698. + "failed (%d).\n", __FUNCTION__, lacStatus);
  4699. + krp->krp_status = ECANCELED;
  4700. + return ECANCELED;
  4701. + }
  4702. +
  4703. + break;
  4704. +
  4705. + default:
  4706. + EPRINTK("%s(): Asymettric function not "
  4707. + "supported (%d).\n", __FUNCTION__, krp->krp_op);
  4708. + krp->krp_status = EOPNOTSUPP;
  4709. + return EOPNOTSUPP;
  4710. + }
  4711. +
  4712. + return ICP_OCF_DRV_STATUS_SUCCESS;
  4713. +}
  4714. +
  4715. +/* Name : icp_ocfDrvSwapBytes
  4716. + *
  4717. + * Description : This function is used to swap the byte order of a buffer.
  4718. + * It has been seen that in general we are passed little endian byte order
  4719. + * buffers, but LAC only accepts big endian byte order buffers.
  4720. + */
  4721. +static void inline
  4722. +icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
  4723. +{
  4724. +
  4725. + int i;
  4726. + u_int8_t *end_ptr;
  4727. + u_int8_t hold_val;
  4728. +
  4729. + end_ptr = num + (buff_len_bytes - 1);
  4730. + buff_len_bytes = buff_len_bytes >> 1;
  4731. + for (i = 0; i < buff_len_bytes; i++) {
  4732. + hold_val = *num;
  4733. + *num = *end_ptr;
  4734. + num++;
  4735. + *end_ptr = hold_val;
  4736. + end_ptr--;
  4737. + }
  4738. +}
  4739. +
  4740. +/* Name : icp_ocfDrvDHComputeKey
  4741. + *
  4742. + * Description : This function will map Diffie Hellman calls from OCF
  4743. + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
  4744. + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
  4745. + * break down to a modular exponentiation.
  4746. + */
  4747. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
  4748. +{
  4749. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  4750. + void *callbackTag = NULL;
  4751. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  4752. + CpaFlatBuffer *pLocalOctetStringPV = NULL;
  4753. + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
  4754. +
  4755. + /* Input checks - check prime is a multiple of 8 bits to allow for
  4756. + allocation later */
  4757. + dh_prime_len_bits =
  4758. + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
  4759. +
  4760. + /* LAC can reject prime lengths based on prime key sizes, we just
  4761. + need to make sure we can allocate space for the base and
  4762. + exponent buffers correctly */
  4763. + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
  4764. + APRINTK("%s(): Warning Prime number buffer size is not a "
  4765. + "multiple of 8 bits\n", __FUNCTION__);
  4766. + }
  4767. +
  4768. + /* Result storage space should be the same size as the prime as this
  4769. + value can take up the same amount of storage space */
  4770. + if (dh_prime_len_bits !=
  4771. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  4772. + DPRINTK("%s(): Return Buffer must be the same size "
  4773. + "as the Prime buffer\n", __FUNCTION__);
  4774. + krp->krp_status = EINVAL;
  4775. + return EINVAL;
  4776. + }
  4777. + /* Switch to size in bytes */
  4778. + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
  4779. +
  4780. + callbackTag = krp;
  4781. +
  4782. + pPhase1OpData = kmem_cache_zalloc(drvDH_zone, GFP_KERNEL);
  4783. + if (NULL == pPhase1OpData) {
  4784. + APRINTK("%s():Failed to get memory for key gen data\n",
  4785. + __FUNCTION__);
  4786. + krp->krp_status = ENOMEM;
  4787. + return ENOMEM;
  4788. + }
  4789. +
  4790. + pLocalOctetStringPV = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  4791. + if (NULL == pLocalOctetStringPV) {
  4792. + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
  4793. + __FUNCTION__);
  4794. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  4795. + krp->krp_status = ENOMEM;
  4796. + return ENOMEM;
  4797. + }
  4798. +
  4799. + /* Link parameters */
  4800. + pPhase1OpData->primeP.pData =
  4801. + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
  4802. +
  4803. + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
  4804. +
  4805. + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
  4806. +
  4807. + pPhase1OpData->baseG.pData =
  4808. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
  4809. +
  4810. + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
  4811. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
  4812. +
  4813. + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
  4814. + pPhase1OpData->baseG.dataLenInBytes);
  4815. +
  4816. + pPhase1OpData->privateValueX.pData =
  4817. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
  4818. +
  4819. + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
  4820. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
  4821. + crp_nbits);
  4822. +
  4823. + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
  4824. + pPhase1OpData->privateValueX.dataLenInBytes);
  4825. +
  4826. + /* Output parameters */
  4827. + pLocalOctetStringPV->pData =
  4828. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
  4829. +
  4830. + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
  4831. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
  4832. +
  4833. + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
  4834. + icp_ocfDrvDhP1CallBack,
  4835. + callbackTag, pPhase1OpData,
  4836. + pLocalOctetStringPV);
  4837. +
  4838. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4839. + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
  4840. + __FUNCTION__, lacStatus);
  4841. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  4842. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  4843. + }
  4844. +
  4845. + return lacStatus;
  4846. +}
  4847. +
  4848. +/* Name : icp_ocfDrvModExp
  4849. + *
  4850. + * Description : This function will map ordinary Modular Exponentiation calls
  4851. + * from OCF to the LAC API.
  4852. + *
  4853. + */
  4854. +static int icp_ocfDrvModExp(struct cryptkop *krp)
  4855. +{
  4856. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  4857. + void *callbackTag = NULL;
  4858. + CpaCyLnModExpOpData *pModExpOpData = NULL;
  4859. + CpaFlatBuffer *pResult = NULL;
  4860. +
  4861. + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
  4862. + NUM_BITS_IN_BYTE) != 0) {
  4863. + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
  4864. + "multiple of 8 bits\n", __FUNCTION__,
  4865. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  4866. + crp_nbits);
  4867. + }
  4868. +
  4869. + /* Result storage space should be the same size as the prime as this
  4870. + value can take up the same amount of storage space */
  4871. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
  4872. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  4873. + APRINTK("%s(): Return Buffer size must be the same or"
  4874. + " greater than the Modulus buffer\n", __FUNCTION__);
  4875. + krp->krp_status = EINVAL;
  4876. + return EINVAL;
  4877. + }
  4878. +
  4879. + callbackTag = krp;
  4880. +
  4881. + pModExpOpData = kmem_cache_zalloc(drvLnModExp_zone, GFP_KERNEL);
  4882. + if (NULL == pModExpOpData) {
  4883. + APRINTK("%s():Failed to get memory for key gen data\n",
  4884. + __FUNCTION__);
  4885. + krp->krp_status = ENOMEM;
  4886. + return ENOMEM;
  4887. + }
  4888. +
  4889. + pResult = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  4890. + if (NULL == pResult) {
  4891. + APRINTK("%s():Failed to get memory for ModExp result\n",
  4892. + __FUNCTION__);
  4893. + kmem_cache_free(drvLnModExp_zone, pModExpOpData);
  4894. + krp->krp_status = ENOMEM;
  4895. + return ENOMEM;
  4896. + }
  4897. +
  4898. + /* Link parameters */
  4899. + pModExpOpData->modulus.pData =
  4900. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
  4901. + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
  4902. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  4903. + crp_nbits);
  4904. +
  4905. + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
  4906. + pModExpOpData->modulus.dataLenInBytes);
  4907. +
  4908. + /*OCF patch to Openswan Pluto regularly sends the base value as 2
  4909. + bits in size. In this case, it has been found it is better to
  4910. + use the base size memory space as the input buffer (if the number
  4911. + is in bits is less than a byte, the number of bits is the input
  4912. + value) */
  4913. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits <
  4914. + NUM_BITS_IN_BYTE) {
  4915. + DPRINTK("%s : base is small (%d)\n", __FUNCTION__, krp->
  4916. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  4917. + pModExpOpData->base.dataLenInBytes = SINGLE_BYTE_VALUE;
  4918. + pModExpOpData->base.pData =
  4919. + (uint8_t *) & (krp->
  4920. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  4921. + crp_nbits);
  4922. + *((uint32_t *) pModExpOpData->base.pData) =
  4923. + htonl(*((uint32_t *) pModExpOpData->base.pData));
  4924. +
  4925. + } else {
  4926. +
  4927. + DPRINTK("%s : base is big (%d)\n", __FUNCTION__, krp->
  4928. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  4929. + pModExpOpData->base.pData =
  4930. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
  4931. + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
  4932. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  4933. + crp_nbits);
  4934. + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
  4935. + pModExpOpData->base.dataLenInBytes);
  4936. + }
  4937. +
  4938. + pModExpOpData->exponent.pData =
  4939. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
  4940. + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
  4941. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
  4942. + crp_nbits);
  4943. +
  4944. + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
  4945. + pModExpOpData->exponent.dataLenInBytes);
  4946. + /* Output parameters */
  4947. + pResult->pData =
  4948. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
  4949. + BITS_TO_BYTES(pResult->dataLenInBytes,
  4950. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
  4951. + crp_nbits);
  4952. +
  4953. + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
  4954. + icp_ocfDrvModExpCallBack,
  4955. + callbackTag, pModExpOpData, pResult);
  4956. +
  4957. + if (CPA_STATUS_SUCCESS != lacStatus) {
  4958. + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
  4959. + __FUNCTION__, lacStatus);
  4960. + krp->krp_status = ECANCELED;
  4961. + icp_ocfDrvFreeFlatBuffer(pResult);
  4962. + kmem_cache_free(drvLnModExp_zone, pModExpOpData);
  4963. + }
  4964. +
  4965. + return lacStatus;
  4966. +}
  4967. +
  4968. +/* Name : icp_ocfDrvModExpCRT
  4969. + *
  4970. + * Description : This function will map ordinary Modular Exponentiation Chinese
  4971. + * Remainder Theorem implementaion calls from OCF to the LAC API.
  4972. + *
  4973. + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
  4974. + * decrypt operation. Therefore P and Q input values must always be prime
  4975. + * numbers. Although basic primality checks are done in LAC, it is up to the
  4976. + * user to do any correct prime number checking before passing the inputs.
  4977. + */
  4978. +
  4979. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
  4980. +{
  4981. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  4982. + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
  4983. + void *callbackTag = NULL;
  4984. + CpaFlatBuffer *pOutputData = NULL;
  4985. +
  4986. + /*Parameter input checks are all done by LAC, no need to repeat
  4987. + them here. */
  4988. + callbackTag = krp;
  4989. +
  4990. + rsaDecryptOpData = kmem_cache_zalloc(drvRSADecrypt_zone, GFP_KERNEL);
  4991. + if (NULL == rsaDecryptOpData) {
  4992. + APRINTK("%s():Failed to get memory"
  4993. + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
  4994. + krp->krp_status = ENOMEM;
  4995. + return ENOMEM;
  4996. + }
  4997. +
  4998. + rsaDecryptOpData->pRecipientPrivateKey
  4999. + = kmem_cache_zalloc(drvRSAPrivateKey_zone, GFP_KERNEL);
  5000. + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
  5001. + APRINTK("%s():Failed to get memory for MOD EXP CRT"
  5002. + " private key values struct\n", __FUNCTION__);
  5003. + kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
  5004. + krp->krp_status = ENOMEM;
  5005. + return ENOMEM;
  5006. + }
  5007. +
  5008. + rsaDecryptOpData->pRecipientPrivateKey->
  5009. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  5010. + rsaDecryptOpData->pRecipientPrivateKey->
  5011. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  5012. +
  5013. + pOutputData = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5014. + if (NULL == pOutputData) {
  5015. + APRINTK("%s():Failed to get memory"
  5016. + " for MOD EXP CRT output data\n", __FUNCTION__);
  5017. + kmem_cache_free(drvRSAPrivateKey_zone,
  5018. + rsaDecryptOpData->pRecipientPrivateKey);
  5019. + kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
  5020. + krp->krp_status = ENOMEM;
  5021. + return ENOMEM;
  5022. + }
  5023. +
  5024. + rsaDecryptOpData->pRecipientPrivateKey->
  5025. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  5026. + rsaDecryptOpData->pRecipientPrivateKey->
  5027. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  5028. +
  5029. + /* Link parameters */
  5030. + rsaDecryptOpData->inputData.pData =
  5031. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
  5032. + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
  5033. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
  5034. + crp_nbits);
  5035. +
  5036. + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
  5037. + rsaDecryptOpData->inputData.dataLenInBytes);
  5038. +
  5039. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
  5040. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
  5041. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  5042. + prime1P.dataLenInBytes,
  5043. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
  5044. + crp_nbits);
  5045. +
  5046. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5047. + privateKeyRep2.prime1P.pData,
  5048. + rsaDecryptOpData->pRecipientPrivateKey->
  5049. + privateKeyRep2.prime1P.dataLenInBytes);
  5050. +
  5051. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
  5052. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  5053. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  5054. + prime2Q.dataLenInBytes,
  5055. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
  5056. + crp_nbits);
  5057. +
  5058. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5059. + privateKeyRep2.prime2Q.pData,
  5060. + rsaDecryptOpData->pRecipientPrivateKey->
  5061. + privateKeyRep2.prime2Q.dataLenInBytes);
  5062. +
  5063. + rsaDecryptOpData->pRecipientPrivateKey->
  5064. + privateKeyRep2.exponent1Dp.pData =
  5065. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
  5066. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  5067. + exponent1Dp.dataLenInBytes,
  5068. + krp->
  5069. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
  5070. + crp_nbits);
  5071. +
  5072. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5073. + privateKeyRep2.exponent1Dp.pData,
  5074. + rsaDecryptOpData->pRecipientPrivateKey->
  5075. + privateKeyRep2.exponent1Dp.dataLenInBytes);
  5076. +
  5077. + rsaDecryptOpData->pRecipientPrivateKey->
  5078. + privateKeyRep2.exponent2Dq.pData =
  5079. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
  5080. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  5081. + privateKeyRep2.exponent2Dq.dataLenInBytes,
  5082. + krp->
  5083. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
  5084. + crp_nbits);
  5085. +
  5086. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5087. + privateKeyRep2.exponent2Dq.pData,
  5088. + rsaDecryptOpData->pRecipientPrivateKey->
  5089. + privateKeyRep2.exponent2Dq.dataLenInBytes);
  5090. +
  5091. + rsaDecryptOpData->pRecipientPrivateKey->
  5092. + privateKeyRep2.coefficientQInv.pData =
  5093. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
  5094. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  5095. + privateKeyRep2.coefficientQInv.dataLenInBytes,
  5096. + krp->
  5097. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
  5098. + crp_nbits);
  5099. +
  5100. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5101. + privateKeyRep2.coefficientQInv.pData,
  5102. + rsaDecryptOpData->pRecipientPrivateKey->
  5103. + privateKeyRep2.coefficientQInv.dataLenInBytes);
  5104. +
  5105. + /* Output Parameter */
  5106. + pOutputData->pData =
  5107. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
  5108. + BITS_TO_BYTES(pOutputData->dataLenInBytes,
  5109. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
  5110. + crp_nbits);
  5111. +
  5112. + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
  5113. + icp_ocfDrvModExpCRTCallBack,
  5114. + callbackTag, rsaDecryptOpData, pOutputData);
  5115. +
  5116. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5117. + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
  5118. + __FUNCTION__, lacStatus);
  5119. + krp->krp_status = ECANCELED;
  5120. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  5121. + kmem_cache_free(drvRSAPrivateKey_zone,
  5122. + rsaDecryptOpData->pRecipientPrivateKey);
  5123. + kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
  5124. + }
  5125. +
  5126. + return lacStatus;
  5127. +}
  5128. +
  5129. +/* Name : icp_ocfDrvCheckALessThanB
  5130. + *
  5131. + * Description : This function will check whether the first argument is less
  5132. + * than the second. It is used to check whether the DSA RS sign Random K
  5133. + * value is less than the Prime Q value (as defined in the specification)
  5134. + *
  5135. + */
  5136. +static int
  5137. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
  5138. +{
  5139. +
  5140. + uint8_t *MSB_K = pK->pData;
  5141. + uint8_t *MSB_Q = pQ->pData;
  5142. + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
  5143. +
  5144. + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
  5145. + return FAIL_A_IS_GREATER_THAN_B;
  5146. + }
  5147. +
  5148. +/*Check MSBs
  5149. +if A == B, check next MSB
  5150. +if A > B, return A_IS_GREATER_THAN_B
  5151. +if A < B, return A_IS_LESS_THAN_B (success)
  5152. +*/
  5153. + while (*MSB_K == *MSB_Q) {
  5154. + MSB_K++;
  5155. + MSB_Q++;
  5156. +
  5157. + buffer_lengths_in_bytes--;
  5158. + if (0 == buffer_lengths_in_bytes) {
  5159. + DPRINTK("%s() Buffers have equal value!!\n",
  5160. + __FUNCTION__);
  5161. + return FAIL_A_IS_EQUAL_TO_B;
  5162. + }
  5163. +
  5164. + }
  5165. +
  5166. + if (*MSB_K < *MSB_Q) {
  5167. + return SUCCESS_A_IS_LESS_THAN_B;
  5168. + } else {
  5169. + return FAIL_A_IS_GREATER_THAN_B;
  5170. + }
  5171. +
  5172. +}
  5173. +
  5174. +/* Name : icp_ocfDrvDsaSign
  5175. + *
  5176. + * Description : This function will map DSA RS Sign from OCF to the LAC API.
  5177. + *
  5178. + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
  5179. + * parameters, OCF expects us to generate the random seed value. This value
  5180. + * is generated and passed to LAC, however the number is discared in the
  5181. + * callback and not returned to the user.
  5182. + */
  5183. +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
  5184. +{
  5185. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5186. + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
  5187. + void *callbackTag = NULL;
  5188. + CpaCyRandGenOpData randGenOpData;
  5189. + int primeQSizeInBytes = 0;
  5190. + int doCheck = 0;
  5191. + CpaFlatBuffer randData;
  5192. + CpaBoolean protocolStatus = CPA_FALSE;
  5193. + CpaFlatBuffer *pR = NULL;
  5194. + CpaFlatBuffer *pS = NULL;
  5195. +
  5196. + callbackTag = krp;
  5197. +
  5198. + BITS_TO_BYTES(primeQSizeInBytes,
  5199. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  5200. + crp_nbits);
  5201. +
  5202. + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
  5203. + APRINTK("%s(): DSA PRIME Q size not equal to the "
  5204. + "FIPS defined 20bytes, = %d\n",
  5205. + __FUNCTION__, primeQSizeInBytes);
  5206. + krp->krp_status = EDOM;
  5207. + return EDOM;
  5208. + }
  5209. +
  5210. + dsaRsSignOpData = kmem_cache_zalloc(drvDSARSSign_zone, GFP_KERNEL);
  5211. + if (NULL == dsaRsSignOpData) {
  5212. + APRINTK("%s():Failed to get memory"
  5213. + " for DSA RS Sign Op data struct\n", __FUNCTION__);
  5214. + krp->krp_status = ENOMEM;
  5215. + return ENOMEM;
  5216. + }
  5217. +
  5218. + dsaRsSignOpData->K.pData =
  5219. + kmem_cache_alloc(drvDSARSSignKValue_zone, GFP_ATOMIC);
  5220. +
  5221. + if (NULL == dsaRsSignOpData->K.pData) {
  5222. + APRINTK("%s():Failed to get memory"
  5223. + " for DSA RS Sign Op Random value\n", __FUNCTION__);
  5224. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5225. + krp->krp_status = ENOMEM;
  5226. + return ENOMEM;
  5227. + }
  5228. +
  5229. + pR = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5230. + if (NULL == pR) {
  5231. + APRINTK("%s():Failed to get memory"
  5232. + " for DSA signature R\n", __FUNCTION__);
  5233. + kmem_cache_free(drvDSARSSignKValue_zone,
  5234. + dsaRsSignOpData->K.pData);
  5235. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5236. + krp->krp_status = ENOMEM;
  5237. + return ENOMEM;
  5238. + }
  5239. +
  5240. + pS = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5241. + if (NULL == pS) {
  5242. + APRINTK("%s():Failed to get memory"
  5243. + " for DSA signature S\n", __FUNCTION__);
  5244. + icp_ocfDrvFreeFlatBuffer(pR);
  5245. + kmem_cache_free(drvDSARSSignKValue_zone,
  5246. + dsaRsSignOpData->K.pData);
  5247. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5248. + krp->krp_status = ENOMEM;
  5249. + return ENOMEM;
  5250. + }
  5251. +
  5252. + /*link prime number parameter for ease of processing */
  5253. + dsaRsSignOpData->P.pData =
  5254. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
  5255. + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
  5256. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
  5257. + crp_nbits);
  5258. +
  5259. + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
  5260. + dsaRsSignOpData->P.dataLenInBytes);
  5261. +
  5262. + dsaRsSignOpData->Q.pData =
  5263. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  5264. + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
  5265. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  5266. + crp_nbits);
  5267. +
  5268. + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
  5269. + dsaRsSignOpData->Q.dataLenInBytes);
  5270. +
  5271. + /*generate random number with equal buffer size to Prime value Q,
  5272. + but value less than Q */
  5273. + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
  5274. +
  5275. + randGenOpData.generateBits = CPA_TRUE;
  5276. + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
  5277. +
  5278. + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
  5279. + dsaRsSignOpData->K.dataLenInBytes,
  5280. + &randData);
  5281. +
  5282. + doCheck = 0;
  5283. + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
  5284. + &(dsaRsSignOpData->Q), &doCheck)) {
  5285. +
  5286. + if (CPA_STATUS_SUCCESS
  5287. + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  5288. + NULL, NULL, &randGenOpData, &randData)) {
  5289. + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
  5290. + "value\n", __FUNCTION__);
  5291. + icp_ocfDrvFreeFlatBuffer(pS);
  5292. + icp_ocfDrvFreeFlatBuffer(pR);
  5293. + kmem_cache_free(drvDSARSSignKValue_zone,
  5294. + dsaRsSignOpData->K.pData);
  5295. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5296. + krp->krp_status = EAGAIN;
  5297. + return EAGAIN;
  5298. + }
  5299. +
  5300. + doCheck++;
  5301. + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
  5302. + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
  5303. + "value less than Q value\n", __FUNCTION__);
  5304. + icp_ocfDrvFreeFlatBuffer(pS);
  5305. + icp_ocfDrvFreeFlatBuffer(pR);
  5306. + kmem_cache_free(drvDSARSSignKValue_zone,
  5307. + dsaRsSignOpData->K.pData);
  5308. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5309. + krp->krp_status = EAGAIN;
  5310. + return EAGAIN;
  5311. + }
  5312. +
  5313. + }
  5314. + /*Rand Data - no need to swap bytes for pK */
  5315. +
  5316. + /* Link parameters */
  5317. + dsaRsSignOpData->G.pData =
  5318. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
  5319. + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
  5320. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
  5321. +
  5322. + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
  5323. + dsaRsSignOpData->G.dataLenInBytes);
  5324. +
  5325. + dsaRsSignOpData->X.pData =
  5326. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
  5327. + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
  5328. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
  5329. + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
  5330. + dsaRsSignOpData->X.dataLenInBytes);
  5331. +
  5332. + dsaRsSignOpData->M.pData =
  5333. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
  5334. + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
  5335. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
  5336. + crp_nbits);
  5337. + icp_ocfDrvSwapBytes(dsaRsSignOpData->M.pData,
  5338. + dsaRsSignOpData->M.dataLenInBytes);
  5339. +
  5340. + /* Output Parameters */
  5341. + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
  5342. + BITS_TO_BYTES(pS->dataLenInBytes,
  5343. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
  5344. + crp_nbits);
  5345. +
  5346. + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
  5347. + BITS_TO_BYTES(pR->dataLenInBytes,
  5348. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
  5349. + crp_nbits);
  5350. +
  5351. + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
  5352. + icp_ocfDrvDsaRSSignCallBack,
  5353. + callbackTag, dsaRsSignOpData,
  5354. + &protocolStatus, pR, pS);
  5355. +
  5356. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5357. + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
  5358. + __FUNCTION__, lacStatus);
  5359. + krp->krp_status = ECANCELED;
  5360. + icp_ocfDrvFreeFlatBuffer(pS);
  5361. + icp_ocfDrvFreeFlatBuffer(pR);
  5362. + kmem_cache_free(drvDSARSSignKValue_zone,
  5363. + dsaRsSignOpData->K.pData);
  5364. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5365. + }
  5366. +
  5367. + return lacStatus;
  5368. +}
  5369. +
  5370. +/* Name : icp_ocfDrvDsaVerify
  5371. + *
  5372. + * Description : This function will map DSA RS Verify from OCF to the LAC API.
  5373. + *
  5374. + */
  5375. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
  5376. +{
  5377. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5378. + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
  5379. + void *callbackTag = NULL;
  5380. + CpaBoolean verifyStatus = CPA_FALSE;
  5381. +
  5382. + callbackTag = krp;
  5383. +
  5384. + dsaVerifyOpData = kmem_cache_zalloc(drvDSAVerify_zone, GFP_KERNEL);
  5385. + if (NULL == dsaVerifyOpData) {
  5386. + APRINTK("%s():Failed to get memory"
  5387. + " for DSA Verify Op data struct\n", __FUNCTION__);
  5388. + krp->krp_status = ENOMEM;
  5389. + return ENOMEM;
  5390. + }
  5391. +
  5392. + /* Link parameters */
  5393. + dsaVerifyOpData->P.pData =
  5394. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
  5395. + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
  5396. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
  5397. + crp_nbits);
  5398. + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
  5399. + dsaVerifyOpData->P.dataLenInBytes);
  5400. +
  5401. + dsaVerifyOpData->Q.pData =
  5402. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  5403. + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
  5404. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
  5405. + crp_nbits);
  5406. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
  5407. + dsaVerifyOpData->Q.dataLenInBytes);
  5408. +
  5409. + dsaVerifyOpData->G.pData =
  5410. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
  5411. + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
  5412. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
  5413. + crp_nbits);
  5414. + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
  5415. + dsaVerifyOpData->G.dataLenInBytes);
  5416. +
  5417. + dsaVerifyOpData->Y.pData =
  5418. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
  5419. + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
  5420. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
  5421. + crp_nbits);
  5422. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
  5423. + dsaVerifyOpData->Y.dataLenInBytes);
  5424. +
  5425. + dsaVerifyOpData->M.pData =
  5426. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
  5427. + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
  5428. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
  5429. + crp_nbits);
  5430. + icp_ocfDrvSwapBytes(dsaVerifyOpData->M.pData,
  5431. + dsaVerifyOpData->M.dataLenInBytes);
  5432. +
  5433. + dsaVerifyOpData->R.pData =
  5434. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
  5435. + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
  5436. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
  5437. + crp_nbits);
  5438. + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
  5439. + dsaVerifyOpData->R.dataLenInBytes);
  5440. +
  5441. + dsaVerifyOpData->S.pData =
  5442. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
  5443. + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
  5444. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
  5445. + crp_nbits);
  5446. + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
  5447. + dsaVerifyOpData->S.dataLenInBytes);
  5448. +
  5449. + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
  5450. + icp_ocfDrvDsaVerifyCallBack,
  5451. + callbackTag, dsaVerifyOpData, &verifyStatus);
  5452. +
  5453. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5454. + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
  5455. + __FUNCTION__, lacStatus);
  5456. + kmem_cache_free(drvDSAVerify_zone, dsaVerifyOpData);
  5457. + krp->krp_status = ECANCELED;
  5458. + }
  5459. +
  5460. + return lacStatus;
  5461. +}
  5462. +
  5463. +/* Name : icp_ocfDrvReadRandom
  5464. + *
  5465. + * Description : This function will map RNG functionality calls from OCF
  5466. + * to the LAC API.
  5467. + */
  5468. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords)
  5469. +{
  5470. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5471. + CpaCyRandGenOpData randGenOpData;
  5472. + CpaFlatBuffer randData;
  5473. +
  5474. + if (NULL == buf) {
  5475. + APRINTK("%s(): Invalid input parameters\n", __FUNCTION__);
  5476. + return EINVAL;
  5477. + }
  5478. +
  5479. + /* maxwords here is number of integers to generate data for */
  5480. + randGenOpData.generateBits = CPA_TRUE;
  5481. +
  5482. + randGenOpData.lenInBytes = maxwords * sizeof(uint32_t);
  5483. +
  5484. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *) buf,
  5485. + randGenOpData.lenInBytes, &randData);
  5486. +
  5487. + lacStatus = cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  5488. + NULL, NULL, &randGenOpData, &randData);
  5489. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5490. + EPRINTK("%s(): icp_LacSymRandGen failed (%d). \n",
  5491. + __FUNCTION__, lacStatus);
  5492. + return RETURN_RAND_NUM_GEN_FAILED;
  5493. + }
  5494. +
  5495. + return randGenOpData.lenInBytes / sizeof(uint32_t);
  5496. +}
  5497. +
  5498. +/* Name : icp_ocfDrvDhP1Callback
  5499. + *
  5500. + * Description : When this function returns it signifies that the LAC
  5501. + * component has completed the DH operation.
  5502. + */
  5503. +static void
  5504. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  5505. + CpaStatus status,
  5506. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
  5507. +{
  5508. + struct cryptkop *krp = NULL;
  5509. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  5510. +
  5511. + if (NULL == callbackTag) {
  5512. + DPRINTK("%s(): Invalid input parameters - "
  5513. + "callbackTag data is NULL\n", __FUNCTION__);
  5514. + return;
  5515. + }
  5516. + krp = (struct cryptkop *)callbackTag;
  5517. +
  5518. + if (NULL == pOpData) {
  5519. + DPRINTK("%s(): Invalid input parameters - "
  5520. + "Operation Data is NULL\n", __FUNCTION__);
  5521. + krp->krp_status = ECANCELED;
  5522. + crypto_kdone(krp);
  5523. + return;
  5524. + }
  5525. + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
  5526. +
  5527. + if (NULL == pLocalOctetStringPV) {
  5528. + DPRINTK("%s(): Invalid input parameters - "
  5529. + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
  5530. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  5531. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  5532. + krp->krp_status = ECANCELED;
  5533. + crypto_kdone(krp);
  5534. + return;
  5535. + }
  5536. +
  5537. + if (CPA_STATUS_SUCCESS == status) {
  5538. + krp->krp_status = CRYPTO_OP_SUCCESS;
  5539. + } else {
  5540. + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
  5541. + "Operation Status = %d\n", __FUNCTION__, status);
  5542. + krp->krp_status = ECANCELED;
  5543. + }
  5544. +
  5545. + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
  5546. + pLocalOctetStringPV->dataLenInBytes);
  5547. +
  5548. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  5549. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  5550. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  5551. +
  5552. + crypto_kdone(krp);
  5553. +
  5554. + return;
  5555. +}
  5556. +
  5557. +/* Name : icp_ocfDrvModExpCallBack
  5558. + *
  5559. + * Description : When this function returns it signifies that the LAC
  5560. + * component has completed the Mod Exp operation.
  5561. + */
  5562. +static void
  5563. +icp_ocfDrvModExpCallBack(void *callbackTag,
  5564. + CpaStatus status,
  5565. + void *pOpdata, CpaFlatBuffer * pResult)
  5566. +{
  5567. + struct cryptkop *krp = NULL;
  5568. + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
  5569. +
  5570. + if (NULL == callbackTag) {
  5571. + DPRINTK("%s(): Invalid input parameters - "
  5572. + "callbackTag data is NULL\n", __FUNCTION__);
  5573. + return;
  5574. + }
  5575. + krp = (struct cryptkop *)callbackTag;
  5576. +
  5577. + if (NULL == pOpdata) {
  5578. + DPRINTK("%s(): Invalid Mod Exp input parameters - "
  5579. + "Operation Data is NULL\n", __FUNCTION__);
  5580. + krp->krp_status = ECANCELED;
  5581. + crypto_kdone(krp);
  5582. + return;
  5583. + }
  5584. + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
  5585. +
  5586. + if (NULL == pResult) {
  5587. + DPRINTK("%s(): Invalid input parameters - "
  5588. + "pResult data is NULL\n", __FUNCTION__);
  5589. + krp->krp_status = ECANCELED;
  5590. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  5591. + kmem_cache_free(drvLnModExp_zone, pLnModExpOpData);
  5592. + crypto_kdone(krp);
  5593. + return;
  5594. + }
  5595. +
  5596. + if (CPA_STATUS_SUCCESS == status) {
  5597. + krp->krp_status = CRYPTO_OP_SUCCESS;
  5598. + } else {
  5599. + APRINTK("%s(): LAC Mod Exp Operation failed - "
  5600. + "Operation Status = %d\n", __FUNCTION__, status);
  5601. + krp->krp_status = ECANCELED;
  5602. + }
  5603. +
  5604. + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
  5605. +
  5606. + /*switch base size value back to original */
  5607. + if (pLnModExpOpData->base.pData ==
  5608. + (uint8_t *) & (krp->
  5609. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  5610. + crp_nbits)) {
  5611. + *((uint32_t *) pLnModExpOpData->base.pData) =
  5612. + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
  5613. + }
  5614. + icp_ocfDrvFreeFlatBuffer(pResult);
  5615. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  5616. + kmem_cache_free(drvLnModExp_zone, pLnModExpOpData);
  5617. +
  5618. + crypto_kdone(krp);
  5619. +
  5620. + return;
  5621. +
  5622. +}
  5623. +
  5624. +/* Name : icp_ocfDrvModExpCRTCallBack
  5625. + *
  5626. + * Description : When this function returns it signifies that the LAC
  5627. + * component has completed the Mod Exp CRT operation.
  5628. + */
  5629. +static void
  5630. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  5631. + CpaStatus status,
  5632. + void *pOpData, CpaFlatBuffer * pOutputData)
  5633. +{
  5634. + struct cryptkop *krp = NULL;
  5635. + CpaCyRsaDecryptOpData *pDecryptData = NULL;
  5636. +
  5637. + if (NULL == callbackTag) {
  5638. + DPRINTK("%s(): Invalid input parameters - "
  5639. + "callbackTag data is NULL\n", __FUNCTION__);
  5640. + return;
  5641. + }
  5642. +
  5643. + krp = (struct cryptkop *)callbackTag;
  5644. +
  5645. + if (NULL == pOpData) {
  5646. + DPRINTK("%s(): Invalid input parameters - "
  5647. + "Operation Data is NULL\n", __FUNCTION__);
  5648. + krp->krp_status = ECANCELED;
  5649. + crypto_kdone(krp);
  5650. + return;
  5651. + }
  5652. + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
  5653. +
  5654. + if (NULL == pOutputData) {
  5655. + DPRINTK("%s(): Invalid input parameter - "
  5656. + "pOutputData is NULL\n", __FUNCTION__);
  5657. + memset(pDecryptData->pRecipientPrivateKey, 0,
  5658. + sizeof(CpaCyRsaPrivateKey));
  5659. + kmem_cache_free(drvRSAPrivateKey_zone,
  5660. + pDecryptData->pRecipientPrivateKey);
  5661. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  5662. + kmem_cache_free(drvRSADecrypt_zone, pDecryptData);
  5663. + krp->krp_status = ECANCELED;
  5664. + crypto_kdone(krp);
  5665. + return;
  5666. + }
  5667. +
  5668. + if (CPA_STATUS_SUCCESS == status) {
  5669. + krp->krp_status = CRYPTO_OP_SUCCESS;
  5670. + } else {
  5671. + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
  5672. + "Operation Status = %d\n", __FUNCTION__, status);
  5673. + krp->krp_status = ECANCELED;
  5674. + }
  5675. +
  5676. + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
  5677. +
  5678. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  5679. + memset(pDecryptData->pRecipientPrivateKey, 0,
  5680. + sizeof(CpaCyRsaPrivateKey));
  5681. + kmem_cache_free(drvRSAPrivateKey_zone,
  5682. + pDecryptData->pRecipientPrivateKey);
  5683. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  5684. + kmem_cache_free(drvRSADecrypt_zone, pDecryptData);
  5685. +
  5686. + crypto_kdone(krp);
  5687. +
  5688. + return;
  5689. +}
  5690. +
  5691. +/* Name : icp_ocfDrvDsaRSSignCallBack
  5692. + *
  5693. + * Description : When this function returns it signifies that the LAC
  5694. + * component has completed the DSA RS sign operation.
  5695. + */
  5696. +static void
  5697. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  5698. + CpaStatus status,
  5699. + void *pOpData,
  5700. + CpaBoolean protocolStatus,
  5701. + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
  5702. +{
  5703. + struct cryptkop *krp = NULL;
  5704. + CpaCyDsaRSSignOpData *pSignData = NULL;
  5705. +
  5706. + if (NULL == callbackTag) {
  5707. + DPRINTK("%s(): Invalid input parameters - "
  5708. + "callbackTag data is NULL\n", __FUNCTION__);
  5709. + return;
  5710. + }
  5711. +
  5712. + krp = (struct cryptkop *)callbackTag;
  5713. +
  5714. + if (NULL == pOpData) {
  5715. + DPRINTK("%s(): Invalid input parameters - "
  5716. + "Operation Data is NULL\n", __FUNCTION__);
  5717. + krp->krp_status = ECANCELED;
  5718. + crypto_kdone(krp);
  5719. + return;
  5720. + }
  5721. + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
  5722. +
  5723. + if (NULL == pR) {
  5724. + DPRINTK("%s(): Invalid input parameter - "
  5725. + "pR sign is NULL\n", __FUNCTION__);
  5726. + icp_ocfDrvFreeFlatBuffer(pS);
  5727. + kmem_cache_free(drvDSARSSign_zone, pSignData);
  5728. + krp->krp_status = ECANCELED;
  5729. + crypto_kdone(krp);
  5730. + return;
  5731. + }
  5732. +
  5733. + if (NULL == pS) {
  5734. + DPRINTK("%s(): Invalid input parameter - "
  5735. + "pS sign is NULL\n", __FUNCTION__);
  5736. + icp_ocfDrvFreeFlatBuffer(pR);
  5737. + kmem_cache_free(drvDSARSSign_zone, pSignData);
  5738. + krp->krp_status = ECANCELED;
  5739. + crypto_kdone(krp);
  5740. + return;
  5741. + }
  5742. +
  5743. + if (CPA_STATUS_SUCCESS != status) {
  5744. + APRINTK("%s(): LAC DSA RS Sign operation failed - "
  5745. + "Operation Status = %d\n", __FUNCTION__, status);
  5746. + krp->krp_status = ECANCELED;
  5747. + } else {
  5748. + krp->krp_status = CRYPTO_OP_SUCCESS;
  5749. +
  5750. + if (CPA_TRUE != protocolStatus) {
  5751. + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
  5752. + "to protocol error\n", __FUNCTION__);
  5753. + krp->krp_status = EIO;
  5754. + }
  5755. + }
  5756. +
  5757. + /* Swap bytes only when the callback status is successful and
  5758. + protocolStatus is set to true */
  5759. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
  5760. + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
  5761. + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
  5762. + }
  5763. +
  5764. + icp_ocfDrvFreeFlatBuffer(pR);
  5765. + icp_ocfDrvFreeFlatBuffer(pS);
  5766. + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
  5767. + kmem_cache_free(drvDSARSSignKValue_zone, pSignData->K.pData);
  5768. + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
  5769. + kmem_cache_free(drvDSARSSign_zone, pSignData);
  5770. + crypto_kdone(krp);
  5771. +
  5772. + return;
  5773. +}
  5774. +
  5775. +/* Name : icp_ocfDrvDsaVerifyCallback
  5776. + *
  5777. + * Description : When this function returns it signifies that the LAC
  5778. + * component has completed the DSA Verify operation.
  5779. + */
  5780. +static void
  5781. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  5782. + CpaStatus status,
  5783. + void *pOpData, CpaBoolean verifyStatus)
  5784. +{
  5785. +
  5786. + struct cryptkop *krp = NULL;
  5787. + CpaCyDsaVerifyOpData *pVerData = NULL;
  5788. +
  5789. + if (NULL == callbackTag) {
  5790. + DPRINTK("%s(): Invalid input parameters - "
  5791. + "callbackTag data is NULL\n", __FUNCTION__);
  5792. + return;
  5793. + }
  5794. +
  5795. + krp = (struct cryptkop *)callbackTag;
  5796. +
  5797. + if (NULL == pOpData) {
  5798. + DPRINTK("%s(): Invalid input parameters - "
  5799. + "Operation Data is NULL\n", __FUNCTION__);
  5800. + krp->krp_status = ECANCELED;
  5801. + crypto_kdone(krp);
  5802. + return;
  5803. + }
  5804. + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
  5805. +
  5806. + if (CPA_STATUS_SUCCESS != status) {
  5807. + APRINTK("%s(): LAC DSA Verify operation failed - "
  5808. + "Operation Status = %d\n", __FUNCTION__, status);
  5809. + krp->krp_status = ECANCELED;
  5810. + } else {
  5811. + krp->krp_status = CRYPTO_OP_SUCCESS;
  5812. +
  5813. + if (CPA_TRUE != verifyStatus) {
  5814. + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
  5815. + krp->krp_status = EIO;
  5816. + }
  5817. + }
  5818. +
  5819. + /* Swap bytes only when the callback status is successful and
  5820. + verifyStatus is set to true */
  5821. + /*Just swapping back the key values for now. Possibly all
  5822. + swapped buffers need to be reverted */
  5823. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
  5824. + icp_ocfDrvSwapBytes(pVerData->R.pData,
  5825. + pVerData->R.dataLenInBytes);
  5826. + icp_ocfDrvSwapBytes(pVerData->S.pData,
  5827. + pVerData->S.dataLenInBytes);
  5828. + }
  5829. +
  5830. + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
  5831. + kmem_cache_free(drvDSAVerify_zone, pVerData);
  5832. + crypto_kdone(krp);
  5833. +
  5834. + return;
  5835. +}
  5836. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.27.10/crypto/ocf/ep80579/icp_common.c
  5837. --- linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
  5838. +++ linux-2.6.27.10/crypto/ocf/ep80579/icp_common.c 2008-12-23 19:31:44.000000000 +0100
  5839. @@ -0,0 +1,891 @@
  5840. +/***************************************************************************
  5841. + *
  5842. + * This file is provided under a dual BSD/GPLv2 license. When using or
  5843. + * redistributing this file, you may do so under either license.
  5844. + *
  5845. + * GPL LICENSE SUMMARY
  5846. + *
  5847. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  5848. + *
  5849. + * This program is free software; you can redistribute it and/or modify
  5850. + * it under the terms of version 2 of the GNU General Public License as
  5851. + * published by the Free Software Foundation.
  5852. + *
  5853. + * This program is distributed in the hope that it will be useful, but
  5854. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  5855. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  5856. + * General Public License for more details.
  5857. + *
  5858. + * You should have received a copy of the GNU General Public License
  5859. + * along with this program; if not, write to the Free Software
  5860. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  5861. + * The full GNU General Public License is included in this distribution
  5862. + * in the file called LICENSE.GPL.
  5863. + *
  5864. + * Contact Information:
  5865. + * Intel Corporation
  5866. + *
  5867. + * BSD LICENSE
  5868. + *
  5869. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  5870. + * All rights reserved.
  5871. + *
  5872. + * Redistribution and use in source and binary forms, with or without
  5873. + * modification, are permitted provided that the following conditions
  5874. + * are met:
  5875. + *
  5876. + * * Redistributions of source code must retain the above copyright
  5877. + * notice, this list of conditions and the following disclaimer.
  5878. + * * Redistributions in binary form must reproduce the above copyright
  5879. + * notice, this list of conditions and the following disclaimer in
  5880. + * the documentation and/or other materials provided with the
  5881. + * distribution.
  5882. + * * Neither the name of Intel Corporation nor the names of its
  5883. + * contributors may be used to endorse or promote products derived
  5884. + * from this software without specific prior written permission.
  5885. + *
  5886. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  5887. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5888. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  5889. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  5890. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  5891. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  5892. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  5893. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  5894. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  5895. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  5896. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5897. + *
  5898. + *
  5899. + * version: Security.L.1.0.130
  5900. + *
  5901. + ***************************************************************************/
  5902. +
  5903. +/*
  5904. + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  5905. + * crypto.
  5906. + *
  5907. + * This driver requires the ICP Access Library that is available from Intel in
  5908. + * order to operate.
  5909. + */
  5910. +
  5911. +#include "icp_ocf.h"
  5912. +
  5913. +#define ICP_OCF_COMP_NAME "ICP_OCF"
  5914. +#define ICP_OCF_VER_MAIN (2)
  5915. +#define ICP_OCF_VER_MJR (0)
  5916. +#define ICP_OCF_VER_MNR (0)
  5917. +
  5918. +#define MAX_DEREG_RETRIES (100)
  5919. +#define DEFAULT_DEREG_RETRIES (10)
  5920. +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  5921. +
  5922. +/* This defines the maximum number of sessions possible between OCF
  5923. + and the OCF Tolapai Driver. If set to zero, there is no limit. */
  5924. +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  5925. +#define NUM_SUPPORTED_CAPABILITIES (21)
  5926. +
  5927. +/*Slabs zones*/
  5928. +struct kmem_cache *drvSessionData_zone = NULL;
  5929. +struct kmem_cache *drvOpData_zone = NULL;
  5930. +struct kmem_cache *drvDH_zone = NULL;
  5931. +struct kmem_cache *drvLnModExp_zone = NULL;
  5932. +struct kmem_cache *drvRSADecrypt_zone = NULL;
  5933. +struct kmem_cache *drvRSAPrivateKey_zone = NULL;
  5934. +struct kmem_cache *drvDSARSSign_zone = NULL;
  5935. +struct kmem_cache *drvDSARSSignKValue_zone = NULL;
  5936. +struct kmem_cache *drvDSAVerify_zone = NULL;
  5937. +
  5938. +/*Slab zones for flatbuffers and bufferlist*/
  5939. +struct kmem_cache *drvFlatBuffer_zone = NULL;
  5940. +
  5941. +static int icp_ocfDrvInit(void);
  5942. +static void icp_ocfDrvExit(void);
  5943. +static void icp_ocfDrvFreeCaches(void);
  5944. +static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
  5945. +
  5946. +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  5947. +
  5948. +/* Module parameter - gives the number of times LAC deregistration shall be
  5949. + re-tried */
  5950. +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  5951. +
  5952. +/* Module parameter - gives the delay time in jiffies before a LAC session
  5953. + shall be attempted to be deregistered again */
  5954. +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  5955. +
  5956. +/* Module parameter - gives the maximum number of sessions possible between
  5957. + OCF and the OCF Tolapai Driver. If set to zero, there is no limit.*/
  5958. +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  5959. +
  5960. +/* This is set when the module is removed from the system, no further
  5961. + processing can take place if this is set */
  5962. +atomic_t icp_ocfDrvIsExiting = ATOMIC_INIT(0);
  5963. +
  5964. +/* This is used to show how many lac sessions were not deregistered*/
  5965. +atomic_t lac_session_failed_dereg_count = ATOMIC_INIT(0);
  5966. +
  5967. +/* This is used to track the number of registered sessions between OCF and
  5968. + * and the OCF Tolapai driver, when max_session is set to value other than
  5969. + * zero. This ensures that the max_session set for the OCF and the driver
  5970. + * is equal to the LAC registered sessions */
  5971. +atomic_t num_ocf_to_drv_registered_sessions = ATOMIC_INIT(0);
  5972. +
  5973. +/* Head of linked list used to store session data */
  5974. +struct list_head icp_ocfDrvGlobalSymListHead;
  5975. +struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
  5976. +
  5977. +spinlock_t icp_ocfDrvSymSessInfoListSpinlock = SPIN_LOCK_UNLOCKED;
  5978. +rwlock_t icp_kmem_cache_destroy_alloc_lock = RW_LOCK_UNLOCKED;
  5979. +
  5980. +struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
  5981. +
  5982. +struct icp_drvBuffListInfo defBuffListInfo;
  5983. +
  5984. +static struct {
  5985. + softc_device_decl sc_dev;
  5986. +} icpDev;
  5987. +
  5988. +static device_method_t icp_methods = {
  5989. + /* crypto device methods */
  5990. + DEVMETHOD(cryptodev_newsession, icp_ocfDrvNewSession),
  5991. + DEVMETHOD(cryptodev_freesession, icp_ocfDrvFreeLACSession),
  5992. + DEVMETHOD(cryptodev_process, icp_ocfDrvSymProcess),
  5993. + DEVMETHOD(cryptodev_kprocess, icp_ocfDrvPkeProcess),
  5994. +};
  5995. +
  5996. +module_param(num_dereg_retries, int, S_IRUGO);
  5997. +module_param(dereg_retry_delay_in_jiffies, int, S_IRUGO);
  5998. +module_param(max_sessions, int, S_IRUGO);
  5999. +
  6000. +MODULE_PARM_DESC(num_dereg_retries,
  6001. + "Number of times to retry LAC Sym Session Deregistration. "
  6002. + "Default 10, Max 100");
  6003. +MODULE_PARM_DESC(dereg_retry_delay_in_jiffies, "Delay in jiffies "
  6004. + "(added to a schedule() function call) before a LAC Sym "
  6005. + "Session Dereg is retried. Default 10");
  6006. +MODULE_PARM_DESC(max_sessions, "This sets the maximum number of sessions "
  6007. + "between OCF and this driver. If this value is set to zero, "
  6008. + "max session count checking is disabled. Default is zero(0)");
  6009. +
  6010. +/* Name : icp_ocfDrvInit
  6011. + *
  6012. + * Description : This function will register all the symmetric and asymmetric
  6013. + * functionality that will be accelerated by the hardware. It will also
  6014. + * get a unique driver ID from the OCF and initialise all slab caches
  6015. + */
  6016. +static int __init icp_ocfDrvInit(void)
  6017. +{
  6018. + int ocfStatus = 0;
  6019. +
  6020. + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  6021. + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  6022. +
  6023. + if (MAX_DEREG_RETRIES < num_dereg_retries) {
  6024. + EPRINTK("Session deregistration retry count set to greater "
  6025. + "than %d", MAX_DEREG_RETRIES);
  6026. + return -1;
  6027. + }
  6028. +
  6029. + /* Initialize and Start the Cryptographic component */
  6030. + if (CPA_STATUS_SUCCESS !=
  6031. + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  6032. + EPRINTK("Failed to initialize and start the instance "
  6033. + "of the Cryptographic component.\n");
  6034. + return -1;
  6035. + }
  6036. +
  6037. + /* Set the default size of BufferList to allocate */
  6038. + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  6039. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  6040. + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  6041. + &defBuffListInfo)) {
  6042. + EPRINTK("Failed to get bufferlist memory info.\n");
  6043. + return -1;
  6044. + }
  6045. +
  6046. + /*Register OCF Tolapai Driver with OCF */
  6047. + memset(&icpDev, 0, sizeof(icpDev));
  6048. + softc_device_init(&icpDev, "icp", 0, icp_methods);
  6049. +
  6050. + icp_ocfDrvDriverId = crypto_get_driverid(softc_get_device(&icpDev),
  6051. + CRYPTOCAP_F_HARDWARE);
  6052. +
  6053. + if (icp_ocfDrvDriverId < 0) {
  6054. + EPRINTK("%s : ICP driver failed to register with OCF!\n",
  6055. + __FUNCTION__);
  6056. + return -ENODEV;
  6057. + }
  6058. +
  6059. + /*Create all the slab caches used by the OCF Tolapai Driver */
  6060. + drvSessionData_zone =
  6061. + ICP_CACHE_CREATE("ICP Session Data", struct icp_drvSessionData);
  6062. + ICP_CACHE_NULL_CHECK(drvSessionData_zone);
  6063. +
  6064. + /*
  6065. + * Allocation of the OpData includes the allocation space for meta data.
  6066. + * The memory after the opData structure is reserved for this meta data.
  6067. + */
  6068. + drvOpData_zone =
  6069. + kmem_cache_create("ICP Op Data", sizeof(struct icp_drvOpData) +
  6070. + defBuffListInfo.metaSize ,0, SLAB_HWCACHE_ALIGN, NULL, NULL);
  6071. +
  6072. +
  6073. + ICP_CACHE_NULL_CHECK(drvOpData_zone);
  6074. +
  6075. + drvDH_zone = ICP_CACHE_CREATE("ICP DH data", CpaCyDhPhase1KeyGenOpData);
  6076. + ICP_CACHE_NULL_CHECK(drvDH_zone);
  6077. +
  6078. + drvLnModExp_zone =
  6079. + ICP_CACHE_CREATE("ICP ModExp data", CpaCyLnModExpOpData);
  6080. + ICP_CACHE_NULL_CHECK(drvLnModExp_zone);
  6081. +
  6082. + drvRSADecrypt_zone =
  6083. + ICP_CACHE_CREATE("ICP RSA decrypt data", CpaCyRsaDecryptOpData);
  6084. + ICP_CACHE_NULL_CHECK(drvRSADecrypt_zone);
  6085. +
  6086. + drvRSAPrivateKey_zone =
  6087. + ICP_CACHE_CREATE("ICP RSA private key data", CpaCyRsaPrivateKey);
  6088. + ICP_CACHE_NULL_CHECK(drvRSAPrivateKey_zone);
  6089. +
  6090. + drvDSARSSign_zone =
  6091. + ICP_CACHE_CREATE("ICP DSA Sign", CpaCyDsaRSSignOpData);
  6092. + ICP_CACHE_NULL_CHECK(drvDSARSSign_zone);
  6093. +
  6094. + /*too awkward to use a macro here */
  6095. + drvDSARSSignKValue_zone =
  6096. + kmem_cache_create("ICP DSA Sign Rand Val",
  6097. + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES, 0,
  6098. + SLAB_HWCACHE_ALIGN, NULL, NULL);
  6099. + ICP_CACHE_NULL_CHECK(drvDSARSSignKValue_zone);
  6100. +
  6101. + drvDSAVerify_zone =
  6102. + ICP_CACHE_CREATE("ICP DSA Verify", CpaCyDsaVerifyOpData);
  6103. + ICP_CACHE_NULL_CHECK(drvDSAVerify_zone);
  6104. +
  6105. + drvFlatBuffer_zone =
  6106. + ICP_CACHE_CREATE("ICP Flat Buffers", CpaFlatBuffer);
  6107. + ICP_CACHE_NULL_CHECK(drvFlatBuffer_zone);
  6108. +
  6109. + /* Register the ICP symmetric crypto support. */
  6110. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_NULL_CBC);
  6111. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_DES_CBC);
  6112. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_3DES_CBC);
  6113. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_AES_CBC);
  6114. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_ARC4);
  6115. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5);
  6116. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5_HMAC);
  6117. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1);
  6118. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1_HMAC);
  6119. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256);
  6120. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256_HMAC);
  6121. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384);
  6122. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384_HMAC);
  6123. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512);
  6124. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512_HMAC);
  6125. +
  6126. + /* Register the ICP asymmetric algorithm support */
  6127. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DH_COMPUTE_KEY);
  6128. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP);
  6129. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP_CRT);
  6130. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_SIGN);
  6131. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_VERIFY);
  6132. +
  6133. + /* Register the ICP random number generator support */
  6134. + if (OCF_REGISTRATION_STATUS_SUCCESS ==
  6135. + crypto_rregister(icp_ocfDrvDriverId, icp_ocfDrvReadRandom, NULL)) {
  6136. + ocfStatus++;
  6137. + }
  6138. +
  6139. + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  6140. + DPRINTK("%s: Failed to register any device capabilities\n",
  6141. + __FUNCTION__);
  6142. + icp_ocfDrvFreeCaches();
  6143. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  6144. + return -ECANCELED;
  6145. + }
  6146. +
  6147. + DPRINTK("%s: Registered %d of %d device capabilities\n",
  6148. + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  6149. +
  6150. +/*Session data linked list used during module exit*/
  6151. + INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  6152. + INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  6153. +
  6154. + icp_ocfDrvFreeLacSessionWorkQ =
  6155. + create_singlethread_workqueue("ocfLacDeregWorkQueue");
  6156. +
  6157. + return 0;
  6158. +}
  6159. +
  6160. +/* Name : icp_ocfDrvExit
  6161. + *
  6162. + * Description : This function will deregister all the symmetric sessions
  6163. + * registered with the LAC component. It will also deregister all symmetric
  6164. + * and asymmetric functionality that can be accelerated by the hardware via OCF
  6165. + * and random number generation if it is enabled.
  6166. + */
  6167. +static void icp_ocfDrvExit(void)
  6168. +{
  6169. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  6170. + struct icp_drvSessionData *sessionData = NULL;
  6171. + struct icp_drvSessionData *tempSessionData = NULL;
  6172. + int i, remaining_delay_time_in_jiffies = 0;
  6173. + /* There is a possibility of a process or new session command being */
  6174. + /* sent before this variable is incremented. The aim of this variable */
  6175. + /* is to stop a loop of calls creating a deadlock situation which */
  6176. + /* would prevent the driver from exiting. */
  6177. +
  6178. + atomic_inc(&icp_ocfDrvIsExiting);
  6179. +
  6180. + /*Existing sessions will be routed to another driver after these calls */
  6181. + crypto_unregister_all(icp_ocfDrvDriverId);
  6182. + crypto_runregister_all(icp_ocfDrvDriverId);
  6183. +
  6184. + /*If any sessions are waiting to be deregistered, do that. This also
  6185. + flushes the work queue */
  6186. + destroy_workqueue(icp_ocfDrvFreeLacSessionWorkQ);
  6187. +
  6188. + /*ENTER CRITICAL SECTION */
  6189. + spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  6190. + list_for_each_entry_safe(tempSessionData, sessionData,
  6191. + &icp_ocfDrvGlobalSymListHead, listNode) {
  6192. + for (i = 0; i < num_dereg_retries; i++) {
  6193. + /*No harm if bad input - LAC will handle error cases */
  6194. + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  6195. + lacStatus =
  6196. + cpaCySymRemoveSession
  6197. + (CPA_INSTANCE_HANDLE_SINGLE,
  6198. + tempSessionData->sessHandle);
  6199. + if (CPA_STATUS_SUCCESS == lacStatus) {
  6200. + /* Succesfully deregistered */
  6201. + break;
  6202. + } else if (CPA_STATUS_RETRY != lacStatus) {
  6203. + atomic_inc
  6204. + (&lac_session_failed_dereg_count);
  6205. + break;
  6206. + }
  6207. +
  6208. + /*schedule_timout returns the time left for completion if
  6209. + * this task is set to TASK_INTERRUPTIBLE */
  6210. + remaining_delay_time_in_jiffies =
  6211. + dereg_retry_delay_in_jiffies;
  6212. + while (0 > remaining_delay_time_in_jiffies) {
  6213. + remaining_delay_time_in_jiffies =
  6214. + schedule_timeout
  6215. + (remaining_delay_time_in_jiffies);
  6216. + }
  6217. +
  6218. + DPRINTK
  6219. + ("%s(): Retry %d to deregistrate the session\n",
  6220. + __FUNCTION__, i);
  6221. + }
  6222. + }
  6223. +
  6224. + /*remove from current list */
  6225. + list_del(&(tempSessionData->listNode));
  6226. + /*add to free mem linked list */
  6227. + list_add(&(tempSessionData->listNode),
  6228. + &icp_ocfDrvGlobalSymListHead_FreeMemList);
  6229. +
  6230. + }
  6231. +
  6232. + /*EXIT CRITICAL SECTION */
  6233. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  6234. +
  6235. + /*set back to initial values */
  6236. + sessionData = NULL;
  6237. + /*still have a reference in our list! */
  6238. + tempSessionData = NULL;
  6239. + /*free memory */
  6240. + list_for_each_entry_safe(tempSessionData, sessionData,
  6241. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  6242. + listNode) {
  6243. +
  6244. + list_del(&(tempSessionData->listNode));
  6245. + /* Free allocated CpaCySymSessionCtx */
  6246. + if (NULL != tempSessionData->sessHandle) {
  6247. + kfree(tempSessionData->sessHandle);
  6248. + }
  6249. + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  6250. + kmem_cache_free(drvSessionData_zone, tempSessionData);
  6251. + }
  6252. +
  6253. + if (0 != atomic_read(&lac_session_failed_dereg_count)) {
  6254. + DPRINTK("%s(): %d LAC sessions were not deregistered "
  6255. + "correctly. This is not a clean exit! \n",
  6256. + __FUNCTION__,
  6257. + atomic_read(&lac_session_failed_dereg_count));
  6258. + }
  6259. +
  6260. + icp_ocfDrvFreeCaches();
  6261. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  6262. +
  6263. + /* Shutdown the Cryptographic component */
  6264. + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  6265. + if (CPA_STATUS_SUCCESS != lacStatus) {
  6266. + DPRINTK("%s(): Failed to stop instance of the "
  6267. + "Cryptographic component.(status == %d)\n",
  6268. + __FUNCTION__, lacStatus);
  6269. + }
  6270. +
  6271. +}
  6272. +
  6273. +/* Name : icp_ocfDrvFreeCaches
  6274. + *
  6275. + * Description : This function deregisters all slab caches
  6276. + */
  6277. +static void icp_ocfDrvFreeCaches(void)
  6278. +{
  6279. + if (atomic_read(&icp_ocfDrvIsExiting) != CPA_TRUE) {
  6280. + atomic_set(&icp_ocfDrvIsExiting, 1);
  6281. + }
  6282. +
  6283. + /*Sym Zones */
  6284. + ICP_CACHE_DESTROY(drvSessionData_zone);
  6285. + ICP_CACHE_DESTROY(drvOpData_zone);
  6286. +
  6287. + /*Asym zones */
  6288. + ICP_CACHE_DESTROY(drvDH_zone);
  6289. + ICP_CACHE_DESTROY(drvLnModExp_zone);
  6290. + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  6291. + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  6292. + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  6293. + ICP_CACHE_DESTROY(drvDSARSSign_zone);
  6294. + ICP_CACHE_DESTROY(drvDSAVerify_zone);
  6295. +
  6296. + /*FlatBuffer and BufferList Zones */
  6297. + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  6298. +
  6299. +}
  6300. +
  6301. +/* Name : icp_ocfDrvDeregRetry
  6302. + *
  6303. + * Description : This function will try to farm the session deregistration
  6304. + * off to a work queue. If it fails, nothing more can be done and it
  6305. + * returns an error
  6306. + */
  6307. +
  6308. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  6309. +{
  6310. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  6311. +
  6312. + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  6313. + __FUNCTION__, sessionToDeregister);
  6314. +
  6315. + /*make sure the session is not available to be allocated during this
  6316. + process */
  6317. + atomic_inc(&lac_session_failed_dereg_count);
  6318. +
  6319. + /*Farm off to work queue */
  6320. + workstore =
  6321. + kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), GFP_ATOMIC);
  6322. + if (NULL == workstore) {
  6323. + DPRINTK("%s(): unable to free session - no memory available "
  6324. + "for work queue\n", __FUNCTION__);
  6325. + return ENOMEM;
  6326. + }
  6327. +
  6328. + workstore->sessionToDeregister = sessionToDeregister;
  6329. +
  6330. + INIT_WORK(&(workstore->work), icp_ocfDrvDeferedFreeLacSessionProcess,
  6331. + workstore);
  6332. + queue_work(icp_ocfDrvFreeLacSessionWorkQ, &(workstore->work));
  6333. +
  6334. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6335. +
  6336. +}
  6337. +
  6338. +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  6339. + *
  6340. + * Description : This function will retry (module input parameter)
  6341. + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  6342. + * CPA_STATUS_RETRY message from the LAC component. This function is run in
  6343. + * Thread context because it is called from a worker thread
  6344. + */
  6345. +static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  6346. +{
  6347. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  6348. + CpaCySymSessionCtx sessionToDeregister = NULL;
  6349. + int i = 0;
  6350. + int remaining_delay_time_in_jiffies = 0;
  6351. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  6352. +
  6353. + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  6354. + if (NULL == workstore) {
  6355. + DPRINTK("%s() function called with null parameter \n",
  6356. + __FUNCTION__);
  6357. + return;
  6358. + }
  6359. +
  6360. + sessionToDeregister = workstore->sessionToDeregister;
  6361. + kfree(workstore);
  6362. +
  6363. + /*if exiting, give deregistration one more blast only */
  6364. + if (atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  6365. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  6366. + sessionToDeregister);
  6367. +
  6368. + if (lacStatus != CPA_STATUS_SUCCESS) {
  6369. + DPRINTK("%s() Failed to Dereg LAC session %p "
  6370. + "during module exit\n", __FUNCTION__,
  6371. + sessionToDeregister);
  6372. + return;
  6373. + }
  6374. +
  6375. + atomic_dec(&lac_session_failed_dereg_count);
  6376. + return;
  6377. + }
  6378. +
  6379. + for (i = 0; i <= num_dereg_retries; i++) {
  6380. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  6381. + sessionToDeregister);
  6382. +
  6383. + if (lacStatus == CPA_STATUS_SUCCESS) {
  6384. + atomic_dec(&lac_session_failed_dereg_count);
  6385. + return;
  6386. + }
  6387. + if (lacStatus != CPA_STATUS_RETRY) {
  6388. + DPRINTK("%s() Failed to deregister session - lacStatus "
  6389. + " = %d", __FUNCTION__, lacStatus);
  6390. + break;
  6391. + }
  6392. +
  6393. + /*schedule_timout returns the time left for completion if this
  6394. + task is set to TASK_INTERRUPTIBLE */
  6395. + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  6396. + while (0 > remaining_delay_time_in_jiffies) {
  6397. + remaining_delay_time_in_jiffies =
  6398. + schedule_timeout(remaining_delay_time_in_jiffies);
  6399. + }
  6400. +
  6401. + }
  6402. +
  6403. + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  6404. + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  6405. + atomic_read(&lac_session_failed_dereg_count));
  6406. +}
  6407. +
  6408. +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  6409. + *
  6410. + * Description : This function converts a "pointer and length" buffer
  6411. + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  6412. + *
  6413. + * This function assumes that the data passed in are valid.
  6414. + */
  6415. +inline void
  6416. +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  6417. + CpaFlatBuffer * pFlatBuffer)
  6418. +{
  6419. + pFlatBuffer->pData = pData;
  6420. + pFlatBuffer->dataLenInBytes = len;
  6421. +}
  6422. +
  6423. +/* Name : icp_ocfDrvSingleSkBuffToFlatBuffer
  6424. + *
  6425. + * Description : This function converts a single socket buffer (sk_buff)
  6426. + * structure to a Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  6427. + *
  6428. + * This function assumes that the data passed in are valid.
  6429. + */
  6430. +static inline void
  6431. +icp_ocfDrvSingleSkBuffToFlatBuffer(struct sk_buff *pSkb,
  6432. + CpaFlatBuffer * pFlatBuffer)
  6433. +{
  6434. + pFlatBuffer->pData = pSkb->data;
  6435. + pFlatBuffer->dataLenInBytes = skb_headlen(pSkb);
  6436. +}
  6437. +
  6438. +/* Name : icp_ocfDrvSkBuffToBufferList
  6439. + *
  6440. + * Description : This function converts a socket buffer (sk_buff) structure to
  6441. + * Fredericksburg Scatter/Gather (CpaBufferList) buffer format.
  6442. + *
  6443. + * This function assumes that the bufferlist has been allocated with the correct
  6444. + * number of buffer arrays.
  6445. + *
  6446. + */
  6447. +inline int
  6448. +icp_ocfDrvSkBuffToBufferList(struct sk_buff *pSkb, CpaBufferList * bufferList)
  6449. +{
  6450. + CpaFlatBuffer *curFlatBuffer = NULL;
  6451. + char *skbuffPageAddr = NULL;
  6452. + struct sk_buff *pCurFrag = NULL;
  6453. + struct skb_shared_info *pShInfo = NULL;
  6454. + uint32_t page_offset = 0, i = 0;
  6455. +
  6456. + DPRINTK("%s(): Entry Point\n", __FUNCTION__);
  6457. +
  6458. + /*
  6459. + * In all cases, the first skb needs to be translated to FlatBuffer.
  6460. + * Perform a buffer translation for the first skbuff
  6461. + */
  6462. + curFlatBuffer = bufferList->pBuffers;
  6463. + icp_ocfDrvSingleSkBuffToFlatBuffer(pSkb, curFlatBuffer);
  6464. +
  6465. + /* Set the userData to point to the original sk_buff */
  6466. + bufferList->pUserData = (void *)pSkb;
  6467. +
  6468. + /* We now know we'll have at least one element in the SGL */
  6469. + bufferList->numBuffers = 1;
  6470. +
  6471. + if (0 == skb_is_nonlinear(pSkb)) {
  6472. + /* Is a linear buffer - therefore it's a single skbuff */
  6473. + DPRINTK("%s(): Exit Point\n", __FUNCTION__);
  6474. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6475. + }
  6476. +
  6477. + curFlatBuffer++;
  6478. + pShInfo = skb_shinfo(pSkb);
  6479. + if (pShInfo->frag_list != NULL && pShInfo->nr_frags != 0) {
  6480. + EPRINTK("%s():"
  6481. + "Translation for a combination of frag_list "
  6482. + "and frags[] array not supported!\n", __FUNCTION__);
  6483. + return ICP_OCF_DRV_STATUS_FAIL;
  6484. + } else if (pShInfo->frag_list != NULL) {
  6485. + /*
  6486. + * Non linear skbuff supported through frag_list
  6487. + * Perform translation for each fragment (sk_buff)
  6488. + * in the frag_list of the first sk_buff.
  6489. + */
  6490. + for (pCurFrag = pShInfo->frag_list;
  6491. + pCurFrag != NULL; pCurFrag = pCurFrag->next) {
  6492. + icp_ocfDrvSingleSkBuffToFlatBuffer(pCurFrag,
  6493. + curFlatBuffer);
  6494. + curFlatBuffer++;
  6495. + bufferList->numBuffers++;
  6496. + }
  6497. + } else if (pShInfo->nr_frags != 0) {
  6498. + /*
  6499. + * Perform translation for each fragment in frags array
  6500. + * and add to the BufferList
  6501. + */
  6502. + for (i = 0; i < pShInfo->nr_frags; i++) {
  6503. + /* Get the page address and offset of this frag */
  6504. + skbuffPageAddr = (char *)pShInfo->frags[i].page;
  6505. + page_offset = pShInfo->frags[i].page_offset;
  6506. +
  6507. + /* Convert a pointer and length to a flat buffer */
  6508. + icp_ocfDrvPtrAndLenToFlatBuffer(skbuffPageAddr +
  6509. + page_offset,
  6510. + pShInfo->frags[i].size,
  6511. + curFlatBuffer);
  6512. + curFlatBuffer++;
  6513. + bufferList->numBuffers++;
  6514. + }
  6515. + } else {
  6516. + EPRINTK("%s():" "Could not recognize skbuff fragments!\n",
  6517. + __FUNCTION__);
  6518. + return ICP_OCF_DRV_STATUS_FAIL;
  6519. + }
  6520. +
  6521. + DPRINTK("%s(): Exit Point\n", __FUNCTION__);
  6522. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6523. +}
  6524. +
  6525. +/* Name : icp_ocfDrvBufferListToSkBuff
  6526. + *
  6527. + * Description : This function converts a Fredericksburg Scatter/Gather
  6528. + * (CpaBufferList) buffer format to socket buffer structure.
  6529. + */
  6530. +inline int
  6531. +icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList, struct sk_buff **skb)
  6532. +{
  6533. + DPRINTK("%s(): Entry Point\n", __FUNCTION__);
  6534. +
  6535. + /* Retrieve the orignal skbuff */
  6536. + *skb = (struct sk_buff *)bufferList->pUserData;
  6537. + if (NULL == *skb) {
  6538. + EPRINTK("%s():"
  6539. + "Error on converting from a BufferList. "
  6540. + "The BufferList does not contain an sk_buff.\n",
  6541. + __FUNCTION__);
  6542. + return ICP_OCF_DRV_STATUS_FAIL;
  6543. + }
  6544. + DPRINTK("%s(): Exit Point\n", __FUNCTION__);
  6545. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6546. +}
  6547. +
  6548. +/* Name : icp_ocfDrvPtrAndLenToBufferList
  6549. + *
  6550. + * Description : This function converts a "pointer and length" buffer
  6551. + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  6552. + *
  6553. + * This function assumes that the data passed in are valid.
  6554. + */
  6555. +inline void
  6556. +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  6557. + CpaBufferList * pBufferList)
  6558. +{
  6559. + pBufferList->numBuffers = 1;
  6560. + pBufferList->pBuffers->pData = pDataIn;
  6561. + pBufferList->pBuffers->dataLenInBytes = length;
  6562. +}
  6563. +
  6564. +/* Name : icp_ocfDrvBufferListToPtrAndLen
  6565. + *
  6566. + * Description : This function converts Fredericksburg Scatter/Gather Buffer
  6567. + * (CpaBufferList) format to a "pointer and length" buffer structure.
  6568. + *
  6569. + * This function assumes that the data passed in are valid.
  6570. + */
  6571. +inline void
  6572. +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  6573. + void **ppDataOut, uint32_t * pLength)
  6574. +{
  6575. + *ppDataOut = pBufferList->pBuffers->pData;
  6576. + *pLength = pBufferList->pBuffers->dataLenInBytes;
  6577. +}
  6578. +
  6579. +/* Name : icp_ocfDrvBufferListMemInfo
  6580. + *
  6581. + * Description : This function will set the number of flat buffers in
  6582. + * bufferlist, the size of memory to allocate for the pPrivateMetaData
  6583. + * member of the CpaBufferList.
  6584. + */
  6585. +int
  6586. +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  6587. + struct icp_drvBuffListInfo *buffListInfo)
  6588. +{
  6589. + buffListInfo->numBuffers = numBuffers;
  6590. +
  6591. + if (CPA_STATUS_SUCCESS !=
  6592. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  6593. + buffListInfo->numBuffers,
  6594. + &(buffListInfo->metaSize))) {
  6595. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  6596. + __FUNCTION__);
  6597. + return ICP_OCF_DRV_STATUS_FAIL;
  6598. + }
  6599. +
  6600. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6601. +}
  6602. +
  6603. +/* Name : icp_ocfDrvGetSkBuffFrags
  6604. + *
  6605. + * Description : This function will determine the number of
  6606. + * fragments in a socket buffer(sk_buff).
  6607. + */
  6608. +inline uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff * pSkb)
  6609. +{
  6610. + uint16_t numFrags = 0;
  6611. + struct sk_buff *pCurFrag = NULL;
  6612. + struct skb_shared_info *pShInfo = NULL;
  6613. +
  6614. + if (NULL == pSkb)
  6615. + return 0;
  6616. +
  6617. + numFrags = 1;
  6618. + if (0 == skb_is_nonlinear(pSkb)) {
  6619. + /* Linear buffer - it's a single skbuff */
  6620. + return numFrags;
  6621. + }
  6622. +
  6623. + pShInfo = skb_shinfo(pSkb);
  6624. + if (NULL != pShInfo->frag_list && 0 != pShInfo->nr_frags) {
  6625. + EPRINTK("%s(): Combination of frag_list "
  6626. + "and frags[] array not supported!\n", __FUNCTION__);
  6627. + return 0;
  6628. + } else if (0 != pShInfo->nr_frags) {
  6629. + numFrags += pShInfo->nr_frags;
  6630. + return numFrags;
  6631. + } else if (NULL != pShInfo->frag_list) {
  6632. + for (pCurFrag = pShInfo->frag_list;
  6633. + pCurFrag != NULL; pCurFrag = pCurFrag->next) {
  6634. + numFrags++;
  6635. + }
  6636. + return numFrags;
  6637. + } else {
  6638. + return 0;
  6639. + }
  6640. +}
  6641. +
  6642. +/* Name : icp_ocfDrvFreeFlatBuffer
  6643. + *
  6644. + * Description : This function will deallocate flat buffer.
  6645. + */
  6646. +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  6647. +{
  6648. + if (pFlatBuffer != NULL) {
  6649. + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  6650. + kmem_cache_free(drvFlatBuffer_zone, pFlatBuffer);
  6651. + }
  6652. +}
  6653. +
  6654. +/* Name : icp_ocfDrvAllocMetaData
  6655. + *
  6656. + * Description : This function will allocate memory for the
  6657. + * pPrivateMetaData member of CpaBufferList.
  6658. + */
  6659. +inline int
  6660. +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  6661. + const struct icp_drvOpData *pOpData)
  6662. +{
  6663. + Cpa32U metaSize = 0;
  6664. +
  6665. + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS){
  6666. + void *pOpDataStartAddr = (void *)pOpData;
  6667. +
  6668. + if (0 == defBuffListInfo.metaSize) {
  6669. + pBufferList->pPrivateMetaData = NULL;
  6670. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6671. + }
  6672. + /*
  6673. + * The meta data allocation has been included as part of the
  6674. + * op data. It has been pre-allocated in memory just after the
  6675. + * icp_drvOpData structure.
  6676. + */
  6677. + pBufferList->pPrivateMetaData = pOpDataStartAddr +
  6678. + sizeof(struct icp_drvOpData);
  6679. + } else {
  6680. + if (CPA_STATUS_SUCCESS !=
  6681. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  6682. + pBufferList->numBuffers,
  6683. + &metaSize)) {
  6684. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  6685. + __FUNCTION__);
  6686. + return ICP_OCF_DRV_STATUS_FAIL;
  6687. + }
  6688. +
  6689. + if (0 == metaSize) {
  6690. + pBufferList->pPrivateMetaData = NULL;
  6691. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6692. + }
  6693. +
  6694. + pBufferList->pPrivateMetaData = kmalloc(metaSize, GFP_ATOMIC);
  6695. + }
  6696. + if (NULL == pBufferList->pPrivateMetaData) {
  6697. + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  6698. + __FUNCTION__);
  6699. + return ICP_OCF_DRV_STATUS_FAIL;
  6700. + }
  6701. +
  6702. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6703. +}
  6704. +
  6705. +/* Name : icp_ocfDrvFreeMetaData
  6706. + *
  6707. + * Description : This function will deallocate pPrivateMetaData memory.
  6708. + */
  6709. +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  6710. +{
  6711. + if (NULL == pBufferList->pPrivateMetaData) {
  6712. + return;
  6713. + }
  6714. +
  6715. + /*
  6716. + * Only free the meta data if the BufferList has more than
  6717. + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  6718. + * Otherwise, the meta data shall be freed when the icp_drvOpData is
  6719. + * freed.
  6720. + */
  6721. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers){
  6722. + kfree(pBufferList->pPrivateMetaData);
  6723. + }
  6724. +}
  6725. +
  6726. +module_init(icp_ocfDrvInit);
  6727. +module_exit(icp_ocfDrvExit);
  6728. +MODULE_LICENSE("Dual BSD/GPL");
  6729. +MODULE_AUTHOR("Intel");
  6730. +MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  6731. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.27.10/crypto/ocf/ep80579/icp_ocf.h
  6732. --- linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
  6733. +++ linux-2.6.27.10/crypto/ocf/ep80579/icp_ocf.h 2008-12-23 19:31:44.000000000 +0100
  6734. @@ -0,0 +1,363 @@
  6735. +/***************************************************************************
  6736. + *
  6737. + * This file is provided under a dual BSD/GPLv2 license. When using or
  6738. + * redistributing this file, you may do so under either license.
  6739. + *
  6740. + * GPL LICENSE SUMMARY
  6741. + *
  6742. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  6743. + *
  6744. + * This program is free software; you can redistribute it and/or modify
  6745. + * it under the terms of version 2 of the GNU General Public License as
  6746. + * published by the Free Software Foundation.
  6747. + *
  6748. + * This program is distributed in the hope that it will be useful, but
  6749. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  6750. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  6751. + * General Public License for more details.
  6752. + *
  6753. + * You should have received a copy of the GNU General Public License
  6754. + * along with this program; if not, write to the Free Software
  6755. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  6756. + * The full GNU General Public License is included in this distribution
  6757. + * in the file called LICENSE.GPL.
  6758. + *
  6759. + * Contact Information:
  6760. + * Intel Corporation
  6761. + *
  6762. + * BSD LICENSE
  6763. + *
  6764. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  6765. + * All rights reserved.
  6766. + *
  6767. + * Redistribution and use in source and binary forms, with or without
  6768. + * modification, are permitted provided that the following conditions
  6769. + * are met:
  6770. + *
  6771. + * * Redistributions of source code must retain the above copyright
  6772. + * notice, this list of conditions and the following disclaimer.
  6773. + * * Redistributions in binary form must reproduce the above copyright
  6774. + * notice, this list of conditions and the following disclaimer in
  6775. + * the documentation and/or other materials provided with the
  6776. + * distribution.
  6777. + * * Neither the name of Intel Corporation nor the names of its
  6778. + * contributors may be used to endorse or promote products derived
  6779. + * from this software without specific prior written permission.
  6780. + *
  6781. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6782. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  6783. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6784. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  6785. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  6786. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  6787. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  6788. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  6789. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  6790. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  6791. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  6792. + *
  6793. + *
  6794. + * version: Security.L.1.0.130
  6795. + *
  6796. + ***************************************************************************/
  6797. +
  6798. +/*
  6799. + * OCF drv driver header file for the Intel ICP processor.
  6800. + */
  6801. +
  6802. +#ifndef ICP_OCF_H
  6803. +#define ICP_OCF_H
  6804. +
  6805. +#include <linux/crypto.h>
  6806. +#include <linux/delay.h>
  6807. +#include <linux/skbuff.h>
  6808. +
  6809. +#include "cryptodev.h"
  6810. +#include "uio.h"
  6811. +
  6812. +#include "cpa.h"
  6813. +#include "cpa_cy_im.h"
  6814. +#include "cpa_cy_sym.h"
  6815. +#include "cpa_cy_rand.h"
  6816. +#include "cpa_cy_dh.h"
  6817. +#include "cpa_cy_rsa.h"
  6818. +#include "cpa_cy_ln.h"
  6819. +#include "cpa_cy_common.h"
  6820. +#include "cpa_cy_dsa.h"
  6821. +
  6822. +#define NUM_BITS_IN_BYTE (8)
  6823. +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
  6824. +#define INVALID_DRIVER_ID (-1)
  6825. +#define RETURN_RAND_NUM_GEN_FAILED (-1)
  6826. +
  6827. +/*This is define means only one operation can be chained to another
  6828. +(resulting in one chain of two operations)*/
  6829. +#define MAX_NUM_OF_CHAINED_OPS (1)
  6830. +/*This is the max block cipher initialisation vector*/
  6831. +#define MAX_IV_LEN_IN_BYTES (20)
  6832. +/*This is used to check whether the OCF to this driver session limit has
  6833. + been disabled*/
  6834. +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
  6835. +
  6836. +/*OCF values mapped here*/
  6837. +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
  6838. +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
  6839. +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
  6840. +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
  6841. +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
  6842. +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
  6843. +
  6844. +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
  6845. +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
  6846. +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
  6847. +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
  6848. +#define ICP_OCF_DRV_STATUS_FAIL (1)
  6849. +
  6850. +/*Turn on/off debug options*/
  6851. +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
  6852. +#define ICP_OCF_PRINT_KERN_ALERT (1)
  6853. +#define ICP_OCF_PRINT_KERN_ERRS (1)
  6854. +
  6855. +/*DSA Prime Q size in bytes (as defined in the standard) */
  6856. +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
  6857. +
  6858. +/*MACRO DEFINITIONS*/
  6859. +
  6860. +#define BITS_TO_BYTES(bytes, bits) \
  6861. + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
  6862. +
  6863. +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
  6864. + kmem_cache_create(cache_ID, sizeof(cache_name),0, \
  6865. + SLAB_HWCACHE_ALIGN, NULL, NULL);
  6866. +
  6867. +#define ICP_CACHE_NULL_CHECK(slab_zone) \
  6868. +{ \
  6869. + if(NULL == slab_zone){ \
  6870. + icp_ocfDrvFreeCaches(); \
  6871. + EPRINTK("%s() line %d: Not enough memory!\n", \
  6872. + __FUNCTION__, __LINE__); \
  6873. + return ENOMEM; \
  6874. + } \
  6875. +}
  6876. +
  6877. +#define ICP_CACHE_DESTROY(slab_zone) \
  6878. +{ \
  6879. + if(NULL != slab_zone){ \
  6880. + kmem_cache_destroy(slab_zone); \
  6881. + slab_zone = NULL; \
  6882. + } \
  6883. +}
  6884. +
  6885. +#define ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(alg) \
  6886. +{ \
  6887. + if(OCF_REGISTRATION_STATUS_SUCCESS == \
  6888. + crypto_register(icp_ocfDrvDriverId, \
  6889. + alg, \
  6890. + 0, \
  6891. + 0)) { \
  6892. + ocfStatus++; \
  6893. + } \
  6894. +}
  6895. +
  6896. +#define ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(alg) \
  6897. +{ \
  6898. + if(OCF_REGISTRATION_STATUS_SUCCESS == \
  6899. + crypto_kregister(icp_ocfDrvDriverId, \
  6900. + alg, \
  6901. + 0)){ \
  6902. + ocfStatus++; \
  6903. + } \
  6904. +}
  6905. +
  6906. +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  6907. +#define DPRINTK(args...) \
  6908. +{ \
  6909. + printk(args); \
  6910. +}
  6911. +
  6912. +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  6913. +
  6914. +#define DPRINTK(args...)
  6915. +
  6916. +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  6917. +
  6918. +#if ICP_OCF_PRINT_KERN_ALERT == 1
  6919. +#define APRINTK(args...) \
  6920. +{ \
  6921. + printk(KERN_ALERT args); \
  6922. +}
  6923. +
  6924. +#else //ICP_OCF_PRINT_KERN_ALERT == 1
  6925. +
  6926. +#define APRINTK(args...)
  6927. +
  6928. +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
  6929. +
  6930. +#if ICP_OCF_PRINT_KERN_ERRS == 1
  6931. +#define EPRINTK(args...) \
  6932. +{ \
  6933. + printk(KERN_ERR args); \
  6934. +}
  6935. +
  6936. +#else //ICP_OCF_PRINT_KERN_ERRS == 1
  6937. +
  6938. +#define EPRINTK(args...)
  6939. +
  6940. +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
  6941. +
  6942. +#define IPRINTK(args...) \
  6943. +{ \
  6944. + printk(KERN_INFO args); \
  6945. +}
  6946. +
  6947. +/*END OF MACRO DEFINITIONS*/
  6948. +
  6949. +typedef enum {
  6950. + ICP_OCF_DRV_ALG_CIPHER = 0,
  6951. + ICP_OCF_DRV_ALG_HASH
  6952. +} icp_ocf_drv_alg_type_t;
  6953. +
  6954. +/* These are all defined in icp_common.c */
  6955. +extern atomic_t lac_session_failed_dereg_count;
  6956. +extern atomic_t icp_ocfDrvIsExiting;
  6957. +extern atomic_t num_ocf_to_drv_registered_sessions;
  6958. +
  6959. +/*These are use inputs used in icp_sym.c and icp_common.c
  6960. + They are instantiated in icp_common.c*/
  6961. +extern int max_sessions;
  6962. +
  6963. +extern int32_t icp_ocfDrvDriverId;
  6964. +extern struct list_head icp_ocfDrvGlobalSymListHead;
  6965. +extern struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
  6966. +extern struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
  6967. +extern spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  6968. +extern rwlock_t icp_kmem_cache_destroy_alloc_lock;
  6969. +
  6970. +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
  6971. +extern struct kmem_cache *drvSessionData_zone;
  6972. +extern struct kmem_cache *drvOpData_zone;
  6973. +
  6974. +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
  6975. +extern struct kmem_cache *drvDH_zone;
  6976. +extern struct kmem_cache *drvLnModExp_zone;
  6977. +extern struct kmem_cache *drvRSADecrypt_zone;
  6978. +extern struct kmem_cache *drvRSAPrivateKey_zone;
  6979. +extern struct kmem_cache *drvDSARSSign_zone;
  6980. +extern struct kmem_cache *drvDSARSSignKValue_zone;
  6981. +extern struct kmem_cache *drvDSAVerify_zone;
  6982. +
  6983. +/*Slab zones for flatbuffers and bufferlist*/
  6984. +extern struct kmem_cache *drvFlatBuffer_zone;
  6985. +
  6986. +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
  6987. +
  6988. +struct icp_drvBuffListInfo {
  6989. + Cpa16U numBuffers;
  6990. + Cpa32U metaSize;
  6991. + Cpa32U metaOffset;
  6992. + Cpa32U buffListSize;
  6993. +};
  6994. +extern struct icp_drvBuffListInfo defBuffListInfo;
  6995. +
  6996. +/*
  6997. +* This struct is used to keep a reference to the relevant node in the list
  6998. +* of sessionData structs, to the buffer type required by OCF and to the OCF
  6999. +* provided crp struct that needs to be returned. All this info is needed in
  7000. +* the callback function.
  7001. +*
  7002. +* IV can sometimes be stored in non-contiguous memory (e.g. skbuff
  7003. +* linked/frag list, therefore a contiguous memory space for the IV data must be
  7004. +* created and passed to LAC
  7005. +*
  7006. +*/
  7007. +struct icp_drvOpData {
  7008. + CpaCySymOpData lacOpData;
  7009. + uint32_t digestSizeInBytes;
  7010. + struct cryptop *crp;
  7011. + uint8_t bufferType;
  7012. + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
  7013. + uint16_t numBufferListArray;
  7014. + CpaBufferList srcBuffer;
  7015. + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
  7016. + CpaBoolean verifyResult;
  7017. +};
  7018. +/*Values used to derisk chances of performs being called against
  7019. +deregistered sessions (for which the slab page has been reclaimed)
  7020. +This is not a fix - since page frames are reclaimed from a slab, one cannot
  7021. +rely on that memory not being re-used by another app.*/
  7022. +typedef enum {
  7023. + ICP_SESSION_INITIALISED = 0x5C5C5C,
  7024. + ICP_SESSION_RUNNING = 0x005C00,
  7025. + ICP_SESSION_DEREGISTERED = 0xC5C5C5
  7026. +} usage_derisk;
  7027. +
  7028. +/*
  7029. +This is the OCF<->OCF_DRV session object:
  7030. +
  7031. +1.The first member is a listNode. These session objects are added to a linked
  7032. + list in order to make it easier to remove them all at session exit time.
  7033. +2.The second member is used to give the session object state and derisk the
  7034. + possibility of OCF batch calls executing against a deregistered session (as
  7035. + described above).
  7036. +3.The third member is a LAC<->OCF_DRV session handle (initialised with the first
  7037. + perform request for that session).
  7038. +4.The fourth is the LAC session context. All the parameters for this structure
  7039. + are only known when the first perform request for this session occurs. That is
  7040. + why the OCF Tolapai Driver only registers a new LAC session at perform time
  7041. +*/
  7042. +struct icp_drvSessionData {
  7043. + struct list_head listNode;
  7044. + usage_derisk inUse;
  7045. + CpaCySymSessionCtx sessHandle;
  7046. + CpaCySymSessionSetupData lacSessCtx;
  7047. +};
  7048. +
  7049. +/* This struct is required for deferred session
  7050. + deregistration as a work queue function can
  7051. + only have one argument*/
  7052. +struct icp_ocfDrvFreeLacSession {
  7053. + CpaCySymSessionCtx sessionToDeregister;
  7054. + struct work_struct work;
  7055. +};
  7056. +
  7057. +int icp_ocfDrvNewSession(device_t dev, uint32_t * sild, struct cryptoini *cri);
  7058. +
  7059. +int icp_ocfDrvFreeLACSession(device_t dev, uint64_t sid);
  7060. +
  7061. +int icp_ocfDrvSymProcess(device_t dev, struct cryptop *crp, int hint);
  7062. +
  7063. +int icp_ocfDrvPkeProcess(device_t dev, struct cryptkop *krp, int hint);
  7064. +
  7065. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
  7066. +
  7067. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
  7068. +
  7069. +int icp_ocfDrvSkBuffToBufferList(struct sk_buff *skb,
  7070. + CpaBufferList * bufferList);
  7071. +
  7072. +int icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList,
  7073. + struct sk_buff **skb);
  7074. +
  7075. +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  7076. + CpaFlatBuffer * pFlatBuffer);
  7077. +
  7078. +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  7079. + CpaBufferList * pBufferList);
  7080. +
  7081. +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  7082. + void **ppDataOut, uint32_t * pLength);
  7083. +
  7084. +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  7085. + struct icp_drvBuffListInfo *buffListInfo);
  7086. +
  7087. +uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff *pSkb);
  7088. +
  7089. +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
  7090. +
  7091. +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  7092. + const struct icp_drvOpData *pOpData);
  7093. +
  7094. +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
  7095. +
  7096. +#endif
  7097. +/* ICP_OCF_H */
  7098. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.27.10/crypto/ocf/ep80579/icp_sym.c
  7099. --- linux-2.6.27.10.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
  7100. +++ linux-2.6.27.10/crypto/ocf/ep80579/icp_sym.c 2008-12-23 19:31:44.000000000 +0100
  7101. @@ -0,0 +1,1382 @@
  7102. +/***************************************************************************
  7103. + *
  7104. + * This file is provided under a dual BSD/GPLv2 license. When using or
  7105. + * redistributing this file, you may do so under either license.
  7106. + *
  7107. + * GPL LICENSE SUMMARY
  7108. + *
  7109. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  7110. + *
  7111. + * This program is free software; you can redistribute it and/or modify
  7112. + * it under the terms of version 2 of the GNU General Public License as
  7113. + * published by the Free Software Foundation.
  7114. + *
  7115. + * This program is distributed in the hope that it will be useful, but
  7116. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  7117. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  7118. + * General Public License for more details.
  7119. + *
  7120. + * You should have received a copy of the GNU General Public License
  7121. + * along with this program; if not, write to the Free Software
  7122. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  7123. + * The full GNU General Public License is included in this distribution
  7124. + * in the file called LICENSE.GPL.
  7125. + *
  7126. + * Contact Information:
  7127. + * Intel Corporation
  7128. + *
  7129. + * BSD LICENSE
  7130. + *
  7131. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  7132. + * All rights reserved.
  7133. + *
  7134. + * Redistribution and use in source and binary forms, with or without
  7135. + * modification, are permitted provided that the following conditions
  7136. + * are met:
  7137. + *
  7138. + * * Redistributions of source code must retain the above copyright
  7139. + * notice, this list of conditions and the following disclaimer.
  7140. + * * Redistributions in binary form must reproduce the above copyright
  7141. + * notice, this list of conditions and the following disclaimer in
  7142. + * the documentation and/or other materials provided with the
  7143. + * distribution.
  7144. + * * Neither the name of Intel Corporation nor the names of its
  7145. + * contributors may be used to endorse or promote products derived
  7146. + * from this software without specific prior written permission.
  7147. + *
  7148. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  7149. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7150. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  7151. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7152. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  7153. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  7154. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  7155. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  7156. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7157. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  7158. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7159. + *
  7160. + *
  7161. + * version: Security.L.1.0.130
  7162. + *
  7163. + ***************************************************************************/
  7164. +/*
  7165. + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
  7166. + * cryptography.
  7167. + *
  7168. + * This driver requires the ICP Access Library that is available from Intel in
  7169. + * order to operate.
  7170. + */
  7171. +
  7172. +#include "icp_ocf.h"
  7173. +
  7174. +/*This is the call back function for all symmetric cryptographic processes.
  7175. + Its main functionality is to free driver crypto operation structure and to
  7176. + call back to OCF*/
  7177. +static void
  7178. +icp_ocfDrvSymCallBack(void *callbackTag,
  7179. + CpaStatus status,
  7180. + const CpaCySymOp operationType,
  7181. + void *pOpData,
  7182. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  7183. +
  7184. +/*This function is used to extract crypto processing information from the OCF
  7185. + inputs, so as that it may be passed onto LAC*/
  7186. +static int
  7187. +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  7188. + struct cryptodesc *crp_desc);
  7189. +
  7190. +/*This function checks whether the crp_desc argument pertains to a digest or a
  7191. + cipher operation*/
  7192. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  7193. +
  7194. +/*This function copies all the passed in session context information and stores
  7195. + it in a LAC context structure*/
  7196. +static int
  7197. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  7198. + CpaCySymSessionSetupData * lacSessCtx);
  7199. +
  7200. +/*This top level function is used to find a pointer to where a digest is
  7201. + stored/needs to be inserted. */
  7202. +static uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  7203. + struct cryptodesc *crp_desc);
  7204. +
  7205. +/*This function is called when a digest pointer has to be found within a
  7206. + SKBUFF.*/
  7207. +static inline uint8_t *icp_ocfDrvSkbuffDigestPointerFind(struct icp_drvOpData
  7208. + *drvOpData,
  7209. + int offsetInBytes,
  7210. + uint32_t
  7211. + digestSizeInBytes);
  7212. +
  7213. +/*The following two functions are called if the SKBUFF digest pointer is not
  7214. + positioned in the linear portion of the buffer (i.e. it is in a linked SKBUFF
  7215. + or page fragment).*/
  7216. +/*This function takes care of the page fragment case.*/
  7217. +static inline uint8_t *icp_ocfDrvDigestSkbNRFragsCheck(struct sk_buff *skb,
  7218. + struct skb_shared_info
  7219. + *skb_shared,
  7220. + int offsetInBytes,
  7221. + uint32_t
  7222. + digestSizeInBytes);
  7223. +
  7224. +/*This function takes care of the linked list case.*/
  7225. +static inline uint8_t *icp_ocfDrvDigestSkbFragListCheck(struct sk_buff *skb,
  7226. + struct skb_shared_info
  7227. + *skb_shared,
  7228. + int offsetInBytes,
  7229. + uint32_t
  7230. + digestSizeInBytes);
  7231. +
  7232. +/*This function is used to free an OCF->OCF_DRV session object*/
  7233. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  7234. +
  7235. +/*max IOV buffs supported in a UIO structure*/
  7236. +#define NUM_IOV_SUPPORTED (1)
  7237. +
  7238. +/* Name : icp_ocfDrvSymCallBack
  7239. + *
  7240. + * Description : When this function returns it signifies that the LAC
  7241. + * component has completed the relevant symmetric operation.
  7242. + *
  7243. + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  7244. + * object was passed to LAC for the cryptographic processing and contains all
  7245. + * the relevant information for cleaning up buffer handles etc. so that the
  7246. + * OCF Tolapai Driver portion of this crypto operation can be fully completed.
  7247. + */
  7248. +static void
  7249. +icp_ocfDrvSymCallBack(void *callbackTag,
  7250. + CpaStatus status,
  7251. + const CpaCySymOp operationType,
  7252. + void *pOpData,
  7253. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  7254. +{
  7255. + struct cryptop *crp = NULL;
  7256. + struct icp_drvOpData *temp_drvOpData =
  7257. + (struct icp_drvOpData *)callbackTag;
  7258. + uint64_t *tempBasePtr = NULL;
  7259. + uint32_t tempLen = 0;
  7260. +
  7261. + if (NULL == temp_drvOpData) {
  7262. + DPRINTK("%s(): The callback from the LAC component"
  7263. + " has failed due to Null userOpaque data"
  7264. + "(status == %d).\n", __FUNCTION__, status);
  7265. + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  7266. + return;
  7267. + }
  7268. +
  7269. + crp = temp_drvOpData->crp;
  7270. + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  7271. +
  7272. + if (NULL == pOpData) {
  7273. + DPRINTK("%s(): The callback from the LAC component"
  7274. + " has failed due to Null Symmetric Op data"
  7275. + "(status == %d).\n", __FUNCTION__, status);
  7276. + crp->crp_etype = ECANCELED;
  7277. + crypto_done(crp);
  7278. + return;
  7279. + }
  7280. +
  7281. + if (NULL == pDstBuffer) {
  7282. + DPRINTK("%s(): The callback from the LAC component"
  7283. + " has failed due to Null Dst Bufferlist data"
  7284. + "(status == %d).\n", __FUNCTION__, status);
  7285. + crp->crp_etype = ECANCELED;
  7286. + crypto_done(crp);
  7287. + return;
  7288. + }
  7289. +
  7290. + if (CPA_STATUS_SUCCESS == status) {
  7291. +
  7292. + if (temp_drvOpData->bufferType == CRYPTO_F_SKBUF) {
  7293. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7294. + icp_ocfDrvBufferListToSkBuff(pDstBuffer,
  7295. + (struct sk_buff **)
  7296. + &(crp->crp_buf))) {
  7297. + EPRINTK("%s(): BufferList to SkBuff "
  7298. + "conversion error.\n", __FUNCTION__);
  7299. + crp->crp_etype = EPERM;
  7300. + }
  7301. + } else {
  7302. + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  7303. + (void **)&tempBasePtr,
  7304. + &tempLen);
  7305. + crp->crp_olen = (int)tempLen;
  7306. + }
  7307. +
  7308. + } else {
  7309. + DPRINTK("%s(): The callback from the LAC component has failed"
  7310. + "(status == %d).\n", __FUNCTION__, status);
  7311. +
  7312. + crp->crp_etype = ECANCELED;
  7313. + }
  7314. +
  7315. + if (temp_drvOpData->numBufferListArray >
  7316. + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  7317. + kfree(pDstBuffer->pBuffers);
  7318. + }
  7319. + icp_ocfDrvFreeMetaData(pDstBuffer);
  7320. + kmem_cache_free(drvOpData_zone, temp_drvOpData);
  7321. +
  7322. + /* Invoke the OCF callback function */
  7323. + crypto_done(crp);
  7324. +
  7325. + return;
  7326. +}
  7327. +
  7328. +/* Name : icp_ocfDrvNewSession
  7329. + *
  7330. + * Description : This function will create a new Driver<->OCF session
  7331. + *
  7332. + * Notes : LAC session registration happens during the first perform call.
  7333. + * That is the first time we know all information about a given session.
  7334. + */
  7335. +int icp_ocfDrvNewSession(device_t dev, uint32_t * sid, struct cryptoini *cri)
  7336. +{
  7337. + struct icp_drvSessionData *sessionData = NULL;
  7338. + uint32_t delete_session = 0;
  7339. +
  7340. + /* The SID passed in should be our driver ID. We can return the */
  7341. + /* local ID (LID) which is a unique identifier which we can use */
  7342. + /* to differentiate between the encrypt/decrypt LAC session handles */
  7343. + if (NULL == sid) {
  7344. + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  7345. + __FUNCTION__);
  7346. + return EINVAL;
  7347. + }
  7348. +
  7349. + if (NULL == cri) {
  7350. + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  7351. + __FUNCTION__);
  7352. + return EINVAL;
  7353. + }
  7354. +
  7355. + if (icp_ocfDrvDriverId != *sid) {
  7356. + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  7357. + __FUNCTION__);
  7358. + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  7359. + return EINVAL;
  7360. + }
  7361. +
  7362. + sessionData = kmem_cache_zalloc(drvSessionData_zone, GFP_ATOMIC);
  7363. + if (NULL == sessionData) {
  7364. + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  7365. + return ENOMEM;
  7366. + }
  7367. +
  7368. + /*ENTER CRITICAL SECTION */
  7369. + spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7370. + /*put this check in the spinlock so no new sessions can be added to the
  7371. + linked list when we are exiting */
  7372. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  7373. + delete_session++;
  7374. +
  7375. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  7376. + if (atomic_read(&num_ocf_to_drv_registered_sessions) >=
  7377. + (max_sessions -
  7378. + atomic_read(&lac_session_failed_dereg_count))) {
  7379. + delete_session++;
  7380. + } else {
  7381. + atomic_inc(&num_ocf_to_drv_registered_sessions);
  7382. + /* Add to session data linked list */
  7383. + list_add(&(sessionData->listNode),
  7384. + &icp_ocfDrvGlobalSymListHead);
  7385. + }
  7386. +
  7387. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  7388. + list_add(&(sessionData->listNode),
  7389. + &icp_ocfDrvGlobalSymListHead);
  7390. + }
  7391. +
  7392. + sessionData->inUse = ICP_SESSION_INITIALISED;
  7393. +
  7394. + /*EXIT CRITICAL SECTION */
  7395. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7396. +
  7397. + if (delete_session) {
  7398. + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  7399. + kmem_cache_free(drvSessionData_zone, sessionData);
  7400. + return EPERM;
  7401. + }
  7402. +
  7403. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7404. + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  7405. + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  7406. + icp_ocfDrvFreeOCFSession(sessionData);
  7407. + return EINVAL;
  7408. + }
  7409. +
  7410. + if (cri->cri_next) {
  7411. + if (cri->cri_next->cri_next != NULL) {
  7412. + DPRINTK("%s():only two chained algorithms supported\n",
  7413. + __FUNCTION__);
  7414. + icp_ocfDrvFreeOCFSession(sessionData);
  7415. + return EPERM;
  7416. + }
  7417. +
  7418. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7419. + icp_ocfDrvAlgorithmSetup(cri->cri_next,
  7420. + &(sessionData->lacSessCtx))) {
  7421. + DPRINTK("%s():second algorithm not supported\n",
  7422. + __FUNCTION__);
  7423. + icp_ocfDrvFreeOCFSession(sessionData);
  7424. + return EINVAL;
  7425. + }
  7426. +
  7427. + sessionData->lacSessCtx.symOperation =
  7428. + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  7429. + }
  7430. +
  7431. + *sid = (uint32_t) sessionData;
  7432. +
  7433. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7434. +}
  7435. +
  7436. +/* Name : icp_ocfDrvAlgorithmSetup
  7437. + *
  7438. + * Description : This function builds the session context data from the
  7439. + * information supplied through OCF. Algorithm chain order and whether the
  7440. + * session is Encrypt/Decrypt can only be found out at perform time however, so
  7441. + * the session is registered with LAC at that time.
  7442. + */
  7443. +static int
  7444. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  7445. + CpaCySymSessionSetupData * lacSessCtx)
  7446. +{
  7447. +
  7448. + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  7449. +
  7450. + switch (cri->cri_alg) {
  7451. +
  7452. + case CRYPTO_NULL_CBC:
  7453. + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  7454. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7455. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7456. + CPA_CY_SYM_CIPHER_NULL;
  7457. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7458. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7459. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7460. + break;
  7461. +
  7462. + case CRYPTO_DES_CBC:
  7463. + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  7464. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7465. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7466. + CPA_CY_SYM_CIPHER_DES_CBC;
  7467. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7468. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7469. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7470. + break;
  7471. +
  7472. + case CRYPTO_3DES_CBC:
  7473. + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  7474. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7475. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7476. + CPA_CY_SYM_CIPHER_3DES_CBC;
  7477. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7478. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7479. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7480. + break;
  7481. +
  7482. + case CRYPTO_AES_CBC:
  7483. + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  7484. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7485. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7486. + CPA_CY_SYM_CIPHER_AES_CBC;
  7487. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7488. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7489. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7490. + break;
  7491. +
  7492. + case CRYPTO_ARC4:
  7493. + DPRINTK("%s(): ARC4\n", __FUNCTION__);
  7494. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7495. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7496. + CPA_CY_SYM_CIPHER_ARC4;
  7497. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7498. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7499. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7500. + break;
  7501. +
  7502. + case CRYPTO_SHA1:
  7503. + DPRINTK("%s(): SHA1\n", __FUNCTION__);
  7504. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7505. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  7506. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  7507. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7508. + (cri->cri_mlen ?
  7509. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  7510. +
  7511. + break;
  7512. +
  7513. + case CRYPTO_SHA1_HMAC:
  7514. + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  7515. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7516. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  7517. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  7518. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7519. + (cri->cri_mlen ?
  7520. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  7521. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  7522. + cri->cri_key;
  7523. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  7524. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7525. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  7526. +
  7527. + break;
  7528. +
  7529. + case CRYPTO_SHA2_256:
  7530. + DPRINTK("%s(): SHA256\n", __FUNCTION__);
  7531. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7532. + lacSessCtx->hashSetupData.hashAlgorithm =
  7533. + CPA_CY_SYM_HASH_SHA256;
  7534. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  7535. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7536. + (cri->cri_mlen ?
  7537. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  7538. +
  7539. + break;
  7540. +
  7541. + case CRYPTO_SHA2_256_HMAC:
  7542. + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  7543. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7544. + lacSessCtx->hashSetupData.hashAlgorithm =
  7545. + CPA_CY_SYM_HASH_SHA256;
  7546. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  7547. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7548. + (cri->cri_mlen ?
  7549. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  7550. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  7551. + cri->cri_key;
  7552. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  7553. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7554. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  7555. +
  7556. + break;
  7557. +
  7558. + case CRYPTO_SHA2_384:
  7559. + DPRINTK("%s(): SHA384\n", __FUNCTION__);
  7560. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7561. + lacSessCtx->hashSetupData.hashAlgorithm =
  7562. + CPA_CY_SYM_HASH_SHA384;
  7563. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  7564. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7565. + (cri->cri_mlen ?
  7566. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  7567. +
  7568. + break;
  7569. +
  7570. + case CRYPTO_SHA2_384_HMAC:
  7571. + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  7572. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7573. + lacSessCtx->hashSetupData.hashAlgorithm =
  7574. + CPA_CY_SYM_HASH_SHA384;
  7575. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  7576. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7577. + (cri->cri_mlen ?
  7578. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  7579. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  7580. + cri->cri_key;
  7581. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  7582. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7583. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  7584. +
  7585. + break;
  7586. +
  7587. + case CRYPTO_SHA2_512:
  7588. + DPRINTK("%s(): SHA512\n", __FUNCTION__);
  7589. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7590. + lacSessCtx->hashSetupData.hashAlgorithm =
  7591. + CPA_CY_SYM_HASH_SHA512;
  7592. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  7593. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7594. + (cri->cri_mlen ?
  7595. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  7596. +
  7597. + break;
  7598. +
  7599. + case CRYPTO_SHA2_512_HMAC:
  7600. + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  7601. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7602. + lacSessCtx->hashSetupData.hashAlgorithm =
  7603. + CPA_CY_SYM_HASH_SHA512;
  7604. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  7605. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7606. + (cri->cri_mlen ?
  7607. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  7608. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  7609. + cri->cri_key;
  7610. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  7611. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7612. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  7613. +
  7614. + break;
  7615. +
  7616. + case CRYPTO_MD5:
  7617. + DPRINTK("%s(): MD5\n", __FUNCTION__);
  7618. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7619. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  7620. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  7621. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7622. + (cri->cri_mlen ?
  7623. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  7624. +
  7625. + break;
  7626. +
  7627. + case CRYPTO_MD5_HMAC:
  7628. + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  7629. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  7630. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  7631. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  7632. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  7633. + (cri->cri_mlen ?
  7634. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  7635. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  7636. + cri->cri_key;
  7637. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  7638. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7639. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  7640. +
  7641. + break;
  7642. +
  7643. + default:
  7644. + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  7645. + return ICP_OCF_DRV_STATUS_FAIL;
  7646. + }
  7647. +
  7648. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7649. +}
  7650. +
  7651. +/* Name : icp_ocfDrvFreeOCFSession
  7652. + *
  7653. + * Description : This function deletes all existing Session data representing
  7654. + * the Cryptographic session established between OCF and this driver. This
  7655. + * also includes freeing the memory allocated for the session context. The
  7656. + * session object is also removed from the session linked list.
  7657. + */
  7658. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  7659. +{
  7660. +
  7661. + sessionData->inUse = ICP_SESSION_DEREGISTERED;
  7662. +
  7663. + /*ENTER CRITICAL SECTION */
  7664. + spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7665. +
  7666. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  7667. + /*If the Driver is exiting, allow that process to
  7668. + handle any deletions */
  7669. + /*EXIT CRITICAL SECTION */
  7670. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7671. + return;
  7672. + }
  7673. +
  7674. + atomic_dec(&num_ocf_to_drv_registered_sessions);
  7675. +
  7676. + list_del(&(sessionData->listNode));
  7677. +
  7678. + /*EXIT CRITICAL SECTION */
  7679. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7680. +
  7681. + if (NULL != sessionData->sessHandle) {
  7682. + kfree(sessionData->sessHandle);
  7683. + }
  7684. + kmem_cache_free(drvSessionData_zone, sessionData);
  7685. +}
  7686. +
  7687. +/* Name : icp_ocfDrvFreeLACSession
  7688. + *
  7689. + * Description : This attempts to deregister a LAC session. If it fails, the
  7690. + * deregistation retry function is called.
  7691. + */
  7692. +int icp_ocfDrvFreeLACSession(device_t dev, uint64_t sid)
  7693. +{
  7694. + CpaCySymSessionCtx sessionToDeregister = NULL;
  7695. + struct icp_drvSessionData *sessionData = NULL;
  7696. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  7697. + int retval = 0;
  7698. +
  7699. + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  7700. + if (NULL == sessionData) {
  7701. + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  7702. + __FUNCTION__);
  7703. + return EINVAL;
  7704. + }
  7705. +
  7706. + sessionToDeregister = sessionData->sessHandle;
  7707. +
  7708. + if (ICP_SESSION_INITIALISED == sessionData->inUse) {
  7709. + DPRINTK("%s() Session not registered with LAC\n", __FUNCTION__);
  7710. + } else if (NULL == sessionData->sessHandle) {
  7711. + EPRINTK
  7712. + ("%s(): OCF Free session called with Null Session Handle.\n",
  7713. + __FUNCTION__);
  7714. + return EINVAL;
  7715. + } else {
  7716. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  7717. + sessionToDeregister);
  7718. + if (CPA_STATUS_RETRY == lacStatus) {
  7719. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7720. + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  7721. + /* the retry function increments the
  7722. + dereg failed count */
  7723. + DPRINTK("%s(): LAC failed to deregister the "
  7724. + "session. (localSessionId= %p)\n",
  7725. + __FUNCTION__, sessionToDeregister);
  7726. + retval = EPERM;
  7727. + }
  7728. +
  7729. + } else if (CPA_STATUS_SUCCESS != lacStatus) {
  7730. + DPRINTK("%s(): LAC failed to deregister the session. "
  7731. + "localSessionId= %p, lacStatus = %d\n",
  7732. + __FUNCTION__, sessionToDeregister, lacStatus);
  7733. + atomic_inc(&lac_session_failed_dereg_count);
  7734. + retval = EPERM;
  7735. + }
  7736. + }
  7737. +
  7738. + icp_ocfDrvFreeOCFSession(sessionData);
  7739. + return retval;
  7740. +
  7741. +}
  7742. +
  7743. +/* Name : icp_ocfDrvAlgCheck
  7744. + *
  7745. + * Description : This function checks whether the cryptodesc argument pertains
  7746. + * to a sym or hash function
  7747. + */
  7748. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  7749. +{
  7750. +
  7751. + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  7752. + crp_desc->crd_alg == CRYPTO_AES_CBC ||
  7753. + crp_desc->crd_alg == CRYPTO_DES_CBC ||
  7754. + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  7755. + crp_desc->crd_alg == CRYPTO_ARC4) {
  7756. + return ICP_OCF_DRV_ALG_CIPHER;
  7757. + }
  7758. +
  7759. + return ICP_OCF_DRV_ALG_HASH;
  7760. +}
  7761. +
  7762. +/* Name : icp_ocfDrvSymProcess
  7763. + *
  7764. + * Description : This function will map symmetric functionality calls from OCF
  7765. + * to the LAC API. It will also allocate memory to store the session context.
  7766. + *
  7767. + * Notes: If it is the first perform call for a given session, then a LAC
  7768. + * session is registered. After the session is registered, no checks as
  7769. + * to whether session paramaters have changed (e.g. alg chain order) are
  7770. + * done.
  7771. + */
  7772. +int icp_ocfDrvSymProcess(device_t dev, struct cryptop *crp, int hint)
  7773. +{
  7774. + struct icp_drvSessionData *sessionData = NULL;
  7775. + struct icp_drvOpData *drvOpData = NULL;
  7776. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  7777. + Cpa32U sessionCtxSizeInBytes = 0;
  7778. + uint16_t numBufferListArray = 0;
  7779. +
  7780. + if (NULL == crp) {
  7781. + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  7782. + __FUNCTION__);
  7783. + return EINVAL;
  7784. + }
  7785. +
  7786. + if (NULL == crp->crp_desc) {
  7787. + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  7788. + "to crp\n", __FUNCTION__);
  7789. + crp->crp_etype = EINVAL;
  7790. + return EINVAL;
  7791. + }
  7792. +
  7793. + if (NULL == crp->crp_buf) {
  7794. + DPRINTK("%s(): Invalid input parameters, no buffer attached "
  7795. + "to crp\n", __FUNCTION__);
  7796. + crp->crp_etype = EINVAL;
  7797. + return EINVAL;
  7798. + }
  7799. +
  7800. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  7801. + crp->crp_etype = EFAULT;
  7802. + return EFAULT;
  7803. + }
  7804. +
  7805. + sessionData = (struct icp_drvSessionData *)
  7806. + (CRYPTO_SESID2LID(crp->crp_sid));
  7807. + if (NULL == sessionData) {
  7808. + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  7809. + __FUNCTION__);
  7810. + crp->crp_etype = EINVAL;
  7811. + return EINVAL;
  7812. + }
  7813. +
  7814. +/*If we get a request against a deregisted session, cancel operation*/
  7815. + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  7816. + DPRINTK("%s(): Session ID %d was deregistered \n",
  7817. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  7818. + crp->crp_etype = EFAULT;
  7819. + return EFAULT;
  7820. + }
  7821. +
  7822. +/*If none of the session states are set, then the session structure was either
  7823. + not initialised properly or we are reading from a freed memory area (possible
  7824. + due to OCF batch mode not removing queued requests against deregistered
  7825. + sessions*/
  7826. + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  7827. + ICP_SESSION_RUNNING != sessionData->inUse) {
  7828. + DPRINTK("%s(): Session - ID %d - not properly initialised or "
  7829. + "memory freed back to the kernel \n",
  7830. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  7831. + crp->crp_etype = EINVAL;
  7832. + return EINVAL;
  7833. + }
  7834. +
  7835. + /*For the below checks, remember error checking is already done in LAC.
  7836. + We're not validating inputs subsequent to registration */
  7837. + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  7838. + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  7839. +
  7840. + if (NULL != crp->crp_desc->crd_next) {
  7841. + if (ICP_OCF_DRV_ALG_CIPHER ==
  7842. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  7843. +
  7844. + sessionData->lacSessCtx.algChainOrder =
  7845. + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  7846. +
  7847. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  7848. + sessionData->lacSessCtx.cipherSetupData.
  7849. + cipherDirection =
  7850. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  7851. + } else {
  7852. + sessionData->lacSessCtx.cipherSetupData.
  7853. + cipherDirection =
  7854. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  7855. + }
  7856. + } else {
  7857. + sessionData->lacSessCtx.algChainOrder =
  7858. + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  7859. +
  7860. + if (crp->crp_desc->crd_next->crd_flags &
  7861. + CRD_F_ENCRYPT) {
  7862. + sessionData->lacSessCtx.cipherSetupData.
  7863. + cipherDirection =
  7864. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  7865. + } else {
  7866. + sessionData->lacSessCtx.cipherSetupData.
  7867. + cipherDirection =
  7868. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  7869. + }
  7870. +
  7871. + }
  7872. +
  7873. + } else if (ICP_OCF_DRV_ALG_CIPHER ==
  7874. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  7875. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  7876. + sessionData->lacSessCtx.cipherSetupData.
  7877. + cipherDirection =
  7878. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  7879. + } else {
  7880. + sessionData->lacSessCtx.cipherSetupData.
  7881. + cipherDirection =
  7882. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  7883. + }
  7884. +
  7885. + }
  7886. +
  7887. + /*No action required for standalone Auth here */
  7888. +
  7889. + /* Allocate memory for SymSessionCtx before the Session Registration */
  7890. + lacStatus =
  7891. + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  7892. + &(sessionData->lacSessCtx),
  7893. + &sessionCtxSizeInBytes);
  7894. + if (CPA_STATUS_SUCCESS != lacStatus) {
  7895. + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  7896. + __FUNCTION__, lacStatus);
  7897. + return EINVAL;
  7898. + }
  7899. + sessionData->sessHandle =
  7900. + kmalloc(sessionCtxSizeInBytes, GFP_ATOMIC);
  7901. + if (NULL == sessionData->sessHandle) {
  7902. + EPRINTK
  7903. + ("%s(): Failed to get memory for SymSessionCtx\n",
  7904. + __FUNCTION__);
  7905. + return ENOMEM;
  7906. + }
  7907. +
  7908. + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  7909. + icp_ocfDrvSymCallBack,
  7910. + &(sessionData->lacSessCtx),
  7911. + sessionData->sessHandle);
  7912. +
  7913. + if (CPA_STATUS_SUCCESS != lacStatus) {
  7914. + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  7915. + __FUNCTION__, lacStatus);
  7916. + return EFAULT;
  7917. + }
  7918. +
  7919. + sessionData->inUse = ICP_SESSION_RUNNING;
  7920. + }
  7921. +
  7922. + drvOpData = kmem_cache_zalloc(drvOpData_zone, GFP_ATOMIC);
  7923. + if (NULL == drvOpData) {
  7924. + EPRINTK("%s():Failed to get memory for drvOpData\n",
  7925. + __FUNCTION__);
  7926. + crp->crp_etype = ENOMEM;
  7927. + return ENOMEM;
  7928. + }
  7929. +
  7930. + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  7931. + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  7932. + digestResultLenInBytes;
  7933. + drvOpData->crp = crp;
  7934. +
  7935. + /* Set the default buffer list array memory allocation */
  7936. + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  7937. + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  7938. +
  7939. + /*
  7940. + * Allocate buffer list array memory allocation if the
  7941. + * data fragment is more than the default allocation
  7942. + */
  7943. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  7944. + numBufferListArray = icp_ocfDrvGetSkBuffFrags((struct sk_buff *)
  7945. + crp->crp_buf);
  7946. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < numBufferListArray) {
  7947. + DPRINTK("%s() numBufferListArray more than default\n",
  7948. + __FUNCTION__);
  7949. + drvOpData->srcBuffer.pBuffers = NULL;
  7950. + drvOpData->srcBuffer.pBuffers =
  7951. + kmalloc(numBufferListArray *
  7952. + sizeof(CpaFlatBuffer), GFP_ATOMIC);
  7953. + if (NULL == drvOpData->srcBuffer.pBuffers) {
  7954. + EPRINTK("%s() Failed to get memory for "
  7955. + "pBuffers\n", __FUNCTION__);
  7956. + kmem_cache_free(drvOpData_zone, drvOpData);
  7957. + crp->crp_etype = ENOMEM;
  7958. + return ENOMEM;
  7959. + }
  7960. + drvOpData->numBufferListArray = numBufferListArray;
  7961. + }
  7962. + }
  7963. +
  7964. + /*
  7965. + * Check the type of buffer structure we got and convert it into
  7966. + * CpaBufferList format.
  7967. + */
  7968. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  7969. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7970. + icp_ocfDrvSkBuffToBufferList((struct sk_buff *)crp->crp_buf,
  7971. + &(drvOpData->srcBuffer))) {
  7972. + EPRINTK("%s():Failed to translate from SK_BUF "
  7973. + "to bufferlist\n", __FUNCTION__);
  7974. + crp->crp_etype = EINVAL;
  7975. + goto err;
  7976. + }
  7977. +
  7978. + drvOpData->bufferType = CRYPTO_F_SKBUF;
  7979. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  7980. + /* OCF only supports IOV of one entry. */
  7981. + if (NUM_IOV_SUPPORTED ==
  7982. + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  7983. +
  7984. + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  7985. + crp_buf))->
  7986. + uio_iov[0].iov_base,
  7987. + ((struct uio *)(crp->
  7988. + crp_buf))->
  7989. + uio_iov[0].iov_len,
  7990. + &(drvOpData->
  7991. + srcBuffer));
  7992. +
  7993. + drvOpData->bufferType = CRYPTO_F_IOV;
  7994. +
  7995. + } else {
  7996. + DPRINTK("%s():Unable to handle IOVs with lengths of "
  7997. + "greater than one!\n", __FUNCTION__);
  7998. + crp->crp_etype = EINVAL;
  7999. + goto err;
  8000. + }
  8001. +
  8002. + } else {
  8003. + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  8004. + crp->crp_ilen,
  8005. + &(drvOpData->srcBuffer));
  8006. +
  8007. + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  8008. + }
  8009. +
  8010. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  8011. + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  8012. + crp->crp_etype = EINVAL;
  8013. + goto err;
  8014. + }
  8015. +
  8016. + if (drvOpData->crp->crp_desc->crd_next != NULL) {
  8017. + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  8018. + crp_desc->crd_next)) {
  8019. + crp->crp_etype = EINVAL;
  8020. + goto err;
  8021. + }
  8022. +
  8023. + }
  8024. +
  8025. + /* Allocate srcBuffer's private meta data */
  8026. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  8027. + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  8028. + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  8029. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  8030. + crp->crp_etype = EINVAL;
  8031. + goto err;
  8032. + }
  8033. +
  8034. + /* Perform "in-place" crypto operation */
  8035. + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  8036. + (void *)drvOpData,
  8037. + &(drvOpData->lacOpData),
  8038. + &(drvOpData->srcBuffer),
  8039. + &(drvOpData->srcBuffer),
  8040. + &(drvOpData->verifyResult));
  8041. + if (CPA_STATUS_RETRY == lacStatus) {
  8042. + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  8043. + __FUNCTION__, lacStatus);
  8044. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  8045. + crp->crp_etype = EINVAL;
  8046. + goto err;
  8047. + }
  8048. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8049. + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  8050. + __FUNCTION__, lacStatus);
  8051. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  8052. + crp->crp_etype = EINVAL;
  8053. + goto err;
  8054. + }
  8055. +
  8056. + return 0; //OCF success status value
  8057. +
  8058. + err:
  8059. + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  8060. + kfree(drvOpData->srcBuffer.pBuffers);
  8061. + }
  8062. + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  8063. + kmem_cache_free(drvOpData_zone, drvOpData);
  8064. +
  8065. + return crp->crp_etype;
  8066. +}
  8067. +
  8068. +/* Name : icp_ocfDrvProcessDataSetup
  8069. + *
  8070. + * Description : This function will setup all the cryptographic operation data
  8071. + * that is required by LAC to execute the operation.
  8072. + */
  8073. +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  8074. + struct cryptodesc *crp_desc)
  8075. +{
  8076. + CpaCyRandGenOpData randGenOpData;
  8077. + CpaFlatBuffer randData;
  8078. +
  8079. + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  8080. +
  8081. + /* Convert from the cryptop to the ICP LAC crypto parameters */
  8082. + switch (crp_desc->crd_alg) {
  8083. + case CRYPTO_NULL_CBC:
  8084. + drvOpData->lacOpData.
  8085. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8086. + drvOpData->lacOpData.
  8087. + messageLenToCipherInBytes = crp_desc->crd_len;
  8088. + drvOpData->verifyResult = CPA_FALSE;
  8089. + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  8090. + break;
  8091. + case CRYPTO_DES_CBC:
  8092. + drvOpData->lacOpData.
  8093. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8094. + drvOpData->lacOpData.
  8095. + messageLenToCipherInBytes = crp_desc->crd_len;
  8096. + drvOpData->verifyResult = CPA_FALSE;
  8097. + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  8098. + break;
  8099. + case CRYPTO_3DES_CBC:
  8100. + drvOpData->lacOpData.
  8101. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8102. + drvOpData->lacOpData.
  8103. + messageLenToCipherInBytes = crp_desc->crd_len;
  8104. + drvOpData->verifyResult = CPA_FALSE;
  8105. + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  8106. + break;
  8107. + case CRYPTO_ARC4:
  8108. + drvOpData->lacOpData.
  8109. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8110. + drvOpData->lacOpData.
  8111. + messageLenToCipherInBytes = crp_desc->crd_len;
  8112. + drvOpData->verifyResult = CPA_FALSE;
  8113. + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  8114. + break;
  8115. + case CRYPTO_AES_CBC:
  8116. + drvOpData->lacOpData.
  8117. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8118. + drvOpData->lacOpData.
  8119. + messageLenToCipherInBytes = crp_desc->crd_len;
  8120. + drvOpData->verifyResult = CPA_FALSE;
  8121. + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  8122. + break;
  8123. + case CRYPTO_SHA1:
  8124. + case CRYPTO_SHA1_HMAC:
  8125. + case CRYPTO_SHA2_256:
  8126. + case CRYPTO_SHA2_256_HMAC:
  8127. + case CRYPTO_SHA2_384:
  8128. + case CRYPTO_SHA2_384_HMAC:
  8129. + case CRYPTO_SHA2_512:
  8130. + case CRYPTO_SHA2_512_HMAC:
  8131. + case CRYPTO_MD5:
  8132. + case CRYPTO_MD5_HMAC:
  8133. + drvOpData->lacOpData.
  8134. + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  8135. + drvOpData->lacOpData.
  8136. + messageLenToHashInBytes = crp_desc->crd_len;
  8137. + drvOpData->lacOpData.
  8138. + pDigestResult =
  8139. + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  8140. +
  8141. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  8142. + DPRINTK("%s(): ERROR - could not calculate "
  8143. + "Digest Result memory address\n", __FUNCTION__);
  8144. + return ICP_OCF_DRV_STATUS_FAIL;
  8145. + }
  8146. +
  8147. + drvOpData->lacOpData.digestVerify = CPA_FALSE;
  8148. + break;
  8149. + default:
  8150. + DPRINTK("%s(): Crypto process error - algorithm not "
  8151. + "found \n", __FUNCTION__);
  8152. + return ICP_OCF_DRV_STATUS_FAIL;
  8153. + }
  8154. +
  8155. + /* Figure out what the IV is supposed to be */
  8156. + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  8157. + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  8158. + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  8159. + /*ARC4 doesn't use an IV */
  8160. + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  8161. + /* Explicit IV provided to OCF */
  8162. + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  8163. + } else {
  8164. + /* IV is not explicitly provided to OCF */
  8165. +
  8166. + /* Point the LAC OP Data IV pointer to our allocated
  8167. + storage location for this session. */
  8168. + drvOpData->lacOpData.pIv = drvOpData->ivData;
  8169. +
  8170. + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  8171. + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  8172. +
  8173. + /* Encrypting - need to create IV */
  8174. + randGenOpData.generateBits = CPA_TRUE;
  8175. + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  8176. +
  8177. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  8178. + drvOpData->
  8179. + ivData,
  8180. + MAX_IV_LEN_IN_BYTES,
  8181. + &randData);
  8182. +
  8183. + if (CPA_STATUS_SUCCESS !=
  8184. + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  8185. + NULL, NULL,
  8186. + &randGenOpData, &randData)) {
  8187. + DPRINTK("%s(): ERROR - Failed to"
  8188. + " generate"
  8189. + " Initialisation Vector\n",
  8190. + __FUNCTION__);
  8191. + return ICP_OCF_DRV_STATUS_FAIL;
  8192. + }
  8193. +
  8194. + crypto_copyback(drvOpData->crp->
  8195. + crp_flags,
  8196. + drvOpData->crp->crp_buf,
  8197. + crp_desc->crd_inject,
  8198. + drvOpData->lacOpData.
  8199. + ivLenInBytes,
  8200. + (caddr_t) (drvOpData->lacOpData.
  8201. + pIv));
  8202. + } else {
  8203. + /* Reading IV from buffer */
  8204. + crypto_copydata(drvOpData->crp->
  8205. + crp_flags,
  8206. + drvOpData->crp->crp_buf,
  8207. + crp_desc->crd_inject,
  8208. + drvOpData->lacOpData.
  8209. + ivLenInBytes,
  8210. + (caddr_t) (drvOpData->lacOpData.
  8211. + pIv));
  8212. + }
  8213. +
  8214. + }
  8215. +
  8216. + }
  8217. +
  8218. + return ICP_OCF_DRV_STATUS_SUCCESS;
  8219. +}
  8220. +
  8221. +/* Name : icp_ocfDrvDigestPointerFind
  8222. + *
  8223. + * Description : This function is used to find the memory address of where the
  8224. + * digest information shall be stored in. Input buffer types are an skbuff, iov
  8225. + * or flat buffer. The address is found using the buffer data start address and
  8226. + * an offset.
  8227. + *
  8228. + * Note: In the case of a linux skbuff, the digest address may exist within
  8229. + * a memory space linked to from the start buffer. These linked memory spaces
  8230. + * must be traversed by the data length offset in order to find the digest start
  8231. + * address. Whether there is enough space for the digest must also be checked.
  8232. + */
  8233. +
  8234. +static uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  8235. + struct cryptodesc *crp_desc)
  8236. +{
  8237. +
  8238. + int offsetInBytes = crp_desc->crd_inject;
  8239. + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  8240. + uint8_t *flat_buffer_base = NULL;
  8241. + int flat_buffer_length = 0;
  8242. + struct sk_buff *skb;
  8243. +
  8244. + if (drvOpData->crp->crp_flags & CRYPTO_F_SKBUF) {
  8245. + /*check if enough overall space to store hash */
  8246. + skb = (struct sk_buff *)(drvOpData->crp->crp_buf);
  8247. +
  8248. + if (skb->len < (offsetInBytes + digestSizeInBytes)) {
  8249. + DPRINTK("%s() Not enough space for Digest"
  8250. + " payload after the offset (%d), "
  8251. + "digest size (%d) \n", __FUNCTION__,
  8252. + offsetInBytes, digestSizeInBytes);
  8253. + return NULL;
  8254. + }
  8255. +
  8256. + return icp_ocfDrvSkbuffDigestPointerFind(drvOpData,
  8257. + offsetInBytes,
  8258. + digestSizeInBytes);
  8259. +
  8260. + } else {
  8261. + /* IOV or flat buffer */
  8262. + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  8263. + /*single IOV check has already been done */
  8264. + flat_buffer_base = ((struct uio *)
  8265. + (drvOpData->crp->crp_buf))->
  8266. + uio_iov[0].iov_base;
  8267. + flat_buffer_length = ((struct uio *)
  8268. + (drvOpData->crp->crp_buf))->
  8269. + uio_iov[0].iov_len;
  8270. + } else {
  8271. + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  8272. + flat_buffer_length = drvOpData->crp->crp_ilen;
  8273. + }
  8274. +
  8275. + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  8276. + DPRINTK("%s() Not enough space for Digest "
  8277. + "(IOV/Flat Buffer) \n", __FUNCTION__);
  8278. + return NULL;
  8279. + } else {
  8280. + return (uint8_t *) (flat_buffer_base + offsetInBytes);
  8281. + }
  8282. + }
  8283. + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  8284. + return NULL;
  8285. +}
  8286. +
  8287. +/* Name : icp_ocfDrvSkbuffDigestPointerFind
  8288. + *
  8289. + * Description : This function is used by icp_ocfDrvDigestPointerFind to process
  8290. + * the non-linear portion of the skbuff if the fragmentation type is a linked
  8291. + * list (frag_list is not NULL in the skb_shared_info structure)
  8292. + */
  8293. +static inline uint8_t *icp_ocfDrvSkbuffDigestPointerFind(struct icp_drvOpData
  8294. + *drvOpData,
  8295. + int offsetInBytes,
  8296. + uint32_t
  8297. + digestSizeInBytes)
  8298. +{
  8299. +
  8300. + struct sk_buff *skb = NULL;
  8301. + struct skb_shared_info *skb_shared = NULL;
  8302. +
  8303. + uint32_t skbuffisnonlinear = 0;
  8304. +
  8305. + uint32_t skbheadlen = 0;
  8306. +
  8307. + skb = (struct sk_buff *)(drvOpData->crp->crp_buf);
  8308. + skbuffisnonlinear = skb_is_nonlinear(skb);
  8309. +
  8310. + skbheadlen = skb_headlen(skb);
  8311. +
  8312. + /*Linear skb checks */
  8313. + if (skbheadlen > offsetInBytes) {
  8314. +
  8315. + if (skbheadlen >= (offsetInBytes + digestSizeInBytes)) {
  8316. + return (uint8_t *) (skb->data + offsetInBytes);
  8317. + } else {
  8318. + DPRINTK("%s() Auth payload stretches "
  8319. + "accross contiguous memory\n", __FUNCTION__);
  8320. + return NULL;
  8321. + }
  8322. + } else {
  8323. + if (skbuffisnonlinear) {
  8324. + offsetInBytes -= skbheadlen;
  8325. + } else {
  8326. + DPRINTK("%s() Offset outside of buffer boundaries\n",
  8327. + __FUNCTION__);
  8328. + return NULL;
  8329. + }
  8330. + }
  8331. +
  8332. + /*Non Linear checks */
  8333. + skb_shared = (struct skb_shared_info *)(skb->end);
  8334. + if (unlikely(NULL == skb_shared)) {
  8335. + DPRINTK("%s() skbuff shared info stucture is NULL! \n",
  8336. + __FUNCTION__);
  8337. + return NULL;
  8338. + } else if ((0 != skb_shared->nr_frags) &&
  8339. + (skb_shared->frag_list != NULL)) {
  8340. + DPRINTK("%s() skbuff nr_frags AND "
  8341. + "frag_list not supported \n", __FUNCTION__);
  8342. + return NULL;
  8343. + }
  8344. +
  8345. + /*TCP segmentation more likely than IP fragmentation */
  8346. + if (likely(0 != skb_shared->nr_frags)) {
  8347. + return icp_ocfDrvDigestSkbNRFragsCheck(skb, skb_shared,
  8348. + offsetInBytes,
  8349. + digestSizeInBytes);
  8350. + } else if (skb_shared->frag_list != NULL) {
  8351. + return icp_ocfDrvDigestSkbFragListCheck(skb, skb_shared,
  8352. + offsetInBytes,
  8353. + digestSizeInBytes);
  8354. + } else {
  8355. + DPRINTK("%s() skbuff is non-linear but does not show any "
  8356. + "linked data\n", __FUNCTION__);
  8357. + return NULL;
  8358. + }
  8359. +
  8360. +}
  8361. +
  8362. +/* Name : icp_ocfDrvDigestSkbNRFragsCheck
  8363. + *
  8364. + * Description : This function is used by icp_ocfDrvSkbuffDigestPointerFind to
  8365. + * process the non-linear portion of the skbuff, if the fragmentation type is
  8366. + * page fragments
  8367. + */
  8368. +static inline uint8_t *icp_ocfDrvDigestSkbNRFragsCheck(struct sk_buff *skb,
  8369. + struct skb_shared_info
  8370. + *skb_shared,
  8371. + int offsetInBytes,
  8372. + uint32_t
  8373. + digestSizeInBytes)
  8374. +{
  8375. + int i = 0;
  8376. + /*nr_frags starts from 1 */
  8377. + if (MAX_SKB_FRAGS < skb_shared->nr_frags) {
  8378. + DPRINTK("%s error processing skbuff "
  8379. + "page frame -- MAX FRAGS exceeded \n", __FUNCTION__);
  8380. + return NULL;
  8381. + }
  8382. +
  8383. + for (i = 0; i < skb_shared->nr_frags; i++) {
  8384. +
  8385. + if (offsetInBytes >= skb_shared->frags[i].size) {
  8386. + /*offset still greater than data position */
  8387. + offsetInBytes -= skb_shared->frags[i].size;
  8388. + } else {
  8389. + /* found the page containing start of hash */
  8390. +
  8391. + if (NULL == skb_shared->frags[i].page) {
  8392. + DPRINTK("%s() Linked page is NULL!\n",
  8393. + __FUNCTION__);
  8394. + return NULL;
  8395. + }
  8396. +
  8397. + if (offsetInBytes + digestSizeInBytes >
  8398. + skb_shared->frags[i].size) {
  8399. + DPRINTK("%s() Auth payload stretches accross "
  8400. + "contiguous memory\n", __FUNCTION__);
  8401. + return NULL;
  8402. + } else {
  8403. + return (uint8_t *) (skb_shared->frags[i].page +
  8404. + skb_shared->frags[i].
  8405. + page_offset +
  8406. + offsetInBytes);
  8407. + }
  8408. + }
  8409. + /*only possible if internal page sizes are set wrong */
  8410. + if (offsetInBytes < 0) {
  8411. + DPRINTK("%s error processing skbuff page frame "
  8412. + "-- offset calculation \n", __FUNCTION__);
  8413. + return NULL;
  8414. + }
  8415. + }
  8416. + /*only possible if internal page sizes are set wrong */
  8417. + DPRINTK("%s error processing skbuff page frame "
  8418. + "-- ran out of page fragments, remaining offset = %d \n",
  8419. + __FUNCTION__, offsetInBytes);
  8420. + return NULL;
  8421. +
  8422. +}
  8423. +
  8424. +/* Name : icp_ocfDrvDigestSkbFragListCheck
  8425. + *
  8426. + * Description : This function is used by icp_ocfDrvSkbuffDigestPointerFind to
  8427. + * process the non-linear portion of the skbuff, if the fragmentation type is
  8428. + * a linked list
  8429. + *
  8430. + */
  8431. +static inline uint8_t *icp_ocfDrvDigestSkbFragListCheck(struct sk_buff *skb,
  8432. + struct skb_shared_info
  8433. + *skb_shared,
  8434. + int offsetInBytes,
  8435. + uint32_t
  8436. + digestSizeInBytes)
  8437. +{
  8438. +
  8439. + struct sk_buff *skb_list = skb_shared->frag_list;
  8440. + /*check added for readability */
  8441. + if (NULL == skb_list) {
  8442. + DPRINTK("%s error processing skbuff "
  8443. + "-- no more list! \n", __FUNCTION__);
  8444. + return NULL;
  8445. + }
  8446. +
  8447. + for (; skb_list; skb_list = skb_list->next) {
  8448. + if (NULL == skb_list) {
  8449. + DPRINTK("%s error processing skbuff "
  8450. + "-- no more list! \n", __FUNCTION__);
  8451. + return NULL;
  8452. + }
  8453. +
  8454. + if (offsetInBytes >= skb_list->len) {
  8455. + offsetInBytes -= skb_list->len;
  8456. +
  8457. + } else {
  8458. + if (offsetInBytes + digestSizeInBytes > skb_list->len) {
  8459. + DPRINTK("%s() Auth payload stretches accross "
  8460. + "contiguous memory\n", __FUNCTION__);
  8461. + return NULL;
  8462. + } else {
  8463. + return (uint8_t *)
  8464. + (skb_list->data + offsetInBytes);
  8465. + }
  8466. +
  8467. + }
  8468. +
  8469. + /*This check is only needed if internal skb_list length values
  8470. + are set wrong. */
  8471. + if (0 > offsetInBytes) {
  8472. + DPRINTK("%s() error processing skbuff object -- offset "
  8473. + "calculation \n", __FUNCTION__);
  8474. + return NULL;
  8475. + }
  8476. +
  8477. + }
  8478. +
  8479. + /*catch all for unusual for-loop exit.
  8480. + This code should never be reached */
  8481. + DPRINTK("%s() Catch-All hit! Process error.\n", __FUNCTION__);
  8482. + return NULL;
  8483. +}
  8484. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ep80579/Makefile linux-2.6.27.10/crypto/ocf/ep80579/Makefile
  8485. --- linux-2.6.27.10.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
  8486. +++ linux-2.6.27.10/crypto/ocf/ep80579/Makefile 2008-12-23 19:31:44.000000000 +0100
  8487. @@ -0,0 +1,107 @@
  8488. +#########################################################################
  8489. +#
  8490. +# Targets supported
  8491. +# all - builds everything and installs
  8492. +# install - identical to all
  8493. +# depend - build dependencies
  8494. +# clean - clears derived objects except the .depend files
  8495. +# distclean- clears all derived objects and the .depend file
  8496. +#
  8497. +# @par
  8498. +# This file is provided under a dual BSD/GPLv2 license. When using or
  8499. +# redistributing this file, you may do so under either license.
  8500. +#
  8501. +# GPL LICENSE SUMMARY
  8502. +#
  8503. +# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  8504. +#
  8505. +# This program is free software; you can redistribute it and/or modify
  8506. +# it under the terms of version 2 of the GNU General Public License as
  8507. +# published by the Free Software Foundation.
  8508. +#
  8509. +# This program is distributed in the hope that it will be useful, but
  8510. +# WITHOUT ANY WARRANTY; without even the implied warranty of
  8511. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  8512. +# General Public License for more details.
  8513. +#
  8514. +# You should have received a copy of the GNU General Public License
  8515. +# along with this program; if not, write to the Free Software
  8516. +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  8517. +# The full GNU General Public License is included in this distribution
  8518. +# in the file called LICENSE.GPL.
  8519. +#
  8520. +# Contact Information:
  8521. +# Intel Corporation
  8522. +#
  8523. +# BSD LICENSE
  8524. +#
  8525. +# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  8526. +# All rights reserved.
  8527. +#
  8528. +# Redistribution and use in source and binary forms, with or without
  8529. +# modification, are permitted provided that the following conditions
  8530. +# are met:
  8531. +#
  8532. +# * Redistributions of source code must retain the above copyright
  8533. +# notice, this list of conditions and the following disclaimer.
  8534. +# * Redistributions in binary form must reproduce the above copyright
  8535. +# notice, this list of conditions and the following disclaimer in
  8536. +# the documentation and/or other materials provided with the
  8537. +# distribution.
  8538. +# * Neither the name of Intel Corporation nor the names of its
  8539. +# contributors may be used to endorse or promote products derived
  8540. +# from this software without specific prior written permission.
  8541. +#
  8542. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  8543. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  8544. +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8545. +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  8546. +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8547. +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  8548. +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  8549. +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  8550. +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8551. +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  8552. +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8553. +#
  8554. +#
  8555. +# version: Security.L.1.0.130
  8556. +############################################################################
  8557. +
  8558. +
  8559. +####################Common variables and definitions########################
  8560. +
  8561. +# Ensure The ENV_DIR environmental var is defined.
  8562. +ifndef ICP_ENV_DIR
  8563. +$(error ICP_ENV_DIR is undefined. Please set the path to your environment makefile \
  8564. + "-> setenv ICP_ENV_DIR <path>")
  8565. +endif
  8566. +
  8567. +#Add your project environment Makefile
  8568. +include $(ICP_ENV_DIR)/environment.mk
  8569. +
  8570. +#include the makefile with all the default and common Make variable definitions
  8571. +include $(ICP_BUILDSYSTEM_PATH)/build_files/common.mk
  8572. +
  8573. +#Add the name for the executable, Library or Module output definitions
  8574. +OUTPUT_NAME= icp_ocf
  8575. +
  8576. +# List of Source Files to be compiled
  8577. +SOURCES= icp_common.c icp_sym.c icp_asym.c
  8578. +
  8579. +#common includes between all supported OSes
  8580. +INCLUDES= -I $(ICP_API_DIR) -I$(ICP_LAC_API) \
  8581. +-I$(ICP_OCF_SRC_DIR)
  8582. +
  8583. +# The location of the os level makefile needs to be changed.
  8584. +include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk
  8585. +
  8586. +# On the line directly below list the outputs you wish to build for,
  8587. +# e.g "lib_static lib_shared exe module" as show below
  8588. +install: module
  8589. +
  8590. +###################Include rules makefiles########################
  8591. +include $(ICP_BUILDSYSTEM_PATH)/build_files/rules.mk
  8592. +###################End of Rules inclusion#########################
  8593. +
  8594. +
  8595. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.27.10/crypto/ocf/hifn/hifn7751.c
  8596. --- linux-2.6.27.10.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
  8597. +++ linux-2.6.27.10/crypto/ocf/hifn/hifn7751.c 2008-12-23 19:31:44.000000000 +0100
  8598. @@ -0,0 +1,2970 @@
  8599. +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
  8600. +
  8601. +/*-
  8602. + * Invertex AEON / Hifn 7751 driver
  8603. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  8604. + * Copyright (c) 1999 Theo de Raadt
  8605. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  8606. + * http://www.netsec.net
  8607. + * Copyright (c) 2003 Hifn Inc.
  8608. + *
  8609. + * This driver is based on a previous driver by Invertex, for which they
  8610. + * requested: Please send any comments, feedback, bug-fixes, or feature
  8611. + * requests to software@invertex.com.
  8612. + *
  8613. + * Redistribution and use in source and binary forms, with or without
  8614. + * modification, are permitted provided that the following conditions
  8615. + * are met:
  8616. + *
  8617. + * 1. Redistributions of source code must retain the above copyright
  8618. + * notice, this list of conditions and the following disclaimer.
  8619. + * 2. Redistributions in binary form must reproduce the above copyright
  8620. + * notice, this list of conditions and the following disclaimer in the
  8621. + * documentation and/or other materials provided with the distribution.
  8622. + * 3. The name of the author may not be used to endorse or promote products
  8623. + * derived from this software without specific prior written permission.
  8624. + *
  8625. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  8626. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  8627. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  8628. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  8629. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  8630. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  8631. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  8632. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8633. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  8634. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8635. + *
  8636. + * Effort sponsored in part by the Defense Advanced Research Projects
  8637. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  8638. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  8639. + *
  8640. + *
  8641. +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
  8642. + */
  8643. +
  8644. +/*
  8645. + * Driver for various Hifn encryption processors.
  8646. + */
  8647. +#ifndef AUTOCONF_INCLUDED
  8648. +#include <linux/config.h>
  8649. +#endif
  8650. +#include <linux/module.h>
  8651. +#include <linux/init.h>
  8652. +#include <linux/list.h>
  8653. +#include <linux/slab.h>
  8654. +#include <linux/wait.h>
  8655. +#include <linux/sched.h>
  8656. +#include <linux/pci.h>
  8657. +#include <linux/delay.h>
  8658. +#include <linux/interrupt.h>
  8659. +#include <linux/spinlock.h>
  8660. +#include <linux/random.h>
  8661. +#include <linux/version.h>
  8662. +#include <linux/skbuff.h>
  8663. +#include <asm/io.h>
  8664. +
  8665. +#include <cryptodev.h>
  8666. +#include <uio.h>
  8667. +#include <hifn/hifn7751reg.h>
  8668. +#include <hifn/hifn7751var.h>
  8669. +
  8670. +#if 1
  8671. +#define DPRINTF(a...) if (hifn_debug) { \
  8672. + printk("%s: ", sc ? \
  8673. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  8674. + printk(a); \
  8675. + } else
  8676. +#else
  8677. +#define DPRINTF(a...)
  8678. +#endif
  8679. +
  8680. +static inline int
  8681. +pci_get_revid(struct pci_dev *dev)
  8682. +{
  8683. + u8 rid = 0;
  8684. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  8685. + return rid;
  8686. +}
  8687. +
  8688. +static struct hifn_stats hifnstats;
  8689. +
  8690. +#define debug hifn_debug
  8691. +int hifn_debug = 0;
  8692. +module_param(hifn_debug, int, 0644);
  8693. +MODULE_PARM_DESC(hifn_debug, "Enable debug");
  8694. +
  8695. +int hifn_maxbatch = 1;
  8696. +module_param(hifn_maxbatch, int, 0644);
  8697. +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
  8698. +
  8699. +#ifdef MODULE_PARM
  8700. +char *hifn_pllconfig = NULL;
  8701. +MODULE_PARM(hifn_pllconfig, "s");
  8702. +#else
  8703. +char hifn_pllconfig[32]; /* This setting is RO after loading */
  8704. +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
  8705. +#endif
  8706. +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
  8707. +
  8708. +#ifdef HIFN_VULCANDEV
  8709. +#include <sys/conf.h>
  8710. +#include <sys/uio.h>
  8711. +
  8712. +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
  8713. +#endif
  8714. +
  8715. +/*
  8716. + * Prototypes and count for the pci_device structure
  8717. + */
  8718. +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  8719. +static void hifn_remove(struct pci_dev *dev);
  8720. +
  8721. +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
  8722. +static int hifn_freesession(device_t, u_int64_t);
  8723. +static int hifn_process(device_t, struct cryptop *, int);
  8724. +
  8725. +static device_method_t hifn_methods = {
  8726. + /* crypto device methods */
  8727. + DEVMETHOD(cryptodev_newsession, hifn_newsession),
  8728. + DEVMETHOD(cryptodev_freesession,hifn_freesession),
  8729. + DEVMETHOD(cryptodev_process, hifn_process),
  8730. +};
  8731. +
  8732. +static void hifn_reset_board(struct hifn_softc *, int);
  8733. +static void hifn_reset_puc(struct hifn_softc *);
  8734. +static void hifn_puc_wait(struct hifn_softc *);
  8735. +static int hifn_enable_crypto(struct hifn_softc *);
  8736. +static void hifn_set_retry(struct hifn_softc *sc);
  8737. +static void hifn_init_dma(struct hifn_softc *);
  8738. +static void hifn_init_pci_registers(struct hifn_softc *);
  8739. +static int hifn_sramsize(struct hifn_softc *);
  8740. +static int hifn_dramsize(struct hifn_softc *);
  8741. +static int hifn_ramtype(struct hifn_softc *);
  8742. +static void hifn_sessions(struct hifn_softc *);
  8743. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  8744. +static irqreturn_t hifn_intr(int irq, void *arg);
  8745. +#else
  8746. +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
  8747. +#endif
  8748. +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
  8749. +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
  8750. +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
  8751. +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
  8752. +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
  8753. +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
  8754. +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
  8755. +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
  8756. +static int hifn_init_pubrng(struct hifn_softc *);
  8757. +static void hifn_tick(unsigned long arg);
  8758. +static void hifn_abort(struct hifn_softc *);
  8759. +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
  8760. +
  8761. +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
  8762. +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
  8763. +
  8764. +#ifdef CONFIG_OCF_RANDOMHARVEST
  8765. +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
  8766. +#endif
  8767. +
  8768. +#define HIFN_MAX_CHIPS 8
  8769. +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
  8770. +
  8771. +static __inline u_int32_t
  8772. +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
  8773. +{
  8774. + u_int32_t v = readl(sc->sc_bar0 + reg);
  8775. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  8776. + return (v);
  8777. +}
  8778. +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
  8779. +
  8780. +static __inline u_int32_t
  8781. +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
  8782. +{
  8783. + u_int32_t v = readl(sc->sc_bar1 + reg);
  8784. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  8785. + return (v);
  8786. +}
  8787. +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
  8788. +
  8789. +/*
  8790. + * map in a given buffer (great on some arches :-)
  8791. + */
  8792. +
  8793. +static int
  8794. +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
  8795. +{
  8796. + struct iovec *iov = uio->uio_iov;
  8797. +
  8798. + DPRINTF("%s()\n", __FUNCTION__);
  8799. +
  8800. + buf->mapsize = 0;
  8801. + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
  8802. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  8803. + iov->iov_base, iov->iov_len,
  8804. + PCI_DMA_BIDIRECTIONAL);
  8805. + buf->segs[buf->nsegs].ds_len = iov->iov_len;
  8806. + buf->mapsize += iov->iov_len;
  8807. + iov++;
  8808. + buf->nsegs++;
  8809. + }
  8810. + /* identify this buffer by the first segment */
  8811. + buf->map = (void *) buf->segs[0].ds_addr;
  8812. + return(0);
  8813. +}
  8814. +
  8815. +/*
  8816. + * map in a given sk_buff
  8817. + */
  8818. +
  8819. +static int
  8820. +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
  8821. +{
  8822. + int i;
  8823. +
  8824. + DPRINTF("%s()\n", __FUNCTION__);
  8825. +
  8826. + buf->mapsize = 0;
  8827. +
  8828. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  8829. + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
  8830. + buf->segs[0].ds_len = skb_headlen(skb);
  8831. + buf->mapsize += buf->segs[0].ds_len;
  8832. +
  8833. + buf->nsegs = 1;
  8834. +
  8835. + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
  8836. + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
  8837. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  8838. + page_address(skb_shinfo(skb)->frags[i].page) +
  8839. + skb_shinfo(skb)->frags[i].page_offset,
  8840. + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
  8841. + buf->mapsize += buf->segs[buf->nsegs].ds_len;
  8842. + buf->nsegs++;
  8843. + }
  8844. +
  8845. + /* identify this buffer by the first segment */
  8846. + buf->map = (void *) buf->segs[0].ds_addr;
  8847. + return(0);
  8848. +}
  8849. +
  8850. +/*
  8851. + * map in a given contiguous buffer
  8852. + */
  8853. +
  8854. +static int
  8855. +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
  8856. +{
  8857. + DPRINTF("%s()\n", __FUNCTION__);
  8858. +
  8859. + buf->mapsize = 0;
  8860. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  8861. + b, len, PCI_DMA_BIDIRECTIONAL);
  8862. + buf->segs[0].ds_len = len;
  8863. + buf->mapsize += buf->segs[0].ds_len;
  8864. + buf->nsegs = 1;
  8865. +
  8866. + /* identify this buffer by the first segment */
  8867. + buf->map = (void *) buf->segs[0].ds_addr;
  8868. + return(0);
  8869. +}
  8870. +
  8871. +#if 0 /* not needed at this time */
  8872. +static void
  8873. +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
  8874. +{
  8875. + int i;
  8876. +
  8877. + DPRINTF("%s()\n", __FUNCTION__);
  8878. + for (i = 0; i < buf->nsegs; i++)
  8879. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  8880. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  8881. +}
  8882. +#endif
  8883. +
  8884. +static void
  8885. +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
  8886. +{
  8887. + int i;
  8888. + DPRINTF("%s()\n", __FUNCTION__);
  8889. + for (i = 0; i < buf->nsegs; i++) {
  8890. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  8891. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  8892. + buf->segs[i].ds_addr = 0;
  8893. + buf->segs[i].ds_len = 0;
  8894. + }
  8895. + buf->nsegs = 0;
  8896. + buf->mapsize = 0;
  8897. + buf->map = 0;
  8898. +}
  8899. +
  8900. +static const char*
  8901. +hifn_partname(struct hifn_softc *sc)
  8902. +{
  8903. + /* XXX sprintf numbers when not decoded */
  8904. + switch (pci_get_vendor(sc->sc_pcidev)) {
  8905. + case PCI_VENDOR_HIFN:
  8906. + switch (pci_get_device(sc->sc_pcidev)) {
  8907. + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
  8908. + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
  8909. + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
  8910. + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
  8911. + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
  8912. + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
  8913. + }
  8914. + return "Hifn unknown-part";
  8915. + case PCI_VENDOR_INVERTEX:
  8916. + switch (pci_get_device(sc->sc_pcidev)) {
  8917. + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
  8918. + }
  8919. + return "Invertex unknown-part";
  8920. + case PCI_VENDOR_NETSEC:
  8921. + switch (pci_get_device(sc->sc_pcidev)) {
  8922. + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
  8923. + }
  8924. + return "NetSec unknown-part";
  8925. + }
  8926. + return "Unknown-vendor unknown-part";
  8927. +}
  8928. +
  8929. +static u_int
  8930. +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
  8931. +{
  8932. + struct hifn_softc *sc = pci_get_drvdata(dev);
  8933. + if (v > max) {
  8934. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  8935. + "using max %u\n", what, v, max);
  8936. + v = max;
  8937. + } else if (v < min) {
  8938. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  8939. + "using min %u\n", what, v, min);
  8940. + v = min;
  8941. + }
  8942. + return v;
  8943. +}
  8944. +
  8945. +/*
  8946. + * Select PLL configuration for 795x parts. This is complicated in
  8947. + * that we cannot determine the optimal parameters without user input.
  8948. + * The reference clock is derived from an external clock through a
  8949. + * multiplier. The external clock is either the host bus (i.e. PCI)
  8950. + * or an external clock generator. When using the PCI bus we assume
  8951. + * the clock is either 33 or 66 MHz; for an external source we cannot
  8952. + * tell the speed.
  8953. + *
  8954. + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
  8955. + * for an external source, followed by the frequency. We calculate
  8956. + * the appropriate multiplier and PLL register contents accordingly.
  8957. + * When no configuration is given we default to "pci66" since that
  8958. + * always will allow the card to work. If a card is using the PCI
  8959. + * bus clock and in a 33MHz slot then it will be operating at half
  8960. + * speed until the correct information is provided.
  8961. + *
  8962. + * We use a default setting of "ext66" because according to Mike Ham
  8963. + * of HiFn, almost every board in existence has an external crystal
  8964. + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
  8965. + * because PCI33 can have clocks from 0 to 33Mhz, and some have
  8966. + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
  8967. + */
  8968. +static void
  8969. +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
  8970. +{
  8971. + const char *pllspec = hifn_pllconfig;
  8972. + u_int freq, mul, fl, fh;
  8973. + u_int32_t pllconfig;
  8974. + char *nxt;
  8975. +
  8976. + if (pllspec == NULL)
  8977. + pllspec = "ext66";
  8978. + fl = 33, fh = 66;
  8979. + pllconfig = 0;
  8980. + if (strncmp(pllspec, "ext", 3) == 0) {
  8981. + pllspec += 3;
  8982. + pllconfig |= HIFN_PLL_REF_SEL;
  8983. + switch (pci_get_device(dev)) {
  8984. + case PCI_PRODUCT_HIFN_7955:
  8985. + case PCI_PRODUCT_HIFN_7956:
  8986. + fl = 20, fh = 100;
  8987. + break;
  8988. +#ifdef notyet
  8989. + case PCI_PRODUCT_HIFN_7954:
  8990. + fl = 20, fh = 66;
  8991. + break;
  8992. +#endif
  8993. + }
  8994. + } else if (strncmp(pllspec, "pci", 3) == 0)
  8995. + pllspec += 3;
  8996. + freq = strtoul(pllspec, &nxt, 10);
  8997. + if (nxt == pllspec)
  8998. + freq = 66;
  8999. + else
  9000. + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
  9001. + /*
  9002. + * Calculate multiplier. We target a Fck of 266 MHz,
  9003. + * allowing only even values, possibly rounded down.
  9004. + * Multipliers > 8 must set the charge pump current.
  9005. + */
  9006. + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
  9007. + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
  9008. + if (mul > 8)
  9009. + pllconfig |= HIFN_PLL_IS;
  9010. + *pll = pllconfig;
  9011. +}
  9012. +
  9013. +/*
  9014. + * Attach an interface that successfully probed.
  9015. + */
  9016. +static int
  9017. +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  9018. +{
  9019. + struct hifn_softc *sc = NULL;
  9020. + char rbase;
  9021. + u_int16_t ena, rev;
  9022. + int rseg, rc;
  9023. + unsigned long mem_start, mem_len;
  9024. + static int num_chips = 0;
  9025. +
  9026. + DPRINTF("%s()\n", __FUNCTION__);
  9027. +
  9028. + if (pci_enable_device(dev) < 0)
  9029. + return(-ENODEV);
  9030. +
  9031. + if (pci_set_mwi(dev))
  9032. + return(-ENODEV);
  9033. +
  9034. + if (!dev->irq) {
  9035. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  9036. + pci_disable_device(dev);
  9037. + return(-ENODEV);
  9038. + }
  9039. +
  9040. + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  9041. + if (!sc)
  9042. + return(-ENOMEM);
  9043. + memset(sc, 0, sizeof(*sc));
  9044. +
  9045. + softc_device_init(sc, "hifn", num_chips, hifn_methods);
  9046. +
  9047. + sc->sc_pcidev = dev;
  9048. + sc->sc_irq = -1;
  9049. + sc->sc_cid = -1;
  9050. + sc->sc_num = num_chips++;
  9051. + if (sc->sc_num < HIFN_MAX_CHIPS)
  9052. + hifn_chip_idx[sc->sc_num] = sc;
  9053. +
  9054. + pci_set_drvdata(sc->sc_pcidev, sc);
  9055. +
  9056. + spin_lock_init(&sc->sc_mtx);
  9057. +
  9058. + /* XXX handle power management */
  9059. +
  9060. + /*
  9061. + * The 7951 and 795x have a random number generator and
  9062. + * public key support; note this.
  9063. + */
  9064. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  9065. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
  9066. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  9067. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
  9068. + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
  9069. + /*
  9070. + * The 7811 has a random number generator and
  9071. + * we also note it's identity 'cuz of some quirks.
  9072. + */
  9073. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  9074. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
  9075. + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
  9076. +
  9077. + /*
  9078. + * The 795x parts support AES.
  9079. + */
  9080. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  9081. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  9082. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
  9083. + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
  9084. + /*
  9085. + * Select PLL configuration. This depends on the
  9086. + * bus and board design and must be manually configured
  9087. + * if the default setting is unacceptable.
  9088. + */
  9089. + hifn_getpllconfig(dev, &sc->sc_pllconfig);
  9090. + }
  9091. +
  9092. + /*
  9093. + * Setup PCI resources. Note that we record the bus
  9094. + * tag and handle for each register mapping, this is
  9095. + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
  9096. + * and WRITE_REG_1 macros throughout the driver.
  9097. + */
  9098. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  9099. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  9100. + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  9101. + if (!sc->sc_bar0) {
  9102. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
  9103. + goto fail;
  9104. + }
  9105. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  9106. +
  9107. + mem_start = pci_resource_start(sc->sc_pcidev, 1);
  9108. + mem_len = pci_resource_len(sc->sc_pcidev, 1);
  9109. + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  9110. + if (!sc->sc_bar1) {
  9111. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
  9112. + goto fail;
  9113. + }
  9114. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  9115. +
  9116. + /* fix up the bus size */
  9117. + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
  9118. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  9119. + goto fail;
  9120. + }
  9121. + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
  9122. + device_printf(sc->sc_dev,
  9123. + "No usable consistent DMA configuration, aborting.\n");
  9124. + goto fail;
  9125. + }
  9126. +
  9127. + hifn_set_retry(sc);
  9128. +
  9129. + /*
  9130. + * Setup the area where the Hifn DMA's descriptors
  9131. + * and associated data structures.
  9132. + */
  9133. + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
  9134. + sizeof(*sc->sc_dma),
  9135. + &sc->sc_dma_physaddr);
  9136. + if (!sc->sc_dma) {
  9137. + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
  9138. + goto fail;
  9139. + }
  9140. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  9141. +
  9142. + /*
  9143. + * Reset the board and do the ``secret handshake''
  9144. + * to enable the crypto support. Then complete the
  9145. + * initialization procedure by setting up the interrupt
  9146. + * and hooking in to the system crypto support so we'll
  9147. + * get used for system services like the crypto device,
  9148. + * IPsec, RNG device, etc.
  9149. + */
  9150. + hifn_reset_board(sc, 0);
  9151. +
  9152. + if (hifn_enable_crypto(sc) != 0) {
  9153. + device_printf(sc->sc_dev, "crypto enabling failed\n");
  9154. + goto fail;
  9155. + }
  9156. + hifn_reset_puc(sc);
  9157. +
  9158. + hifn_init_dma(sc);
  9159. + hifn_init_pci_registers(sc);
  9160. +
  9161. + pci_set_master(sc->sc_pcidev);
  9162. +
  9163. + /* XXX can't dynamically determine ram type for 795x; force dram */
  9164. + if (sc->sc_flags & HIFN_IS_7956)
  9165. + sc->sc_drammodel = 1;
  9166. + else if (hifn_ramtype(sc))
  9167. + goto fail;
  9168. +
  9169. + if (sc->sc_drammodel == 0)
  9170. + hifn_sramsize(sc);
  9171. + else
  9172. + hifn_dramsize(sc);
  9173. +
  9174. + /*
  9175. + * Workaround for NetSec 7751 rev A: half ram size because two
  9176. + * of the address lines were left floating
  9177. + */
  9178. + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
  9179. + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
  9180. + pci_get_revid(dev) == 0x61) /*XXX???*/
  9181. + sc->sc_ramsize >>= 1;
  9182. +
  9183. + /*
  9184. + * Arrange the interrupt line.
  9185. + */
  9186. + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
  9187. + if (rc) {
  9188. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  9189. + goto fail;
  9190. + }
  9191. + sc->sc_irq = dev->irq;
  9192. +
  9193. + hifn_sessions(sc);
  9194. +
  9195. + /*
  9196. + * NB: Keep only the low 16 bits; this masks the chip id
  9197. + * from the 7951.
  9198. + */
  9199. + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
  9200. +
  9201. + rseg = sc->sc_ramsize / 1024;
  9202. + rbase = 'K';
  9203. + if (sc->sc_ramsize >= (1024 * 1024)) {
  9204. + rbase = 'M';
  9205. + rseg /= 1024;
  9206. + }
  9207. + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
  9208. + hifn_partname(sc), rev,
  9209. + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
  9210. + if (sc->sc_flags & HIFN_IS_7956)
  9211. + printf(", pll=0x%x<%s clk, %ux mult>",
  9212. + sc->sc_pllconfig,
  9213. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  9214. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  9215. + printf("\n");
  9216. +
  9217. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  9218. + if (sc->sc_cid < 0) {
  9219. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  9220. + goto fail;
  9221. + }
  9222. +
  9223. + WRITE_REG_0(sc, HIFN_0_PUCNFG,
  9224. + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
  9225. + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  9226. +
  9227. + switch (ena) {
  9228. + case HIFN_PUSTAT_ENA_2:
  9229. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  9230. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  9231. + if (sc->sc_flags & HIFN_HAS_AES)
  9232. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  9233. + /*FALLTHROUGH*/
  9234. + case HIFN_PUSTAT_ENA_1:
  9235. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  9236. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  9237. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  9238. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  9239. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  9240. + break;
  9241. + }
  9242. +
  9243. + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
  9244. + hifn_init_pubrng(sc);
  9245. +
  9246. + init_timer(&sc->sc_tickto);
  9247. + sc->sc_tickto.function = hifn_tick;
  9248. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  9249. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  9250. +
  9251. + return (0);
  9252. +
  9253. +fail:
  9254. + if (sc->sc_cid >= 0)
  9255. + crypto_unregister_all(sc->sc_cid);
  9256. + if (sc->sc_irq != -1)
  9257. + free_irq(sc->sc_irq, sc);
  9258. + if (sc->sc_dma) {
  9259. + /* Turn off DMA polling */
  9260. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9261. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9262. +
  9263. + pci_free_consistent(sc->sc_pcidev,
  9264. + sizeof(*sc->sc_dma),
  9265. + sc->sc_dma, sc->sc_dma_physaddr);
  9266. + }
  9267. + kfree(sc);
  9268. + return (-ENXIO);
  9269. +}
  9270. +
  9271. +/*
  9272. + * Detach an interface that successfully probed.
  9273. + */
  9274. +static void
  9275. +hifn_remove(struct pci_dev *dev)
  9276. +{
  9277. + struct hifn_softc *sc = pci_get_drvdata(dev);
  9278. + unsigned long l_flags;
  9279. +
  9280. + DPRINTF("%s()\n", __FUNCTION__);
  9281. +
  9282. + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
  9283. +
  9284. + /* disable interrupts */
  9285. + HIFN_LOCK(sc);
  9286. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  9287. + HIFN_UNLOCK(sc);
  9288. +
  9289. + /*XXX other resources */
  9290. + del_timer_sync(&sc->sc_tickto);
  9291. +
  9292. + /* Turn off DMA polling */
  9293. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9294. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9295. +
  9296. + crypto_unregister_all(sc->sc_cid);
  9297. +
  9298. + free_irq(sc->sc_irq, sc);
  9299. +
  9300. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  9301. + sc->sc_dma, sc->sc_dma_physaddr);
  9302. +}
  9303. +
  9304. +
  9305. +static int
  9306. +hifn_init_pubrng(struct hifn_softc *sc)
  9307. +{
  9308. + int i;
  9309. +
  9310. + DPRINTF("%s()\n", __FUNCTION__);
  9311. +
  9312. + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
  9313. + /* Reset 7951 public key/rng engine */
  9314. + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
  9315. + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
  9316. +
  9317. + for (i = 0; i < 100; i++) {
  9318. + DELAY(1000);
  9319. + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
  9320. + HIFN_PUBRST_RESET) == 0)
  9321. + break;
  9322. + }
  9323. +
  9324. + if (i == 100) {
  9325. + device_printf(sc->sc_dev, "public key init failed\n");
  9326. + return (1);
  9327. + }
  9328. + }
  9329. +
  9330. + /* Enable the rng, if available */
  9331. +#ifdef CONFIG_OCF_RANDOMHARVEST
  9332. + if (sc->sc_flags & HIFN_HAS_RNG) {
  9333. + if (sc->sc_flags & HIFN_IS_7811) {
  9334. + u_int32_t r;
  9335. + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
  9336. + if (r & HIFN_7811_RNGENA_ENA) {
  9337. + r &= ~HIFN_7811_RNGENA_ENA;
  9338. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  9339. + }
  9340. + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
  9341. + HIFN_7811_RNGCFG_DEFL);
  9342. + r |= HIFN_7811_RNGENA_ENA;
  9343. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  9344. + } else
  9345. + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
  9346. + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
  9347. + HIFN_RNGCFG_ENA);
  9348. +
  9349. + sc->sc_rngfirst = 1;
  9350. + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
  9351. + }
  9352. +#endif
  9353. +
  9354. + /* Enable public key engine, if available */
  9355. + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
  9356. + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
  9357. + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
  9358. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  9359. +#ifdef HIFN_VULCANDEV
  9360. + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
  9361. + UID_ROOT, GID_WHEEL, 0666,
  9362. + "vulcanpk");
  9363. + sc->sc_pkdev->si_drv1 = sc;
  9364. +#endif
  9365. + }
  9366. +
  9367. + return (0);
  9368. +}
  9369. +
  9370. +#ifdef CONFIG_OCF_RANDOMHARVEST
  9371. +static int
  9372. +hifn_read_random(void *arg, u_int32_t *buf, int len)
  9373. +{
  9374. + struct hifn_softc *sc = (struct hifn_softc *) arg;
  9375. + u_int32_t sts;
  9376. + int i, rc = 0;
  9377. +
  9378. + if (len <= 0)
  9379. + return rc;
  9380. +
  9381. + if (sc->sc_flags & HIFN_IS_7811) {
  9382. + /* ONLY VALID ON 7811!!!! */
  9383. + for (i = 0; i < 5; i++) {
  9384. + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
  9385. + if (sts & HIFN_7811_RNGSTS_UFL) {
  9386. + device_printf(sc->sc_dev,
  9387. + "RNG underflow: disabling\n");
  9388. + /* DAVIDM perhaps return -1 */
  9389. + break;
  9390. + }
  9391. + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
  9392. + break;
  9393. +
  9394. + /*
  9395. + * There are at least two words in the RNG FIFO
  9396. + * at this point.
  9397. + */
  9398. + if (rc < len)
  9399. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  9400. + if (rc < len)
  9401. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  9402. + }
  9403. + } else
  9404. + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
  9405. +
  9406. + /* NB: discard first data read */
  9407. + if (sc->sc_rngfirst) {
  9408. + sc->sc_rngfirst = 0;
  9409. + rc = 0;
  9410. + }
  9411. +
  9412. + return(rc);
  9413. +}
  9414. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  9415. +
  9416. +static void
  9417. +hifn_puc_wait(struct hifn_softc *sc)
  9418. +{
  9419. + int i;
  9420. + int reg = HIFN_0_PUCTRL;
  9421. +
  9422. + if (sc->sc_flags & HIFN_IS_7956) {
  9423. + reg = HIFN_0_PUCTRL2;
  9424. + }
  9425. +
  9426. + for (i = 5000; i > 0; i--) {
  9427. + DELAY(1);
  9428. + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
  9429. + break;
  9430. + }
  9431. + if (!i)
  9432. + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
  9433. + READ_REG_0(sc, HIFN_0_PUCTRL));
  9434. +}
  9435. +
  9436. +/*
  9437. + * Reset the processing unit.
  9438. + */
  9439. +static void
  9440. +hifn_reset_puc(struct hifn_softc *sc)
  9441. +{
  9442. + /* Reset processing unit */
  9443. + int reg = HIFN_0_PUCTRL;
  9444. +
  9445. + if (sc->sc_flags & HIFN_IS_7956) {
  9446. + reg = HIFN_0_PUCTRL2;
  9447. + }
  9448. + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
  9449. +
  9450. + hifn_puc_wait(sc);
  9451. +}
  9452. +
  9453. +/*
  9454. + * Set the Retry and TRDY registers; note that we set them to
  9455. + * zero because the 7811 locks up when forced to retry (section
  9456. + * 3.6 of "Specification Update SU-0014-04". Not clear if we
  9457. + * should do this for all Hifn parts, but it doesn't seem to hurt.
  9458. + */
  9459. +static void
  9460. +hifn_set_retry(struct hifn_softc *sc)
  9461. +{
  9462. + DPRINTF("%s()\n", __FUNCTION__);
  9463. + /* NB: RETRY only responds to 8-bit reads/writes */
  9464. + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
  9465. + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
  9466. +}
  9467. +
  9468. +/*
  9469. + * Resets the board. Values in the regesters are left as is
  9470. + * from the reset (i.e. initial values are assigned elsewhere).
  9471. + */
  9472. +static void
  9473. +hifn_reset_board(struct hifn_softc *sc, int full)
  9474. +{
  9475. + u_int32_t reg;
  9476. +
  9477. + DPRINTF("%s()\n", __FUNCTION__);
  9478. + /*
  9479. + * Set polling in the DMA configuration register to zero. 0x7 avoids
  9480. + * resetting the board and zeros out the other fields.
  9481. + */
  9482. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9483. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9484. +
  9485. + /*
  9486. + * Now that polling has been disabled, we have to wait 1 ms
  9487. + * before resetting the board.
  9488. + */
  9489. + DELAY(1000);
  9490. +
  9491. + /* Reset the DMA unit */
  9492. + if (full) {
  9493. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
  9494. + DELAY(1000);
  9495. + } else {
  9496. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
  9497. + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
  9498. + hifn_reset_puc(sc);
  9499. + }
  9500. +
  9501. + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
  9502. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  9503. +
  9504. + /* Bring dma unit out of reset */
  9505. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9506. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9507. +
  9508. + hifn_puc_wait(sc);
  9509. + hifn_set_retry(sc);
  9510. +
  9511. + if (sc->sc_flags & HIFN_IS_7811) {
  9512. + for (reg = 0; reg < 1000; reg++) {
  9513. + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
  9514. + HIFN_MIPSRST_CRAMINIT)
  9515. + break;
  9516. + DELAY(1000);
  9517. + }
  9518. + if (reg == 1000)
  9519. + device_printf(sc->sc_dev, ": cram init timeout\n");
  9520. + } else {
  9521. + /* set up DMA configuration register #2 */
  9522. + /* turn off all PK and BAR0 swaps */
  9523. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
  9524. + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
  9525. + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
  9526. + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
  9527. + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
  9528. + }
  9529. +}
  9530. +
  9531. +static u_int32_t
  9532. +hifn_next_signature(u_int32_t a, u_int cnt)
  9533. +{
  9534. + int i;
  9535. + u_int32_t v;
  9536. +
  9537. + for (i = 0; i < cnt; i++) {
  9538. +
  9539. + /* get the parity */
  9540. + v = a & 0x80080125;
  9541. + v ^= v >> 16;
  9542. + v ^= v >> 8;
  9543. + v ^= v >> 4;
  9544. + v ^= v >> 2;
  9545. + v ^= v >> 1;
  9546. +
  9547. + a = (v & 1) ^ (a << 1);
  9548. + }
  9549. +
  9550. + return a;
  9551. +}
  9552. +
  9553. +
  9554. +/*
  9555. + * Checks to see if crypto is already enabled. If crypto isn't enable,
  9556. + * "hifn_enable_crypto" is called to enable it. The check is important,
  9557. + * as enabling crypto twice will lock the board.
  9558. + */
  9559. +static int
  9560. +hifn_enable_crypto(struct hifn_softc *sc)
  9561. +{
  9562. + u_int32_t dmacfg, ramcfg, encl, addr, i;
  9563. + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  9564. + 0x00, 0x00, 0x00, 0x00 };
  9565. +
  9566. + DPRINTF("%s()\n", __FUNCTION__);
  9567. +
  9568. + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  9569. + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
  9570. +
  9571. + /*
  9572. + * The RAM config register's encrypt level bit needs to be set before
  9573. + * every read performed on the encryption level register.
  9574. + */
  9575. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  9576. +
  9577. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  9578. +
  9579. + /*
  9580. + * Make sure we don't re-unlock. Two unlocks kills chip until the
  9581. + * next reboot.
  9582. + */
  9583. + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
  9584. +#ifdef HIFN_DEBUG
  9585. + if (hifn_debug)
  9586. + device_printf(sc->sc_dev,
  9587. + "Strong crypto already enabled!\n");
  9588. +#endif
  9589. + goto report;
  9590. + }
  9591. +
  9592. + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
  9593. +#ifdef HIFN_DEBUG
  9594. + if (hifn_debug)
  9595. + device_printf(sc->sc_dev,
  9596. + "Unknown encryption level 0x%x\n", encl);
  9597. +#endif
  9598. + return 1;
  9599. + }
  9600. +
  9601. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
  9602. + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9603. + DELAY(1000);
  9604. + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
  9605. + DELAY(1000);
  9606. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
  9607. + DELAY(1000);
  9608. +
  9609. + for (i = 0; i <= 12; i++) {
  9610. + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
  9611. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
  9612. +
  9613. + DELAY(1000);
  9614. + }
  9615. +
  9616. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  9617. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  9618. +
  9619. +#ifdef HIFN_DEBUG
  9620. + if (hifn_debug) {
  9621. + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
  9622. + device_printf(sc->sc_dev, "Engine is permanently "
  9623. + "locked until next system reset!\n");
  9624. + else
  9625. + device_printf(sc->sc_dev, "Engine enabled "
  9626. + "successfully!\n");
  9627. + }
  9628. +#endif
  9629. +
  9630. +report:
  9631. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
  9632. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
  9633. +
  9634. + switch (encl) {
  9635. + case HIFN_PUSTAT_ENA_1:
  9636. + case HIFN_PUSTAT_ENA_2:
  9637. + break;
  9638. + case HIFN_PUSTAT_ENA_0:
  9639. + default:
  9640. + device_printf(sc->sc_dev, "disabled\n");
  9641. + break;
  9642. + }
  9643. +
  9644. + return 0;
  9645. +}
  9646. +
  9647. +/*
  9648. + * Give initial values to the registers listed in the "Register Space"
  9649. + * section of the HIFN Software Development reference manual.
  9650. + */
  9651. +static void
  9652. +hifn_init_pci_registers(struct hifn_softc *sc)
  9653. +{
  9654. + DPRINTF("%s()\n", __FUNCTION__);
  9655. +
  9656. + /* write fixed values needed by the Initialization registers */
  9657. + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
  9658. + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
  9659. + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
  9660. +
  9661. + /* write all 4 ring address registers */
  9662. + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
  9663. + offsetof(struct hifn_dma, cmdr[0]));
  9664. + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
  9665. + offsetof(struct hifn_dma, srcr[0]));
  9666. + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
  9667. + offsetof(struct hifn_dma, dstr[0]));
  9668. + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
  9669. + offsetof(struct hifn_dma, resr[0]));
  9670. +
  9671. + DELAY(2000);
  9672. +
  9673. + /* write status register */
  9674. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  9675. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
  9676. + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
  9677. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
  9678. + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
  9679. + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
  9680. + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
  9681. + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
  9682. + HIFN_DMACSR_S_WAIT |
  9683. + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
  9684. + HIFN_DMACSR_C_WAIT |
  9685. + HIFN_DMACSR_ENGINE |
  9686. + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
  9687. + HIFN_DMACSR_PUBDONE : 0) |
  9688. + ((sc->sc_flags & HIFN_IS_7811) ?
  9689. + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
  9690. +
  9691. + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
  9692. + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
  9693. + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
  9694. + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
  9695. + ((sc->sc_flags & HIFN_IS_7811) ?
  9696. + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
  9697. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  9698. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  9699. +
  9700. +
  9701. + if (sc->sc_flags & HIFN_IS_7956) {
  9702. + u_int32_t pll;
  9703. +
  9704. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  9705. + HIFN_PUCNFG_TCALLPHASES |
  9706. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
  9707. +
  9708. + /* turn off the clocks and insure bypass is set */
  9709. + pll = READ_REG_1(sc, HIFN_1_PLL);
  9710. + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
  9711. + | HIFN_PLL_BP | HIFN_PLL_MBSET;
  9712. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  9713. + DELAY(10*1000); /* 10ms */
  9714. +
  9715. + /* change configuration */
  9716. + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
  9717. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  9718. + DELAY(10*1000); /* 10ms */
  9719. +
  9720. + /* disable bypass */
  9721. + pll &= ~HIFN_PLL_BP;
  9722. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  9723. + /* enable clocks with new configuration */
  9724. + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
  9725. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  9726. + } else {
  9727. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  9728. + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
  9729. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
  9730. + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
  9731. + }
  9732. +
  9733. + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
  9734. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9735. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
  9736. + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
  9737. + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
  9738. +}
  9739. +
  9740. +/*
  9741. + * The maximum number of sessions supported by the card
  9742. + * is dependent on the amount of context ram, which
  9743. + * encryption algorithms are enabled, and how compression
  9744. + * is configured. This should be configured before this
  9745. + * routine is called.
  9746. + */
  9747. +static void
  9748. +hifn_sessions(struct hifn_softc *sc)
  9749. +{
  9750. + u_int32_t pucnfg;
  9751. + int ctxsize;
  9752. +
  9753. + DPRINTF("%s()\n", __FUNCTION__);
  9754. +
  9755. + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  9756. +
  9757. + if (pucnfg & HIFN_PUCNFG_COMPSING) {
  9758. + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
  9759. + ctxsize = 128;
  9760. + else
  9761. + ctxsize = 512;
  9762. + /*
  9763. + * 7955/7956 has internal context memory of 32K
  9764. + */
  9765. + if (sc->sc_flags & HIFN_IS_7956)
  9766. + sc->sc_maxses = 32768 / ctxsize;
  9767. + else
  9768. + sc->sc_maxses = 1 +
  9769. + ((sc->sc_ramsize - 32768) / ctxsize);
  9770. + } else
  9771. + sc->sc_maxses = sc->sc_ramsize / 16384;
  9772. +
  9773. + if (sc->sc_maxses > 2048)
  9774. + sc->sc_maxses = 2048;
  9775. +}
  9776. +
  9777. +/*
  9778. + * Determine ram type (sram or dram). Board should be just out of a reset
  9779. + * state when this is called.
  9780. + */
  9781. +static int
  9782. +hifn_ramtype(struct hifn_softc *sc)
  9783. +{
  9784. + u_int8_t data[8], dataexpect[8];
  9785. + int i;
  9786. +
  9787. + for (i = 0; i < sizeof(data); i++)
  9788. + data[i] = dataexpect[i] = 0x55;
  9789. + if (hifn_writeramaddr(sc, 0, data))
  9790. + return (-1);
  9791. + if (hifn_readramaddr(sc, 0, data))
  9792. + return (-1);
  9793. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  9794. + sc->sc_drammodel = 1;
  9795. + return (0);
  9796. + }
  9797. +
  9798. + for (i = 0; i < sizeof(data); i++)
  9799. + data[i] = dataexpect[i] = 0xaa;
  9800. + if (hifn_writeramaddr(sc, 0, data))
  9801. + return (-1);
  9802. + if (hifn_readramaddr(sc, 0, data))
  9803. + return (-1);
  9804. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  9805. + sc->sc_drammodel = 1;
  9806. + return (0);
  9807. + }
  9808. +
  9809. + return (0);
  9810. +}
  9811. +
  9812. +#define HIFN_SRAM_MAX (32 << 20)
  9813. +#define HIFN_SRAM_STEP_SIZE 16384
  9814. +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
  9815. +
  9816. +static int
  9817. +hifn_sramsize(struct hifn_softc *sc)
  9818. +{
  9819. + u_int32_t a;
  9820. + u_int8_t data[8];
  9821. + u_int8_t dataexpect[sizeof(data)];
  9822. + int32_t i;
  9823. +
  9824. + for (i = 0; i < sizeof(data); i++)
  9825. + data[i] = dataexpect[i] = i ^ 0x5a;
  9826. +
  9827. + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
  9828. + a = i * HIFN_SRAM_STEP_SIZE;
  9829. + bcopy(&i, data, sizeof(i));
  9830. + hifn_writeramaddr(sc, a, data);
  9831. + }
  9832. +
  9833. + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
  9834. + a = i * HIFN_SRAM_STEP_SIZE;
  9835. + bcopy(&i, dataexpect, sizeof(i));
  9836. + if (hifn_readramaddr(sc, a, data) < 0)
  9837. + return (0);
  9838. + if (bcmp(data, dataexpect, sizeof(data)) != 0)
  9839. + return (0);
  9840. + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
  9841. + }
  9842. +
  9843. + return (0);
  9844. +}
  9845. +
  9846. +/*
  9847. + * XXX For dram boards, one should really try all of the
  9848. + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
  9849. + * is already set up correctly.
  9850. + */
  9851. +static int
  9852. +hifn_dramsize(struct hifn_softc *sc)
  9853. +{
  9854. + u_int32_t cnfg;
  9855. +
  9856. + if (sc->sc_flags & HIFN_IS_7956) {
  9857. + /*
  9858. + * 7955/7956 have a fixed internal ram of only 32K.
  9859. + */
  9860. + sc->sc_ramsize = 32768;
  9861. + } else {
  9862. + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
  9863. + HIFN_PUCNFG_DRAMMASK;
  9864. + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
  9865. + }
  9866. + return (0);
  9867. +}
  9868. +
  9869. +static void
  9870. +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
  9871. +{
  9872. + struct hifn_dma *dma = sc->sc_dma;
  9873. +
  9874. + DPRINTF("%s()\n", __FUNCTION__);
  9875. +
  9876. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  9877. + dma->cmdi = 0;
  9878. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  9879. + wmb();
  9880. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  9881. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  9882. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  9883. + }
  9884. + *cmdp = dma->cmdi++;
  9885. + dma->cmdk = dma->cmdi;
  9886. +
  9887. + if (dma->srci == HIFN_D_SRC_RSIZE) {
  9888. + dma->srci = 0;
  9889. + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  9890. + wmb();
  9891. + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
  9892. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  9893. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  9894. + }
  9895. + *srcp = dma->srci++;
  9896. + dma->srck = dma->srci;
  9897. +
  9898. + if (dma->dsti == HIFN_D_DST_RSIZE) {
  9899. + dma->dsti = 0;
  9900. + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  9901. + wmb();
  9902. + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
  9903. + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
  9904. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  9905. + }
  9906. + *dstp = dma->dsti++;
  9907. + dma->dstk = dma->dsti;
  9908. +
  9909. + if (dma->resi == HIFN_D_RES_RSIZE) {
  9910. + dma->resi = 0;
  9911. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  9912. + wmb();
  9913. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  9914. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  9915. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  9916. + }
  9917. + *resp = dma->resi++;
  9918. + dma->resk = dma->resi;
  9919. +}
  9920. +
  9921. +static int
  9922. +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  9923. +{
  9924. + struct hifn_dma *dma = sc->sc_dma;
  9925. + hifn_base_command_t wc;
  9926. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  9927. + int r, cmdi, resi, srci, dsti;
  9928. +
  9929. + DPRINTF("%s()\n", __FUNCTION__);
  9930. +
  9931. + wc.masks = htole16(3 << 13);
  9932. + wc.session_num = htole16(addr >> 14);
  9933. + wc.total_source_count = htole16(8);
  9934. + wc.total_dest_count = htole16(addr & 0x3fff);
  9935. +
  9936. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  9937. +
  9938. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  9939. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  9940. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  9941. +
  9942. + /* build write command */
  9943. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  9944. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
  9945. + bcopy(data, &dma->test_src, sizeof(dma->test_src));
  9946. +
  9947. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
  9948. + + offsetof(struct hifn_dma, test_src));
  9949. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
  9950. + + offsetof(struct hifn_dma, test_dst));
  9951. +
  9952. + dma->cmdr[cmdi].l = htole32(16 | masks);
  9953. + dma->srcr[srci].l = htole32(8 | masks);
  9954. + dma->dstr[dsti].l = htole32(4 | masks);
  9955. + dma->resr[resi].l = htole32(4 | masks);
  9956. +
  9957. + for (r = 10000; r >= 0; r--) {
  9958. + DELAY(10);
  9959. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  9960. + break;
  9961. + }
  9962. + if (r == 0) {
  9963. + device_printf(sc->sc_dev, "writeramaddr -- "
  9964. + "result[%d](addr %d) still valid\n", resi, addr);
  9965. + r = -1;
  9966. + return (-1);
  9967. + } else
  9968. + r = 0;
  9969. +
  9970. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  9971. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  9972. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  9973. +
  9974. + return (r);
  9975. +}
  9976. +
  9977. +static int
  9978. +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  9979. +{
  9980. + struct hifn_dma *dma = sc->sc_dma;
  9981. + hifn_base_command_t rc;
  9982. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  9983. + int r, cmdi, srci, dsti, resi;
  9984. +
  9985. + DPRINTF("%s()\n", __FUNCTION__);
  9986. +
  9987. + rc.masks = htole16(2 << 13);
  9988. + rc.session_num = htole16(addr >> 14);
  9989. + rc.total_source_count = htole16(addr & 0x3fff);
  9990. + rc.total_dest_count = htole16(8);
  9991. +
  9992. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  9993. +
  9994. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  9995. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  9996. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  9997. +
  9998. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  9999. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
  10000. +
  10001. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
  10002. + offsetof(struct hifn_dma, test_src));
  10003. + dma->test_src = 0;
  10004. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
  10005. + offsetof(struct hifn_dma, test_dst));
  10006. + dma->test_dst = 0;
  10007. + dma->cmdr[cmdi].l = htole32(8 | masks);
  10008. + dma->srcr[srci].l = htole32(8 | masks);
  10009. + dma->dstr[dsti].l = htole32(8 | masks);
  10010. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
  10011. +
  10012. + for (r = 10000; r >= 0; r--) {
  10013. + DELAY(10);
  10014. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  10015. + break;
  10016. + }
  10017. + if (r == 0) {
  10018. + device_printf(sc->sc_dev, "readramaddr -- "
  10019. + "result[%d](addr %d) still valid\n", resi, addr);
  10020. + r = -1;
  10021. + } else {
  10022. + r = 0;
  10023. + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
  10024. + }
  10025. +
  10026. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  10027. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  10028. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  10029. +
  10030. + return (r);
  10031. +}
  10032. +
  10033. +/*
  10034. + * Initialize the descriptor rings.
  10035. + */
  10036. +static void
  10037. +hifn_init_dma(struct hifn_softc *sc)
  10038. +{
  10039. + struct hifn_dma *dma = sc->sc_dma;
  10040. + int i;
  10041. +
  10042. + DPRINTF("%s()\n", __FUNCTION__);
  10043. +
  10044. + hifn_set_retry(sc);
  10045. +
  10046. + /* initialize static pointer values */
  10047. + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
  10048. + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
  10049. + offsetof(struct hifn_dma, command_bufs[i][0]));
  10050. + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
  10051. + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
  10052. + offsetof(struct hifn_dma, result_bufs[i][0]));
  10053. +
  10054. + dma->cmdr[HIFN_D_CMD_RSIZE].p =
  10055. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
  10056. + dma->srcr[HIFN_D_SRC_RSIZE].p =
  10057. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
  10058. + dma->dstr[HIFN_D_DST_RSIZE].p =
  10059. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
  10060. + dma->resr[HIFN_D_RES_RSIZE].p =
  10061. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
  10062. +
  10063. + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
  10064. + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
  10065. + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
  10066. +}
  10067. +
  10068. +/*
  10069. + * Writes out the raw command buffer space. Returns the
  10070. + * command buffer size.
  10071. + */
  10072. +static u_int
  10073. +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
  10074. +{
  10075. + struct hifn_softc *sc = NULL;
  10076. + u_int8_t *buf_pos;
  10077. + hifn_base_command_t *base_cmd;
  10078. + hifn_mac_command_t *mac_cmd;
  10079. + hifn_crypt_command_t *cry_cmd;
  10080. + int using_mac, using_crypt, len, ivlen;
  10081. + u_int32_t dlen, slen;
  10082. +
  10083. + DPRINTF("%s()\n", __FUNCTION__);
  10084. +
  10085. + buf_pos = buf;
  10086. + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
  10087. + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
  10088. +
  10089. + base_cmd = (hifn_base_command_t *)buf_pos;
  10090. + base_cmd->masks = htole16(cmd->base_masks);
  10091. + slen = cmd->src_mapsize;
  10092. + if (cmd->sloplen)
  10093. + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
  10094. + else
  10095. + dlen = cmd->dst_mapsize;
  10096. + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
  10097. + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
  10098. + dlen >>= 16;
  10099. + slen >>= 16;
  10100. + base_cmd->session_num = htole16(
  10101. + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
  10102. + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
  10103. + buf_pos += sizeof(hifn_base_command_t);
  10104. +
  10105. + if (using_mac) {
  10106. + mac_cmd = (hifn_mac_command_t *)buf_pos;
  10107. + dlen = cmd->maccrd->crd_len;
  10108. + mac_cmd->source_count = htole16(dlen & 0xffff);
  10109. + dlen >>= 16;
  10110. + mac_cmd->masks = htole16(cmd->mac_masks |
  10111. + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
  10112. + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
  10113. + mac_cmd->reserved = 0;
  10114. + buf_pos += sizeof(hifn_mac_command_t);
  10115. + }
  10116. +
  10117. + if (using_crypt) {
  10118. + cry_cmd = (hifn_crypt_command_t *)buf_pos;
  10119. + dlen = cmd->enccrd->crd_len;
  10120. + cry_cmd->source_count = htole16(dlen & 0xffff);
  10121. + dlen >>= 16;
  10122. + cry_cmd->masks = htole16(cmd->cry_masks |
  10123. + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
  10124. + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
  10125. + cry_cmd->reserved = 0;
  10126. + buf_pos += sizeof(hifn_crypt_command_t);
  10127. + }
  10128. +
  10129. + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
  10130. + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
  10131. + buf_pos += HIFN_MAC_KEY_LENGTH;
  10132. + }
  10133. +
  10134. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
  10135. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  10136. + case HIFN_CRYPT_CMD_ALG_3DES:
  10137. + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
  10138. + buf_pos += HIFN_3DES_KEY_LENGTH;
  10139. + break;
  10140. + case HIFN_CRYPT_CMD_ALG_DES:
  10141. + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
  10142. + buf_pos += HIFN_DES_KEY_LENGTH;
  10143. + break;
  10144. + case HIFN_CRYPT_CMD_ALG_RC4:
  10145. + len = 256;
  10146. + do {
  10147. + int clen;
  10148. +
  10149. + clen = MIN(cmd->cklen, len);
  10150. + bcopy(cmd->ck, buf_pos, clen);
  10151. + len -= clen;
  10152. + buf_pos += clen;
  10153. + } while (len > 0);
  10154. + bzero(buf_pos, 4);
  10155. + buf_pos += 4;
  10156. + break;
  10157. + case HIFN_CRYPT_CMD_ALG_AES:
  10158. + /*
  10159. + * AES keys are variable 128, 192 and
  10160. + * 256 bits (16, 24 and 32 bytes).
  10161. + */
  10162. + bcopy(cmd->ck, buf_pos, cmd->cklen);
  10163. + buf_pos += cmd->cklen;
  10164. + break;
  10165. + }
  10166. + }
  10167. +
  10168. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
  10169. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  10170. + case HIFN_CRYPT_CMD_ALG_AES:
  10171. + ivlen = HIFN_AES_IV_LENGTH;
  10172. + break;
  10173. + default:
  10174. + ivlen = HIFN_IV_LENGTH;
  10175. + break;
  10176. + }
  10177. + bcopy(cmd->iv, buf_pos, ivlen);
  10178. + buf_pos += ivlen;
  10179. + }
  10180. +
  10181. + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
  10182. + bzero(buf_pos, 8);
  10183. + buf_pos += 8;
  10184. + }
  10185. +
  10186. + return (buf_pos - buf);
  10187. +}
  10188. +
  10189. +static int
  10190. +hifn_dmamap_aligned(struct hifn_operand *op)
  10191. +{
  10192. + struct hifn_softc *sc = NULL;
  10193. + int i;
  10194. +
  10195. + DPRINTF("%s()\n", __FUNCTION__);
  10196. +
  10197. + for (i = 0; i < op->nsegs; i++) {
  10198. + if (op->segs[i].ds_addr & 3)
  10199. + return (0);
  10200. + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
  10201. + return (0);
  10202. + }
  10203. + return (1);
  10204. +}
  10205. +
  10206. +static __inline int
  10207. +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
  10208. +{
  10209. + struct hifn_dma *dma = sc->sc_dma;
  10210. +
  10211. + if (++idx == HIFN_D_DST_RSIZE) {
  10212. + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
  10213. + HIFN_D_MASKDONEIRQ);
  10214. + HIFN_DSTR_SYNC(sc, idx,
  10215. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10216. + idx = 0;
  10217. + }
  10218. + return (idx);
  10219. +}
  10220. +
  10221. +static int
  10222. +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
  10223. +{
  10224. + struct hifn_dma *dma = sc->sc_dma;
  10225. + struct hifn_operand *dst = &cmd->dst;
  10226. + u_int32_t p, l;
  10227. + int idx, used = 0, i;
  10228. +
  10229. + DPRINTF("%s()\n", __FUNCTION__);
  10230. +
  10231. + idx = dma->dsti;
  10232. + for (i = 0; i < dst->nsegs - 1; i++) {
  10233. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  10234. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
  10235. + wmb();
  10236. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  10237. + HIFN_DSTR_SYNC(sc, idx,
  10238. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10239. + used++;
  10240. +
  10241. + idx = hifn_dmamap_dstwrap(sc, idx);
  10242. + }
  10243. +
  10244. + if (cmd->sloplen == 0) {
  10245. + p = dst->segs[i].ds_addr;
  10246. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  10247. + dst->segs[i].ds_len;
  10248. + } else {
  10249. + p = sc->sc_dma_physaddr +
  10250. + offsetof(struct hifn_dma, slop[cmd->slopidx]);
  10251. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  10252. + sizeof(u_int32_t);
  10253. +
  10254. + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
  10255. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  10256. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
  10257. + (dst->segs[i].ds_len - cmd->sloplen));
  10258. + wmb();
  10259. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  10260. + HIFN_DSTR_SYNC(sc, idx,
  10261. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10262. + used++;
  10263. +
  10264. + idx = hifn_dmamap_dstwrap(sc, idx);
  10265. + }
  10266. + }
  10267. + dma->dstr[idx].p = htole32(p);
  10268. + dma->dstr[idx].l = htole32(l);
  10269. + wmb();
  10270. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  10271. + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10272. + used++;
  10273. +
  10274. + idx = hifn_dmamap_dstwrap(sc, idx);
  10275. +
  10276. + dma->dsti = idx;
  10277. + dma->dstu += used;
  10278. + return (idx);
  10279. +}
  10280. +
  10281. +static __inline int
  10282. +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
  10283. +{
  10284. + struct hifn_dma *dma = sc->sc_dma;
  10285. +
  10286. + if (++idx == HIFN_D_SRC_RSIZE) {
  10287. + dma->srcr[idx].l = htole32(HIFN_D_VALID |
  10288. + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
  10289. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  10290. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10291. + idx = 0;
  10292. + }
  10293. + return (idx);
  10294. +}
  10295. +
  10296. +static int
  10297. +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
  10298. +{
  10299. + struct hifn_dma *dma = sc->sc_dma;
  10300. + struct hifn_operand *src = &cmd->src;
  10301. + int idx, i;
  10302. + u_int32_t last = 0;
  10303. +
  10304. + DPRINTF("%s()\n", __FUNCTION__);
  10305. +
  10306. + idx = dma->srci;
  10307. + for (i = 0; i < src->nsegs; i++) {
  10308. + if (i == src->nsegs - 1)
  10309. + last = HIFN_D_LAST;
  10310. +
  10311. + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
  10312. + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
  10313. + HIFN_D_MASKDONEIRQ | last);
  10314. + wmb();
  10315. + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
  10316. + HIFN_SRCR_SYNC(sc, idx,
  10317. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10318. +
  10319. + idx = hifn_dmamap_srcwrap(sc, idx);
  10320. + }
  10321. + dma->srci = idx;
  10322. + dma->srcu += src->nsegs;
  10323. + return (idx);
  10324. +}
  10325. +
  10326. +
  10327. +static int
  10328. +hifn_crypto(
  10329. + struct hifn_softc *sc,
  10330. + struct hifn_command *cmd,
  10331. + struct cryptop *crp,
  10332. + int hint)
  10333. +{
  10334. + struct hifn_dma *dma = sc->sc_dma;
  10335. + u_int32_t cmdlen, csr;
  10336. + int cmdi, resi, err = 0;
  10337. + unsigned long l_flags;
  10338. +
  10339. + DPRINTF("%s()\n", __FUNCTION__);
  10340. +
  10341. + /*
  10342. + * need 1 cmd, and 1 res
  10343. + *
  10344. + * NB: check this first since it's easy.
  10345. + */
  10346. + HIFN_LOCK(sc);
  10347. + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
  10348. + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
  10349. +#ifdef HIFN_DEBUG
  10350. + if (hifn_debug) {
  10351. + device_printf(sc->sc_dev,
  10352. + "cmd/result exhaustion, cmdu %u resu %u\n",
  10353. + dma->cmdu, dma->resu);
  10354. + }
  10355. +#endif
  10356. + hifnstats.hst_nomem_cr++;
  10357. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  10358. + HIFN_UNLOCK(sc);
  10359. + return (ERESTART);
  10360. + }
  10361. +
  10362. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10363. + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
  10364. + hifnstats.hst_nomem_load++;
  10365. + err = ENOMEM;
  10366. + goto err_srcmap1;
  10367. + }
  10368. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  10369. + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
  10370. + hifnstats.hst_nomem_load++;
  10371. + err = ENOMEM;
  10372. + goto err_srcmap1;
  10373. + }
  10374. + } else {
  10375. + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
  10376. + hifnstats.hst_nomem_load++;
  10377. + err = ENOMEM;
  10378. + goto err_srcmap1;
  10379. + }
  10380. + }
  10381. +
  10382. + if (hifn_dmamap_aligned(&cmd->src)) {
  10383. + cmd->sloplen = cmd->src_mapsize & 3;
  10384. + cmd->dst = cmd->src;
  10385. + } else {
  10386. + if (crp->crp_flags & CRYPTO_F_IOV) {
  10387. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  10388. + err = EINVAL;
  10389. + goto err_srcmap;
  10390. + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10391. +#ifdef NOTYET
  10392. + int totlen, len;
  10393. + struct mbuf *m, *m0, *mlast;
  10394. +
  10395. + KASSERT(cmd->dst_m == cmd->src_m,
  10396. + ("hifn_crypto: dst_m initialized improperly"));
  10397. + hifnstats.hst_unaligned++;
  10398. + /*
  10399. + * Source is not aligned on a longword boundary.
  10400. + * Copy the data to insure alignment. If we fail
  10401. + * to allocate mbufs or clusters while doing this
  10402. + * we return ERESTART so the operation is requeued
  10403. + * at the crypto later, but only if there are
  10404. + * ops already posted to the hardware; otherwise we
  10405. + * have no guarantee that we'll be re-entered.
  10406. + */
  10407. + totlen = cmd->src_mapsize;
  10408. + if (cmd->src_m->m_flags & M_PKTHDR) {
  10409. + len = MHLEN;
  10410. + MGETHDR(m0, M_DONTWAIT, MT_DATA);
  10411. + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
  10412. + m_free(m0);
  10413. + m0 = NULL;
  10414. + }
  10415. + } else {
  10416. + len = MLEN;
  10417. + MGET(m0, M_DONTWAIT, MT_DATA);
  10418. + }
  10419. + if (m0 == NULL) {
  10420. + hifnstats.hst_nomem_mbuf++;
  10421. + err = dma->cmdu ? ERESTART : ENOMEM;
  10422. + goto err_srcmap;
  10423. + }
  10424. + if (totlen >= MINCLSIZE) {
  10425. + MCLGET(m0, M_DONTWAIT);
  10426. + if ((m0->m_flags & M_EXT) == 0) {
  10427. + hifnstats.hst_nomem_mcl++;
  10428. + err = dma->cmdu ? ERESTART : ENOMEM;
  10429. + m_freem(m0);
  10430. + goto err_srcmap;
  10431. + }
  10432. + len = MCLBYTES;
  10433. + }
  10434. + totlen -= len;
  10435. + m0->m_pkthdr.len = m0->m_len = len;
  10436. + mlast = m0;
  10437. +
  10438. + while (totlen > 0) {
  10439. + MGET(m, M_DONTWAIT, MT_DATA);
  10440. + if (m == NULL) {
  10441. + hifnstats.hst_nomem_mbuf++;
  10442. + err = dma->cmdu ? ERESTART : ENOMEM;
  10443. + m_freem(m0);
  10444. + goto err_srcmap;
  10445. + }
  10446. + len = MLEN;
  10447. + if (totlen >= MINCLSIZE) {
  10448. + MCLGET(m, M_DONTWAIT);
  10449. + if ((m->m_flags & M_EXT) == 0) {
  10450. + hifnstats.hst_nomem_mcl++;
  10451. + err = dma->cmdu ? ERESTART : ENOMEM;
  10452. + mlast->m_next = m;
  10453. + m_freem(m0);
  10454. + goto err_srcmap;
  10455. + }
  10456. + len = MCLBYTES;
  10457. + }
  10458. +
  10459. + m->m_len = len;
  10460. + m0->m_pkthdr.len += len;
  10461. + totlen -= len;
  10462. +
  10463. + mlast->m_next = m;
  10464. + mlast = m;
  10465. + }
  10466. + cmd->dst_m = m0;
  10467. +#else
  10468. + device_printf(sc->sc_dev,
  10469. + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
  10470. + __FILE__, __LINE__);
  10471. + err = EINVAL;
  10472. + goto err_srcmap;
  10473. +#endif
  10474. + } else {
  10475. + device_printf(sc->sc_dev,
  10476. + "%s,%d: unaligned contig buffers not implemented\n",
  10477. + __FILE__, __LINE__);
  10478. + err = EINVAL;
  10479. + goto err_srcmap;
  10480. + }
  10481. + }
  10482. +
  10483. + if (cmd->dst_map == NULL) {
  10484. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10485. + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
  10486. + hifnstats.hst_nomem_map++;
  10487. + err = ENOMEM;
  10488. + goto err_dstmap1;
  10489. + }
  10490. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  10491. + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
  10492. + hifnstats.hst_nomem_load++;
  10493. + err = ENOMEM;
  10494. + goto err_dstmap1;
  10495. + }
  10496. + } else {
  10497. + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
  10498. + hifnstats.hst_nomem_load++;
  10499. + err = ENOMEM;
  10500. + goto err_dstmap1;
  10501. + }
  10502. + }
  10503. + }
  10504. +
  10505. +#ifdef HIFN_DEBUG
  10506. + if (hifn_debug) {
  10507. + device_printf(sc->sc_dev,
  10508. + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
  10509. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  10510. + READ_REG_1(sc, HIFN_1_DMA_IER),
  10511. + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
  10512. + cmd->src_nsegs, cmd->dst_nsegs);
  10513. + }
  10514. +#endif
  10515. +
  10516. +#if 0
  10517. + if (cmd->src_map == cmd->dst_map) {
  10518. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  10519. + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
  10520. + } else {
  10521. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  10522. + BUS_DMASYNC_PREWRITE);
  10523. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  10524. + BUS_DMASYNC_PREREAD);
  10525. + }
  10526. +#endif
  10527. +
  10528. + /*
  10529. + * need N src, and N dst
  10530. + */
  10531. + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
  10532. + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
  10533. +#ifdef HIFN_DEBUG
  10534. + if (hifn_debug) {
  10535. + device_printf(sc->sc_dev,
  10536. + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
  10537. + dma->srcu, cmd->src_nsegs,
  10538. + dma->dstu, cmd->dst_nsegs);
  10539. + }
  10540. +#endif
  10541. + hifnstats.hst_nomem_sd++;
  10542. + err = ERESTART;
  10543. + goto err_dstmap;
  10544. + }
  10545. +
  10546. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  10547. + dma->cmdi = 0;
  10548. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10549. + wmb();
  10550. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  10551. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  10552. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10553. + }
  10554. + cmdi = dma->cmdi++;
  10555. + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
  10556. + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
  10557. +
  10558. + /* .p for command/result already set */
  10559. + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
  10560. + HIFN_D_MASKDONEIRQ);
  10561. + wmb();
  10562. + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
  10563. + HIFN_CMDR_SYNC(sc, cmdi,
  10564. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10565. + dma->cmdu++;
  10566. +
  10567. + /*
  10568. + * We don't worry about missing an interrupt (which a "command wait"
  10569. + * interrupt salvages us from), unless there is more than one command
  10570. + * in the queue.
  10571. + */
  10572. + if (dma->cmdu > 1) {
  10573. + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
  10574. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  10575. + }
  10576. +
  10577. + hifnstats.hst_ipackets++;
  10578. + hifnstats.hst_ibytes += cmd->src_mapsize;
  10579. +
  10580. + hifn_dmamap_load_src(sc, cmd);
  10581. +
  10582. + /*
  10583. + * Unlike other descriptors, we don't mask done interrupt from
  10584. + * result descriptor.
  10585. + */
  10586. +#ifdef HIFN_DEBUG
  10587. + if (hifn_debug)
  10588. + device_printf(sc->sc_dev, "load res\n");
  10589. +#endif
  10590. + if (dma->resi == HIFN_D_RES_RSIZE) {
  10591. + dma->resi = 0;
  10592. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10593. + wmb();
  10594. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  10595. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  10596. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10597. + }
  10598. + resi = dma->resi++;
  10599. + KASSERT(dma->hifn_commands[resi] == NULL,
  10600. + ("hifn_crypto: command slot %u busy", resi));
  10601. + dma->hifn_commands[resi] = cmd;
  10602. + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
  10603. + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
  10604. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
  10605. + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
  10606. + wmb();
  10607. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  10608. + sc->sc_curbatch++;
  10609. + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
  10610. + hifnstats.hst_maxbatch = sc->sc_curbatch;
  10611. + hifnstats.hst_totbatch++;
  10612. + } else {
  10613. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
  10614. + wmb();
  10615. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  10616. + sc->sc_curbatch = 0;
  10617. + }
  10618. + HIFN_RESR_SYNC(sc, resi,
  10619. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10620. + dma->resu++;
  10621. +
  10622. + if (cmd->sloplen)
  10623. + cmd->slopidx = resi;
  10624. +
  10625. + hifn_dmamap_load_dst(sc, cmd);
  10626. +
  10627. + csr = 0;
  10628. + if (sc->sc_c_busy == 0) {
  10629. + csr |= HIFN_DMACSR_C_CTRL_ENA;
  10630. + sc->sc_c_busy = 1;
  10631. + }
  10632. + if (sc->sc_s_busy == 0) {
  10633. + csr |= HIFN_DMACSR_S_CTRL_ENA;
  10634. + sc->sc_s_busy = 1;
  10635. + }
  10636. + if (sc->sc_r_busy == 0) {
  10637. + csr |= HIFN_DMACSR_R_CTRL_ENA;
  10638. + sc->sc_r_busy = 1;
  10639. + }
  10640. + if (sc->sc_d_busy == 0) {
  10641. + csr |= HIFN_DMACSR_D_CTRL_ENA;
  10642. + sc->sc_d_busy = 1;
  10643. + }
  10644. + if (csr)
  10645. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
  10646. +
  10647. +#ifdef HIFN_DEBUG
  10648. + if (hifn_debug) {
  10649. + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
  10650. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  10651. + READ_REG_1(sc, HIFN_1_DMA_IER));
  10652. + }
  10653. +#endif
  10654. +
  10655. + sc->sc_active = 5;
  10656. + HIFN_UNLOCK(sc);
  10657. + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
  10658. + return (err); /* success */
  10659. +
  10660. +err_dstmap:
  10661. + if (cmd->src_map != cmd->dst_map)
  10662. + pci_unmap_buf(sc, &cmd->dst);
  10663. +err_dstmap1:
  10664. +err_srcmap:
  10665. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10666. + if (cmd->src_skb != cmd->dst_skb)
  10667. +#ifdef NOTYET
  10668. + m_freem(cmd->dst_m);
  10669. +#else
  10670. + device_printf(sc->sc_dev,
  10671. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  10672. + __FILE__, __LINE__);
  10673. +#endif
  10674. + }
  10675. + pci_unmap_buf(sc, &cmd->src);
  10676. +err_srcmap1:
  10677. + HIFN_UNLOCK(sc);
  10678. + return (err);
  10679. +}
  10680. +
  10681. +static void
  10682. +hifn_tick(unsigned long arg)
  10683. +{
  10684. + struct hifn_softc *sc;
  10685. + unsigned long l_flags;
  10686. +
  10687. + if (arg >= HIFN_MAX_CHIPS)
  10688. + return;
  10689. + sc = hifn_chip_idx[arg];
  10690. + if (!sc)
  10691. + return;
  10692. +
  10693. + HIFN_LOCK(sc);
  10694. + if (sc->sc_active == 0) {
  10695. + struct hifn_dma *dma = sc->sc_dma;
  10696. + u_int32_t r = 0;
  10697. +
  10698. + if (dma->cmdu == 0 && sc->sc_c_busy) {
  10699. + sc->sc_c_busy = 0;
  10700. + r |= HIFN_DMACSR_C_CTRL_DIS;
  10701. + }
  10702. + if (dma->srcu == 0 && sc->sc_s_busy) {
  10703. + sc->sc_s_busy = 0;
  10704. + r |= HIFN_DMACSR_S_CTRL_DIS;
  10705. + }
  10706. + if (dma->dstu == 0 && sc->sc_d_busy) {
  10707. + sc->sc_d_busy = 0;
  10708. + r |= HIFN_DMACSR_D_CTRL_DIS;
  10709. + }
  10710. + if (dma->resu == 0 && sc->sc_r_busy) {
  10711. + sc->sc_r_busy = 0;
  10712. + r |= HIFN_DMACSR_R_CTRL_DIS;
  10713. + }
  10714. + if (r)
  10715. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
  10716. + } else
  10717. + sc->sc_active--;
  10718. + HIFN_UNLOCK(sc);
  10719. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  10720. +}
  10721. +
  10722. +static irqreturn_t
  10723. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  10724. +hifn_intr(int irq, void *arg)
  10725. +#else
  10726. +hifn_intr(int irq, void *arg, struct pt_regs *regs)
  10727. +#endif
  10728. +{
  10729. + struct hifn_softc *sc = arg;
  10730. + struct hifn_dma *dma;
  10731. + u_int32_t dmacsr, restart;
  10732. + int i, u;
  10733. + unsigned long l_flags;
  10734. +
  10735. + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
  10736. +
  10737. + /* Nothing in the DMA unit interrupted */
  10738. + if ((dmacsr & sc->sc_dmaier) == 0)
  10739. + return IRQ_NONE;
  10740. +
  10741. + HIFN_LOCK(sc);
  10742. +
  10743. + dma = sc->sc_dma;
  10744. +
  10745. +#ifdef HIFN_DEBUG
  10746. + if (hifn_debug) {
  10747. + device_printf(sc->sc_dev,
  10748. + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
  10749. + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
  10750. + dma->cmdi, dma->srci, dma->dsti, dma->resi,
  10751. + dma->cmdk, dma->srck, dma->dstk, dma->resk,
  10752. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  10753. + }
  10754. +#endif
  10755. +
  10756. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
  10757. +
  10758. + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
  10759. + (dmacsr & HIFN_DMACSR_PUBDONE))
  10760. + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
  10761. + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
  10762. +
  10763. + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
  10764. + if (restart)
  10765. + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
  10766. +
  10767. + if (sc->sc_flags & HIFN_IS_7811) {
  10768. + if (dmacsr & HIFN_DMACSR_ILLR)
  10769. + device_printf(sc->sc_dev, "illegal read\n");
  10770. + if (dmacsr & HIFN_DMACSR_ILLW)
  10771. + device_printf(sc->sc_dev, "illegal write\n");
  10772. + }
  10773. +
  10774. + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
  10775. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
  10776. + if (restart) {
  10777. + device_printf(sc->sc_dev, "abort, resetting.\n");
  10778. + hifnstats.hst_abort++;
  10779. + hifn_abort(sc);
  10780. + HIFN_UNLOCK(sc);
  10781. + return IRQ_HANDLED;
  10782. + }
  10783. +
  10784. + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
  10785. + /*
  10786. + * If no slots to process and we receive a "waiting on
  10787. + * command" interrupt, we disable the "waiting on command"
  10788. + * (by clearing it).
  10789. + */
  10790. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  10791. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  10792. + }
  10793. +
  10794. + /* clear the rings */
  10795. + i = dma->resk; u = dma->resu;
  10796. + while (u != 0) {
  10797. + HIFN_RESR_SYNC(sc, i,
  10798. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  10799. + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
  10800. + HIFN_RESR_SYNC(sc, i,
  10801. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10802. + break;
  10803. + }
  10804. +
  10805. + if (i != HIFN_D_RES_RSIZE) {
  10806. + struct hifn_command *cmd;
  10807. + u_int8_t *macbuf = NULL;
  10808. +
  10809. + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
  10810. + cmd = dma->hifn_commands[i];
  10811. + KASSERT(cmd != NULL,
  10812. + ("hifn_intr: null command slot %u", i));
  10813. + dma->hifn_commands[i] = NULL;
  10814. +
  10815. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  10816. + macbuf = dma->result_bufs[i];
  10817. + macbuf += 12;
  10818. + }
  10819. +
  10820. + hifn_callback(sc, cmd, macbuf);
  10821. + hifnstats.hst_opackets++;
  10822. + u--;
  10823. + }
  10824. +
  10825. + if (++i == (HIFN_D_RES_RSIZE + 1))
  10826. + i = 0;
  10827. + }
  10828. + dma->resk = i; dma->resu = u;
  10829. +
  10830. + i = dma->srck; u = dma->srcu;
  10831. + while (u != 0) {
  10832. + if (i == HIFN_D_SRC_RSIZE)
  10833. + i = 0;
  10834. + HIFN_SRCR_SYNC(sc, i,
  10835. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  10836. + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
  10837. + HIFN_SRCR_SYNC(sc, i,
  10838. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10839. + break;
  10840. + }
  10841. + i++, u--;
  10842. + }
  10843. + dma->srck = i; dma->srcu = u;
  10844. +
  10845. + i = dma->cmdk; u = dma->cmdu;
  10846. + while (u != 0) {
  10847. + HIFN_CMDR_SYNC(sc, i,
  10848. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  10849. + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
  10850. + HIFN_CMDR_SYNC(sc, i,
  10851. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10852. + break;
  10853. + }
  10854. + if (i != HIFN_D_CMD_RSIZE) {
  10855. + u--;
  10856. + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
  10857. + }
  10858. + if (++i == (HIFN_D_CMD_RSIZE + 1))
  10859. + i = 0;
  10860. + }
  10861. + dma->cmdk = i; dma->cmdu = u;
  10862. +
  10863. + HIFN_UNLOCK(sc);
  10864. +
  10865. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  10866. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  10867. +#ifdef HIFN_DEBUG
  10868. + if (hifn_debug)
  10869. + device_printf(sc->sc_dev,
  10870. + "wakeup crypto (%x) u %d/%d/%d/%d\n",
  10871. + sc->sc_needwakeup,
  10872. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  10873. +#endif
  10874. + sc->sc_needwakeup &= ~wakeup;
  10875. + crypto_unblock(sc->sc_cid, wakeup);
  10876. + }
  10877. +
  10878. + return IRQ_HANDLED;
  10879. +}
  10880. +
  10881. +/*
  10882. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  10883. + * contains our registration id, and should contain an encoded session
  10884. + * id on successful allocation.
  10885. + */
  10886. +static int
  10887. +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  10888. +{
  10889. + struct hifn_softc *sc = device_get_softc(dev);
  10890. + struct cryptoini *c;
  10891. + int mac = 0, cry = 0, sesn;
  10892. + struct hifn_session *ses = NULL;
  10893. + unsigned long l_flags;
  10894. +
  10895. + DPRINTF("%s()\n", __FUNCTION__);
  10896. +
  10897. + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
  10898. + if (sidp == NULL || cri == NULL || sc == NULL) {
  10899. + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
  10900. + return (EINVAL);
  10901. + }
  10902. +
  10903. + HIFN_LOCK(sc);
  10904. + if (sc->sc_sessions == NULL) {
  10905. + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
  10906. + SLAB_ATOMIC);
  10907. + if (ses == NULL) {
  10908. + HIFN_UNLOCK(sc);
  10909. + return (ENOMEM);
  10910. + }
  10911. + sesn = 0;
  10912. + sc->sc_nsessions = 1;
  10913. + } else {
  10914. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  10915. + if (!sc->sc_sessions[sesn].hs_used) {
  10916. + ses = &sc->sc_sessions[sesn];
  10917. + break;
  10918. + }
  10919. + }
  10920. +
  10921. + if (ses == NULL) {
  10922. + sesn = sc->sc_nsessions;
  10923. + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
  10924. + SLAB_ATOMIC);
  10925. + if (ses == NULL) {
  10926. + HIFN_UNLOCK(sc);
  10927. + return (ENOMEM);
  10928. + }
  10929. + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
  10930. + bzero(sc->sc_sessions, sesn * sizeof(*ses));
  10931. + kfree(sc->sc_sessions);
  10932. + sc->sc_sessions = ses;
  10933. + ses = &sc->sc_sessions[sesn];
  10934. + sc->sc_nsessions++;
  10935. + }
  10936. + }
  10937. + HIFN_UNLOCK(sc);
  10938. +
  10939. + bzero(ses, sizeof(*ses));
  10940. + ses->hs_used = 1;
  10941. +
  10942. + for (c = cri; c != NULL; c = c->cri_next) {
  10943. + switch (c->cri_alg) {
  10944. + case CRYPTO_MD5:
  10945. + case CRYPTO_SHA1:
  10946. + case CRYPTO_MD5_HMAC:
  10947. + case CRYPTO_SHA1_HMAC:
  10948. + if (mac) {
  10949. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  10950. + return (EINVAL);
  10951. + }
  10952. + mac = 1;
  10953. + ses->hs_mlen = c->cri_mlen;
  10954. + if (ses->hs_mlen == 0) {
  10955. + switch (c->cri_alg) {
  10956. + case CRYPTO_MD5:
  10957. + case CRYPTO_MD5_HMAC:
  10958. + ses->hs_mlen = 16;
  10959. + break;
  10960. + case CRYPTO_SHA1:
  10961. + case CRYPTO_SHA1_HMAC:
  10962. + ses->hs_mlen = 20;
  10963. + break;
  10964. + }
  10965. + }
  10966. + break;
  10967. + case CRYPTO_DES_CBC:
  10968. + case CRYPTO_3DES_CBC:
  10969. + case CRYPTO_AES_CBC:
  10970. + /* XXX this may read fewer, does it matter? */
  10971. + read_random(ses->hs_iv,
  10972. + c->cri_alg == CRYPTO_AES_CBC ?
  10973. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  10974. + /*FALLTHROUGH*/
  10975. + case CRYPTO_ARC4:
  10976. + if (cry) {
  10977. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  10978. + return (EINVAL);
  10979. + }
  10980. + cry = 1;
  10981. + break;
  10982. + default:
  10983. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  10984. + return (EINVAL);
  10985. + }
  10986. + }
  10987. + if (mac == 0 && cry == 0) {
  10988. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  10989. + return (EINVAL);
  10990. + }
  10991. +
  10992. + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
  10993. +
  10994. + return (0);
  10995. +}
  10996. +
  10997. +/*
  10998. + * Deallocate a session.
  10999. + * XXX this routine should run a zero'd mac/encrypt key into context ram.
  11000. + * XXX to blow away any keys already stored there.
  11001. + */
  11002. +static int
  11003. +hifn_freesession(device_t dev, u_int64_t tid)
  11004. +{
  11005. + struct hifn_softc *sc = device_get_softc(dev);
  11006. + int session, error;
  11007. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  11008. + unsigned long l_flags;
  11009. +
  11010. + DPRINTF("%s()\n", __FUNCTION__);
  11011. +
  11012. + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
  11013. + if (sc == NULL) {
  11014. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11015. + return (EINVAL);
  11016. + }
  11017. +
  11018. + HIFN_LOCK(sc);
  11019. + session = HIFN_SESSION(sid);
  11020. + if (session < sc->sc_nsessions) {
  11021. + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
  11022. + error = 0;
  11023. + } else {
  11024. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11025. + error = EINVAL;
  11026. + }
  11027. + HIFN_UNLOCK(sc);
  11028. +
  11029. + return (error);
  11030. +}
  11031. +
  11032. +static int
  11033. +hifn_process(device_t dev, struct cryptop *crp, int hint)
  11034. +{
  11035. + struct hifn_softc *sc = device_get_softc(dev);
  11036. + struct hifn_command *cmd = NULL;
  11037. + int session, err, ivlen;
  11038. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  11039. +
  11040. + DPRINTF("%s()\n", __FUNCTION__);
  11041. +
  11042. + if (crp == NULL || crp->crp_callback == NULL) {
  11043. + hifnstats.hst_invalid++;
  11044. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11045. + return (EINVAL);
  11046. + }
  11047. + session = HIFN_SESSION(crp->crp_sid);
  11048. +
  11049. + if (sc == NULL || session >= sc->sc_nsessions) {
  11050. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11051. + err = EINVAL;
  11052. + goto errout;
  11053. + }
  11054. +
  11055. + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
  11056. + if (cmd == NULL) {
  11057. + hifnstats.hst_nomem++;
  11058. + err = ENOMEM;
  11059. + goto errout;
  11060. + }
  11061. + memset(cmd, 0, sizeof(*cmd));
  11062. +
  11063. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  11064. + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
  11065. + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
  11066. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  11067. + cmd->src_io = (struct uio *)crp->crp_buf;
  11068. + cmd->dst_io = (struct uio *)crp->crp_buf;
  11069. + } else {
  11070. + cmd->src_buf = crp->crp_buf;
  11071. + cmd->dst_buf = crp->crp_buf;
  11072. + }
  11073. +
  11074. + crd1 = crp->crp_desc;
  11075. + if (crd1 == NULL) {
  11076. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11077. + err = EINVAL;
  11078. + goto errout;
  11079. + }
  11080. + crd2 = crd1->crd_next;
  11081. +
  11082. + if (crd2 == NULL) {
  11083. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  11084. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  11085. + crd1->crd_alg == CRYPTO_SHA1 ||
  11086. + crd1->crd_alg == CRYPTO_MD5) {
  11087. + maccrd = crd1;
  11088. + enccrd = NULL;
  11089. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  11090. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  11091. + crd1->crd_alg == CRYPTO_AES_CBC ||
  11092. + crd1->crd_alg == CRYPTO_ARC4) {
  11093. + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
  11094. + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
  11095. + maccrd = NULL;
  11096. + enccrd = crd1;
  11097. + } else {
  11098. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11099. + err = EINVAL;
  11100. + goto errout;
  11101. + }
  11102. + } else {
  11103. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  11104. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  11105. + crd1->crd_alg == CRYPTO_MD5 ||
  11106. + crd1->crd_alg == CRYPTO_SHA1) &&
  11107. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  11108. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  11109. + crd2->crd_alg == CRYPTO_AES_CBC ||
  11110. + crd2->crd_alg == CRYPTO_ARC4) &&
  11111. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  11112. + cmd->base_masks = HIFN_BASE_CMD_DECODE;
  11113. + maccrd = crd1;
  11114. + enccrd = crd2;
  11115. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  11116. + crd1->crd_alg == CRYPTO_ARC4 ||
  11117. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  11118. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  11119. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  11120. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  11121. + crd2->crd_alg == CRYPTO_MD5 ||
  11122. + crd2->crd_alg == CRYPTO_SHA1) &&
  11123. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  11124. + enccrd = crd1;
  11125. + maccrd = crd2;
  11126. + } else {
  11127. + /*
  11128. + * We cannot order the 7751 as requested
  11129. + */
  11130. + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
  11131. + err = EINVAL;
  11132. + goto errout;
  11133. + }
  11134. + }
  11135. +
  11136. + if (enccrd) {
  11137. + cmd->enccrd = enccrd;
  11138. + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
  11139. + switch (enccrd->crd_alg) {
  11140. + case CRYPTO_ARC4:
  11141. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
  11142. + break;
  11143. + case CRYPTO_DES_CBC:
  11144. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
  11145. + HIFN_CRYPT_CMD_MODE_CBC |
  11146. + HIFN_CRYPT_CMD_NEW_IV;
  11147. + break;
  11148. + case CRYPTO_3DES_CBC:
  11149. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
  11150. + HIFN_CRYPT_CMD_MODE_CBC |
  11151. + HIFN_CRYPT_CMD_NEW_IV;
  11152. + break;
  11153. + case CRYPTO_AES_CBC:
  11154. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
  11155. + HIFN_CRYPT_CMD_MODE_CBC |
  11156. + HIFN_CRYPT_CMD_NEW_IV;
  11157. + break;
  11158. + default:
  11159. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11160. + err = EINVAL;
  11161. + goto errout;
  11162. + }
  11163. + if (enccrd->crd_alg != CRYPTO_ARC4) {
  11164. + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
  11165. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  11166. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  11167. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  11168. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  11169. + else
  11170. + bcopy(sc->sc_sessions[session].hs_iv,
  11171. + cmd->iv, ivlen);
  11172. +
  11173. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
  11174. + == 0) {
  11175. + crypto_copyback(crp->crp_flags,
  11176. + crp->crp_buf, enccrd->crd_inject,
  11177. + ivlen, cmd->iv);
  11178. + }
  11179. + } else {
  11180. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  11181. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  11182. + else {
  11183. + crypto_copydata(crp->crp_flags,
  11184. + crp->crp_buf, enccrd->crd_inject,
  11185. + ivlen, cmd->iv);
  11186. + }
  11187. + }
  11188. + }
  11189. +
  11190. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  11191. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  11192. + cmd->ck = enccrd->crd_key;
  11193. + cmd->cklen = enccrd->crd_klen >> 3;
  11194. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  11195. +
  11196. + /*
  11197. + * Need to specify the size for the AES key in the masks.
  11198. + */
  11199. + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
  11200. + HIFN_CRYPT_CMD_ALG_AES) {
  11201. + switch (cmd->cklen) {
  11202. + case 16:
  11203. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
  11204. + break;
  11205. + case 24:
  11206. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
  11207. + break;
  11208. + case 32:
  11209. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
  11210. + break;
  11211. + default:
  11212. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11213. + err = EINVAL;
  11214. + goto errout;
  11215. + }
  11216. + }
  11217. + }
  11218. +
  11219. + if (maccrd) {
  11220. + cmd->maccrd = maccrd;
  11221. + cmd->base_masks |= HIFN_BASE_CMD_MAC;
  11222. +
  11223. + switch (maccrd->crd_alg) {
  11224. + case CRYPTO_MD5:
  11225. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  11226. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  11227. + HIFN_MAC_CMD_POS_IPSEC;
  11228. + break;
  11229. + case CRYPTO_MD5_HMAC:
  11230. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  11231. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  11232. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  11233. + break;
  11234. + case CRYPTO_SHA1:
  11235. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  11236. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  11237. + HIFN_MAC_CMD_POS_IPSEC;
  11238. + break;
  11239. + case CRYPTO_SHA1_HMAC:
  11240. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  11241. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  11242. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  11243. + break;
  11244. + }
  11245. +
  11246. + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
  11247. + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  11248. + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
  11249. + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
  11250. + bzero(cmd->mac + (maccrd->crd_klen >> 3),
  11251. + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
  11252. + }
  11253. + }
  11254. +
  11255. + cmd->crp = crp;
  11256. + cmd->session_num = session;
  11257. + cmd->softc = sc;
  11258. +
  11259. + err = hifn_crypto(sc, cmd, crp, hint);
  11260. + if (!err) {
  11261. + return 0;
  11262. + } else if (err == ERESTART) {
  11263. + /*
  11264. + * There weren't enough resources to dispatch the request
  11265. + * to the part. Notify the caller so they'll requeue this
  11266. + * request and resubmit it again soon.
  11267. + */
  11268. +#ifdef HIFN_DEBUG
  11269. + if (hifn_debug)
  11270. + device_printf(sc->sc_dev, "requeue request\n");
  11271. +#endif
  11272. + kfree(cmd);
  11273. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  11274. + return (err);
  11275. + }
  11276. +
  11277. +errout:
  11278. + if (cmd != NULL)
  11279. + kfree(cmd);
  11280. + if (err == EINVAL)
  11281. + hifnstats.hst_invalid++;
  11282. + else
  11283. + hifnstats.hst_nomem++;
  11284. + crp->crp_etype = err;
  11285. + crypto_done(crp);
  11286. + return (err);
  11287. +}
  11288. +
  11289. +static void
  11290. +hifn_abort(struct hifn_softc *sc)
  11291. +{
  11292. + struct hifn_dma *dma = sc->sc_dma;
  11293. + struct hifn_command *cmd;
  11294. + struct cryptop *crp;
  11295. + int i, u;
  11296. +
  11297. + DPRINTF("%s()\n", __FUNCTION__);
  11298. +
  11299. + i = dma->resk; u = dma->resu;
  11300. + while (u != 0) {
  11301. + cmd = dma->hifn_commands[i];
  11302. + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
  11303. + dma->hifn_commands[i] = NULL;
  11304. + crp = cmd->crp;
  11305. +
  11306. + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
  11307. + /* Salvage what we can. */
  11308. + u_int8_t *macbuf;
  11309. +
  11310. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  11311. + macbuf = dma->result_bufs[i];
  11312. + macbuf += 12;
  11313. + } else
  11314. + macbuf = NULL;
  11315. + hifnstats.hst_opackets++;
  11316. + hifn_callback(sc, cmd, macbuf);
  11317. + } else {
  11318. +#if 0
  11319. + if (cmd->src_map == cmd->dst_map) {
  11320. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11321. + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  11322. + } else {
  11323. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11324. + BUS_DMASYNC_POSTWRITE);
  11325. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  11326. + BUS_DMASYNC_POSTREAD);
  11327. + }
  11328. +#endif
  11329. +
  11330. + if (cmd->src_skb != cmd->dst_skb) {
  11331. +#ifdef NOTYET
  11332. + m_freem(cmd->src_m);
  11333. + crp->crp_buf = (caddr_t)cmd->dst_m;
  11334. +#else
  11335. + device_printf(sc->sc_dev,
  11336. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  11337. + __FILE__, __LINE__);
  11338. +#endif
  11339. + }
  11340. +
  11341. + /* non-shared buffers cannot be restarted */
  11342. + if (cmd->src_map != cmd->dst_map) {
  11343. + /*
  11344. + * XXX should be EAGAIN, delayed until
  11345. + * after the reset.
  11346. + */
  11347. + crp->crp_etype = ENOMEM;
  11348. + pci_unmap_buf(sc, &cmd->dst);
  11349. + } else
  11350. + crp->crp_etype = ENOMEM;
  11351. +
  11352. + pci_unmap_buf(sc, &cmd->src);
  11353. +
  11354. + kfree(cmd);
  11355. + if (crp->crp_etype != EAGAIN)
  11356. + crypto_done(crp);
  11357. + }
  11358. +
  11359. + if (++i == HIFN_D_RES_RSIZE)
  11360. + i = 0;
  11361. + u--;
  11362. + }
  11363. + dma->resk = i; dma->resu = u;
  11364. +
  11365. + hifn_reset_board(sc, 1);
  11366. + hifn_init_dma(sc);
  11367. + hifn_init_pci_registers(sc);
  11368. +}
  11369. +
  11370. +static void
  11371. +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
  11372. +{
  11373. + struct hifn_dma *dma = sc->sc_dma;
  11374. + struct cryptop *crp = cmd->crp;
  11375. + struct cryptodesc *crd;
  11376. + int i, u, ivlen;
  11377. +
  11378. + DPRINTF("%s()\n", __FUNCTION__);
  11379. +
  11380. +#if 0
  11381. + if (cmd->src_map == cmd->dst_map) {
  11382. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11383. + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  11384. + } else {
  11385. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11386. + BUS_DMASYNC_POSTWRITE);
  11387. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  11388. + BUS_DMASYNC_POSTREAD);
  11389. + }
  11390. +#endif
  11391. +
  11392. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  11393. + if (cmd->src_skb != cmd->dst_skb) {
  11394. +#ifdef NOTYET
  11395. + crp->crp_buf = (caddr_t)cmd->dst_m;
  11396. + totlen = cmd->src_mapsize;
  11397. + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
  11398. + if (totlen < m->m_len) {
  11399. + m->m_len = totlen;
  11400. + totlen = 0;
  11401. + } else
  11402. + totlen -= m->m_len;
  11403. + }
  11404. + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
  11405. + m_freem(cmd->src_m);
  11406. +#else
  11407. + device_printf(sc->sc_dev,
  11408. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  11409. + __FILE__, __LINE__);
  11410. +#endif
  11411. + }
  11412. + }
  11413. +
  11414. + if (cmd->sloplen != 0) {
  11415. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  11416. + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
  11417. + (caddr_t)&dma->slop[cmd->slopidx]);
  11418. + }
  11419. +
  11420. + i = dma->dstk; u = dma->dstu;
  11421. + while (u != 0) {
  11422. + if (i == HIFN_D_DST_RSIZE)
  11423. + i = 0;
  11424. +#if 0
  11425. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  11426. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  11427. +#endif
  11428. + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
  11429. +#if 0
  11430. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  11431. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11432. +#endif
  11433. + break;
  11434. + }
  11435. + i++, u--;
  11436. + }
  11437. + dma->dstk = i; dma->dstu = u;
  11438. +
  11439. + hifnstats.hst_obytes += cmd->dst_mapsize;
  11440. +
  11441. + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
  11442. + HIFN_BASE_CMD_CRYPT) {
  11443. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  11444. + if (crd->crd_alg != CRYPTO_DES_CBC &&
  11445. + crd->crd_alg != CRYPTO_3DES_CBC &&
  11446. + crd->crd_alg != CRYPTO_AES_CBC)
  11447. + continue;
  11448. + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
  11449. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  11450. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  11451. + crd->crd_skip + crd->crd_len - ivlen, ivlen,
  11452. + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
  11453. + break;
  11454. + }
  11455. + }
  11456. +
  11457. + if (macbuf != NULL) {
  11458. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  11459. + int len;
  11460. +
  11461. + if (crd->crd_alg != CRYPTO_MD5 &&
  11462. + crd->crd_alg != CRYPTO_SHA1 &&
  11463. + crd->crd_alg != CRYPTO_MD5_HMAC &&
  11464. + crd->crd_alg != CRYPTO_SHA1_HMAC) {
  11465. + continue;
  11466. + }
  11467. + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
  11468. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  11469. + crd->crd_inject, len, macbuf);
  11470. + break;
  11471. + }
  11472. + }
  11473. +
  11474. + if (cmd->src_map != cmd->dst_map)
  11475. + pci_unmap_buf(sc, &cmd->dst);
  11476. + pci_unmap_buf(sc, &cmd->src);
  11477. + kfree(cmd);
  11478. + crypto_done(crp);
  11479. +}
  11480. +
  11481. +/*
  11482. + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
  11483. + * and Group 1 registers; avoid conditions that could create
  11484. + * burst writes by doing a read in between the writes.
  11485. + *
  11486. + * NB: The read we interpose is always to the same register;
  11487. + * we do this because reading from an arbitrary (e.g. last)
  11488. + * register may not always work.
  11489. + */
  11490. +static void
  11491. +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  11492. +{
  11493. + if (sc->sc_flags & HIFN_IS_7811) {
  11494. + if (sc->sc_bar0_lastreg == reg - 4)
  11495. + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
  11496. + sc->sc_bar0_lastreg = reg;
  11497. + }
  11498. + writel(val, sc->sc_bar0 + reg);
  11499. +}
  11500. +
  11501. +static void
  11502. +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  11503. +{
  11504. + if (sc->sc_flags & HIFN_IS_7811) {
  11505. + if (sc->sc_bar1_lastreg == reg - 4)
  11506. + readl(sc->sc_bar1 + HIFN_1_REVID);
  11507. + sc->sc_bar1_lastreg = reg;
  11508. + }
  11509. + writel(val, sc->sc_bar1 + reg);
  11510. +}
  11511. +
  11512. +
  11513. +static struct pci_device_id hifn_pci_tbl[] = {
  11514. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
  11515. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11516. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
  11517. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11518. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
  11519. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11520. + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
  11521. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11522. + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
  11523. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11524. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
  11525. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11526. + /*
  11527. + * Other vendors share this PCI ID as well, such as
  11528. + * http://www.powercrypt.com, and obviously they also
  11529. + * use the same key.
  11530. + */
  11531. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
  11532. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11533. + { 0, 0, 0, 0, 0, 0, }
  11534. +};
  11535. +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
  11536. +
  11537. +static struct pci_driver hifn_driver = {
  11538. + .name = "hifn",
  11539. + .id_table = hifn_pci_tbl,
  11540. + .probe = hifn_probe,
  11541. + .remove = hifn_remove,
  11542. + /* add PM stuff here one day */
  11543. +};
  11544. +
  11545. +static int __init hifn_init (void)
  11546. +{
  11547. + struct hifn_softc *sc = NULL;
  11548. + int rc;
  11549. +
  11550. + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
  11551. +
  11552. + rc = pci_register_driver(&hifn_driver);
  11553. + pci_register_driver_compat(&hifn_driver, rc);
  11554. +
  11555. + return rc;
  11556. +}
  11557. +
  11558. +static void __exit hifn_exit (void)
  11559. +{
  11560. + pci_unregister_driver(&hifn_driver);
  11561. +}
  11562. +
  11563. +module_init(hifn_init);
  11564. +module_exit(hifn_exit);
  11565. +
  11566. +MODULE_LICENSE("BSD");
  11567. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  11568. +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
  11569. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.27.10/crypto/ocf/hifn/hifn7751reg.h
  11570. --- linux-2.6.27.10.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
  11571. +++ linux-2.6.27.10/crypto/ocf/hifn/hifn7751reg.h 2008-12-23 19:31:44.000000000 +0100
  11572. @@ -0,0 +1,540 @@
  11573. +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
  11574. +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
  11575. +
  11576. +/*-
  11577. + * Invertex AEON / Hifn 7751 driver
  11578. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  11579. + * Copyright (c) 1999 Theo de Raadt
  11580. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  11581. + * http://www.netsec.net
  11582. + *
  11583. + * Please send any comments, feedback, bug-fixes, or feature requests to
  11584. + * software@invertex.com.
  11585. + *
  11586. + * Redistribution and use in source and binary forms, with or without
  11587. + * modification, are permitted provided that the following conditions
  11588. + * are met:
  11589. + *
  11590. + * 1. Redistributions of source code must retain the above copyright
  11591. + * notice, this list of conditions and the following disclaimer.
  11592. + * 2. Redistributions in binary form must reproduce the above copyright
  11593. + * notice, this list of conditions and the following disclaimer in the
  11594. + * documentation and/or other materials provided with the distribution.
  11595. + * 3. The name of the author may not be used to endorse or promote products
  11596. + * derived from this software without specific prior written permission.
  11597. + *
  11598. + *
  11599. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  11600. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  11601. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  11602. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  11603. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  11604. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11605. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11606. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11607. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  11608. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11609. + *
  11610. + * Effort sponsored in part by the Defense Advanced Research Projects
  11611. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  11612. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  11613. + *
  11614. + */
  11615. +#ifndef __HIFN_H__
  11616. +#define __HIFN_H__
  11617. +
  11618. +/*
  11619. + * Some PCI configuration space offset defines. The names were made
  11620. + * identical to the names used by the Linux kernel.
  11621. + */
  11622. +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
  11623. +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
  11624. +#define HIFN_TRDY_TIMEOUT 0x40
  11625. +#define HIFN_RETRY_TIMEOUT 0x41
  11626. +
  11627. +/*
  11628. + * PCI vendor and device identifiers
  11629. + * (the names are preserved from their OpenBSD source).
  11630. + */
  11631. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  11632. +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
  11633. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  11634. +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
  11635. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  11636. +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
  11637. +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
  11638. +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
  11639. +
  11640. +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
  11641. +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
  11642. +
  11643. +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
  11644. +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
  11645. +
  11646. +/*
  11647. + * The values below should multiple of 4 -- and be large enough to handle
  11648. + * any command the driver implements.
  11649. + *
  11650. + * MAX_COMMAND = base command + mac command + encrypt command +
  11651. + * mac-key + rc4-key
  11652. + * MAX_RESULT = base result + mac result + mac + encrypt result
  11653. + *
  11654. + *
  11655. + */
  11656. +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
  11657. +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
  11658. +
  11659. +/*
  11660. + * hifn_desc_t
  11661. + *
  11662. + * Holds an individual descriptor for any of the rings.
  11663. + */
  11664. +typedef struct hifn_desc {
  11665. + volatile u_int32_t l; /* length and status bits */
  11666. + volatile u_int32_t p;
  11667. +} hifn_desc_t;
  11668. +
  11669. +/*
  11670. + * Masks for the "length" field of struct hifn_desc.
  11671. + */
  11672. +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
  11673. +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
  11674. +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
  11675. +#define HIFN_D_OVER 0x08000000 /* overflow */
  11676. +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
  11677. +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
  11678. +#define HIFN_D_VALID 0x80000000 /* valid bit */
  11679. +
  11680. +
  11681. +/*
  11682. + * Processing Unit Registers (offset from BASEREG0)
  11683. + */
  11684. +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
  11685. +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
  11686. +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
  11687. +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
  11688. +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
  11689. +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
  11690. +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
  11691. +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
  11692. +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
  11693. +#define HIFN_0_MUTE1 0x80
  11694. +#define HIFN_0_MUTE2 0x90
  11695. +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
  11696. +
  11697. +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
  11698. +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
  11699. +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
  11700. +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
  11701. +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
  11702. +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
  11703. +
  11704. +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
  11705. +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
  11706. +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
  11707. +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  11708. +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  11709. +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
  11710. +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
  11711. +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
  11712. +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
  11713. +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
  11714. +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
  11715. +
  11716. +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
  11717. +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
  11718. +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
  11719. +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
  11720. +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
  11721. +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
  11722. +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
  11723. +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
  11724. +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
  11725. +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
  11726. +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
  11727. +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
  11728. +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
  11729. +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
  11730. +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
  11731. +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
  11732. +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
  11733. +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
  11734. +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
  11735. +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
  11736. +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
  11737. +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
  11738. +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
  11739. +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
  11740. +
  11741. +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
  11742. +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
  11743. +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
  11744. +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  11745. +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  11746. +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
  11747. +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
  11748. +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
  11749. +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
  11750. +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
  11751. +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
  11752. +
  11753. +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
  11754. +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
  11755. +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
  11756. +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  11757. +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  11758. +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
  11759. +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
  11760. +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
  11761. +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
  11762. +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
  11763. +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
  11764. +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
  11765. +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
  11766. +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
  11767. +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
  11768. +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
  11769. +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
  11770. +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
  11771. +
  11772. +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
  11773. +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
  11774. +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
  11775. +
  11776. +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
  11777. +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
  11778. +
  11779. +/*
  11780. + * DMA Interface Registers (offset from BASEREG1)
  11781. + */
  11782. +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
  11783. +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
  11784. +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
  11785. +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
  11786. +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
  11787. +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
  11788. +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
  11789. +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
  11790. +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
  11791. +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
  11792. +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
  11793. +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
  11794. +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
  11795. +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
  11796. +#define HIFN_1_REVID 0x98 /* Revision ID */
  11797. +
  11798. +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
  11799. +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
  11800. +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
  11801. +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
  11802. +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
  11803. +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
  11804. +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
  11805. +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
  11806. +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
  11807. +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
  11808. +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
  11809. +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
  11810. +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
  11811. +
  11812. +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
  11813. +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
  11814. +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
  11815. +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
  11816. +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
  11817. +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
  11818. +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
  11819. +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
  11820. +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
  11821. +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
  11822. +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
  11823. +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
  11824. +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
  11825. +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
  11826. +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  11827. +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
  11828. +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
  11829. +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
  11830. +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
  11831. +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
  11832. +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
  11833. +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
  11834. +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
  11835. +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  11836. +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
  11837. +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
  11838. +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
  11839. +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
  11840. +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
  11841. +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
  11842. +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
  11843. +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
  11844. +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
  11845. +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  11846. +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
  11847. +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
  11848. +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
  11849. +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
  11850. +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
  11851. +
  11852. +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
  11853. +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
  11854. +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
  11855. +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
  11856. +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
  11857. +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
  11858. +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  11859. +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
  11860. +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
  11861. +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
  11862. +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
  11863. +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  11864. +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
  11865. +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
  11866. +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
  11867. +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
  11868. +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
  11869. +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  11870. +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
  11871. +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
  11872. +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
  11873. +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
  11874. +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
  11875. +
  11876. +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
  11877. +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
  11878. +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
  11879. +#define HIFN_DMACNFG_UNLOCK 0x00000800
  11880. +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
  11881. +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
  11882. +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
  11883. +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
  11884. +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
  11885. +
  11886. +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
  11887. +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
  11888. +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
  11889. +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
  11890. +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
  11891. +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
  11892. +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
  11893. +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
  11894. +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
  11895. +
  11896. +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
  11897. +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
  11898. +
  11899. +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
  11900. +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
  11901. +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
  11902. +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
  11903. +
  11904. +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
  11905. +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
  11906. +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
  11907. +
  11908. +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
  11909. +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
  11910. +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
  11911. +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
  11912. +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
  11913. +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
  11914. +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
  11915. +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
  11916. +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
  11917. +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
  11918. +
  11919. +/* Public key reset register (HIFN_1_PUB_RESET) */
  11920. +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
  11921. +
  11922. +/* Public operation register (HIFN_1_PUB_OP) */
  11923. +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
  11924. +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
  11925. +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
  11926. +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
  11927. +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
  11928. +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
  11929. +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
  11930. +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
  11931. +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
  11932. +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
  11933. +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
  11934. +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
  11935. +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
  11936. +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
  11937. +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
  11938. +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
  11939. +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
  11940. +
  11941. +/* Public operand length register (HIFN_1_PUB_OPLEN) */
  11942. +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
  11943. +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
  11944. +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
  11945. +
  11946. +/* Public status register (HIFN_1_PUB_STATUS) */
  11947. +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
  11948. +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
  11949. +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
  11950. +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
  11951. +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
  11952. +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
  11953. +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
  11954. +
  11955. +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
  11956. +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
  11957. +
  11958. +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
  11959. +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
  11960. +
  11961. +/*
  11962. + * Register offsets in register set 1
  11963. + */
  11964. +
  11965. +#define HIFN_UNLOCK_SECRET1 0xf4
  11966. +#define HIFN_UNLOCK_SECRET2 0xfc
  11967. +
  11968. +/*
  11969. + * PLL config register
  11970. + *
  11971. + * This register is present only on 7954/7955/7956 parts. It must be
  11972. + * programmed according to the bus interface method used by the h/w.
  11973. + * Note that the parts require a stable clock. Since the PCI clock
  11974. + * may vary the reference clock must usually be used. To avoid
  11975. + * overclocking the core logic, setup must be done carefully, refer
  11976. + * to the driver for details. The exact multiplier required varies
  11977. + * by part and system configuration; refer to the Hifn documentation.
  11978. + */
  11979. +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
  11980. +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
  11981. +/* bit 2 reserved */
  11982. +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
  11983. +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
  11984. +/* bits 5-9 reserved */
  11985. +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
  11986. +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
  11987. +#define HIFN_PLL_ND_SHIFT 11
  11988. +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
  11989. +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
  11990. +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
  11991. +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
  11992. +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
  11993. +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
  11994. +/* bits 14-15 reserved */
  11995. +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
  11996. +/* bits 17-31 reserved */
  11997. +
  11998. +/*
  11999. + * Board configuration specifies only these bits.
  12000. + */
  12001. +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
  12002. +
  12003. +/*
  12004. + * Public Key Engine Mode Register
  12005. + */
  12006. +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
  12007. +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
  12008. +
  12009. +
  12010. +/*********************************************************************
  12011. + * Structs for board commands
  12012. + *
  12013. + *********************************************************************/
  12014. +
  12015. +/*
  12016. + * Structure to help build up the command data structure.
  12017. + */
  12018. +typedef struct hifn_base_command {
  12019. + volatile u_int16_t masks;
  12020. + volatile u_int16_t session_num;
  12021. + volatile u_int16_t total_source_count;
  12022. + volatile u_int16_t total_dest_count;
  12023. +} hifn_base_command_t;
  12024. +
  12025. +#define HIFN_BASE_CMD_MAC 0x0400
  12026. +#define HIFN_BASE_CMD_CRYPT 0x0800
  12027. +#define HIFN_BASE_CMD_DECODE 0x2000
  12028. +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
  12029. +#define HIFN_BASE_CMD_SRCLEN_S 14
  12030. +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
  12031. +#define HIFN_BASE_CMD_DSTLEN_S 12
  12032. +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
  12033. +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
  12034. +
  12035. +/*
  12036. + * Structure to help build up the command data structure.
  12037. + */
  12038. +typedef struct hifn_crypt_command {
  12039. + volatile u_int16_t masks;
  12040. + volatile u_int16_t header_skip;
  12041. + volatile u_int16_t source_count;
  12042. + volatile u_int16_t reserved;
  12043. +} hifn_crypt_command_t;
  12044. +
  12045. +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
  12046. +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
  12047. +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
  12048. +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
  12049. +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
  12050. +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
  12051. +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
  12052. +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
  12053. +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
  12054. +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
  12055. +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
  12056. +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
  12057. +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
  12058. +
  12059. +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
  12060. +#define HIFN_CRYPT_CMD_SRCLEN_S 14
  12061. +
  12062. +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
  12063. +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
  12064. +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
  12065. +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
  12066. +
  12067. +/*
  12068. + * Structure to help build up the command data structure.
  12069. + */
  12070. +typedef struct hifn_mac_command {
  12071. + volatile u_int16_t masks;
  12072. + volatile u_int16_t header_skip;
  12073. + volatile u_int16_t source_count;
  12074. + volatile u_int16_t reserved;
  12075. +} hifn_mac_command_t;
  12076. +
  12077. +#define HIFN_MAC_CMD_ALG_MASK 0x0001
  12078. +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
  12079. +#define HIFN_MAC_CMD_ALG_MD5 0x0001
  12080. +#define HIFN_MAC_CMD_MODE_MASK 0x000c
  12081. +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
  12082. +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
  12083. +#define HIFN_MAC_CMD_MODE_HASH 0x0008
  12084. +#define HIFN_MAC_CMD_MODE_FULL 0x0004
  12085. +#define HIFN_MAC_CMD_TRUNC 0x0010
  12086. +#define HIFN_MAC_CMD_RESULT 0x0020
  12087. +#define HIFN_MAC_CMD_APPEND 0x0040
  12088. +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
  12089. +#define HIFN_MAC_CMD_SRCLEN_S 14
  12090. +
  12091. +/*
  12092. + * MAC POS IPsec initiates authentication after encryption on encodes
  12093. + * and before decryption on decodes.
  12094. + */
  12095. +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
  12096. +#define HIFN_MAC_CMD_NEW_KEY 0x0800
  12097. +
  12098. +/*
  12099. + * The poll frequency and poll scalar defines are unshifted values used
  12100. + * to set fields in the DMA Configuration Register.
  12101. + */
  12102. +#ifndef HIFN_POLL_FREQUENCY
  12103. +#define HIFN_POLL_FREQUENCY 0x1
  12104. +#endif
  12105. +
  12106. +#ifndef HIFN_POLL_SCALAR
  12107. +#define HIFN_POLL_SCALAR 0x0
  12108. +#endif
  12109. +
  12110. +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
  12111. +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
  12112. +#endif /* __HIFN_H__ */
  12113. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.27.10/crypto/ocf/hifn/hifn7751var.h
  12114. --- linux-2.6.27.10.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
  12115. +++ linux-2.6.27.10/crypto/ocf/hifn/hifn7751var.h 2008-12-23 19:31:44.000000000 +0100
  12116. @@ -0,0 +1,369 @@
  12117. +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
  12118. +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
  12119. +
  12120. +/*-
  12121. + * Invertex AEON / Hifn 7751 driver
  12122. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  12123. + * Copyright (c) 1999 Theo de Raadt
  12124. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  12125. + * http://www.netsec.net
  12126. + *
  12127. + * Please send any comments, feedback, bug-fixes, or feature requests to
  12128. + * software@invertex.com.
  12129. + *
  12130. + * Redistribution and use in source and binary forms, with or without
  12131. + * modification, are permitted provided that the following conditions
  12132. + * are met:
  12133. + *
  12134. + * 1. Redistributions of source code must retain the above copyright
  12135. + * notice, this list of conditions and the following disclaimer.
  12136. + * 2. Redistributions in binary form must reproduce the above copyright
  12137. + * notice, this list of conditions and the following disclaimer in the
  12138. + * documentation and/or other materials provided with the distribution.
  12139. + * 3. The name of the author may not be used to endorse or promote products
  12140. + * derived from this software without specific prior written permission.
  12141. + *
  12142. + *
  12143. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12144. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12145. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12146. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12147. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12148. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12149. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12150. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12151. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12152. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12153. + *
  12154. + * Effort sponsored in part by the Defense Advanced Research Projects
  12155. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  12156. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  12157. + *
  12158. + */
  12159. +
  12160. +#ifndef __HIFN7751VAR_H__
  12161. +#define __HIFN7751VAR_H__
  12162. +
  12163. +#ifdef __KERNEL__
  12164. +
  12165. +/*
  12166. + * Some configurable values for the driver. By default command+result
  12167. + * descriptor rings are the same size. The src+dst descriptor rings
  12168. + * are sized at 3.5x the number of potential commands. Slower parts
  12169. + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
  12170. + * src+cmd/result descriptors. It's not clear that increasing the size
  12171. + * of the descriptor rings helps performance significantly as other
  12172. + * factors tend to come into play (e.g. copying misaligned packets).
  12173. + */
  12174. +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
  12175. +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
  12176. +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
  12177. +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
  12178. +
  12179. +/*
  12180. + * Length values for cryptography
  12181. + */
  12182. +#define HIFN_DES_KEY_LENGTH 8
  12183. +#define HIFN_3DES_KEY_LENGTH 24
  12184. +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
  12185. +#define HIFN_IV_LENGTH 8
  12186. +#define HIFN_AES_IV_LENGTH 16
  12187. +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
  12188. +
  12189. +/*
  12190. + * Length values for authentication
  12191. + */
  12192. +#define HIFN_MAC_KEY_LENGTH 64
  12193. +#define HIFN_MD5_LENGTH 16
  12194. +#define HIFN_SHA1_LENGTH 20
  12195. +#define HIFN_MAC_TRUNC_LENGTH 12
  12196. +
  12197. +#define MAX_SCATTER 64
  12198. +
  12199. +/*
  12200. + * Data structure to hold all 4 rings and any other ring related data.
  12201. + */
  12202. +struct hifn_dma {
  12203. + /*
  12204. + * Descriptor rings. We add +1 to the size to accomidate the
  12205. + * jump descriptor.
  12206. + */
  12207. + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
  12208. + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
  12209. + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
  12210. + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
  12211. +
  12212. + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
  12213. +
  12214. + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
  12215. + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
  12216. + u_int32_t slop[HIFN_D_CMD_RSIZE];
  12217. +
  12218. + u_int64_t test_src, test_dst;
  12219. +
  12220. + /*
  12221. + * Our current positions for insertion and removal from the desriptor
  12222. + * rings.
  12223. + */
  12224. + int cmdi, srci, dsti, resi;
  12225. + volatile int cmdu, srcu, dstu, resu;
  12226. + int cmdk, srck, dstk, resk;
  12227. +};
  12228. +
  12229. +struct hifn_session {
  12230. + int hs_used;
  12231. + int hs_mlen;
  12232. + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
  12233. +};
  12234. +
  12235. +#define HIFN_RING_SYNC(sc, r, i, f) \
  12236. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  12237. +
  12238. +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
  12239. +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
  12240. +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
  12241. +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
  12242. +
  12243. +#define HIFN_CMD_SYNC(sc, i, f) \
  12244. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  12245. +
  12246. +#define HIFN_RES_SYNC(sc, i, f) \
  12247. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  12248. +
  12249. +typedef int bus_size_t;
  12250. +
  12251. +/*
  12252. + * Holds data specific to a single HIFN board.
  12253. + */
  12254. +struct hifn_softc {
  12255. + softc_device_decl sc_dev;
  12256. +
  12257. + struct pci_dev *sc_pcidev; /* PCI device pointer */
  12258. + spinlock_t sc_mtx; /* per-instance lock */
  12259. +
  12260. + int sc_num; /* for multiple devs */
  12261. +
  12262. + ocf_iomem_t sc_bar0;
  12263. + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
  12264. + ocf_iomem_t sc_bar1;
  12265. + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
  12266. +
  12267. + int sc_irq;
  12268. +
  12269. + u_int32_t sc_dmaier;
  12270. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  12271. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  12272. +
  12273. + struct hifn_dma *sc_dma;
  12274. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  12275. +
  12276. + int sc_dmansegs;
  12277. + int32_t sc_cid;
  12278. + int sc_maxses;
  12279. + int sc_nsessions;
  12280. + struct hifn_session *sc_sessions;
  12281. + int sc_ramsize;
  12282. + int sc_flags;
  12283. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  12284. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  12285. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  12286. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  12287. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  12288. +
  12289. + struct timer_list sc_tickto; /* for managing DMA */
  12290. +
  12291. + int sc_rngfirst;
  12292. + int sc_rnghz; /* RNG polling frequency */
  12293. +
  12294. + int sc_c_busy; /* command ring busy */
  12295. + int sc_s_busy; /* source data ring busy */
  12296. + int sc_d_busy; /* destination data ring busy */
  12297. + int sc_r_busy; /* result ring busy */
  12298. + int sc_active; /* for initial countdown */
  12299. + int sc_needwakeup; /* ops q'd wating on resources */
  12300. + int sc_curbatch; /* # ops submitted w/o int */
  12301. + int sc_suspended;
  12302. +#ifdef HIFN_VULCANDEV
  12303. + struct cdev *sc_pkdev;
  12304. +#endif
  12305. +};
  12306. +
  12307. +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  12308. +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  12309. +
  12310. +/*
  12311. + * hifn_command_t
  12312. + *
  12313. + * This is the control structure used to pass commands to hifn_encrypt().
  12314. + *
  12315. + * flags
  12316. + * -----
  12317. + * Flags is the bitwise "or" values for command configuration. A single
  12318. + * encrypt direction needs to be set:
  12319. + *
  12320. + * HIFN_ENCODE or HIFN_DECODE
  12321. + *
  12322. + * To use cryptography, a single crypto algorithm must be included:
  12323. + *
  12324. + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
  12325. + *
  12326. + * To use authentication is used, a single MAC algorithm must be included:
  12327. + *
  12328. + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
  12329. + *
  12330. + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
  12331. + * If the value below is set, hash values are truncated or assumed
  12332. + * truncated to 12 bytes:
  12333. + *
  12334. + * HIFN_MAC_TRUNC
  12335. + *
  12336. + * Keys for encryption and authentication can be sent as part of a command,
  12337. + * or the last key value used with a particular session can be retrieved
  12338. + * and used again if either of these flags are not specified.
  12339. + *
  12340. + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
  12341. + *
  12342. + * session_num
  12343. + * -----------
  12344. + * A number between 0 and 2048 (for DRAM models) or a number between
  12345. + * 0 and 768 (for SRAM models). Those who don't want to use session
  12346. + * numbers should leave value at zero and send a new crypt key and/or
  12347. + * new MAC key on every command. If you use session numbers and
  12348. + * don't send a key with a command, the last key sent for that same
  12349. + * session number will be used.
  12350. + *
  12351. + * Warning: Using session numbers and multiboard at the same time
  12352. + * is currently broken.
  12353. + *
  12354. + * mbuf
  12355. + * ----
  12356. + * Either fill in the mbuf pointer and npa=0 or
  12357. + * fill packp[] and packl[] and set npa to > 0
  12358. + *
  12359. + * mac_header_skip
  12360. + * ---------------
  12361. + * The number of bytes of the source_buf that are skipped over before
  12362. + * authentication begins. This must be a number between 0 and 2^16-1
  12363. + * and can be used by IPsec implementers to skip over IP headers.
  12364. + * *** Value ignored if authentication not used ***
  12365. + *
  12366. + * crypt_header_skip
  12367. + * -----------------
  12368. + * The number of bytes of the source_buf that are skipped over before
  12369. + * the cryptographic operation begins. This must be a number between 0
  12370. + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
  12371. + * than the auth_header_skip (to skip over the ESP header).
  12372. + * *** Value ignored if cryptography not used ***
  12373. + *
  12374. + */
  12375. +struct hifn_operand {
  12376. + union {
  12377. + struct sk_buff *skb;
  12378. + struct uio *io;
  12379. + unsigned char *buf;
  12380. + } u;
  12381. + void *map;
  12382. + bus_size_t mapsize;
  12383. + int nsegs;
  12384. + struct {
  12385. + dma_addr_t ds_addr;
  12386. + int ds_len;
  12387. + } segs[MAX_SCATTER];
  12388. +};
  12389. +
  12390. +struct hifn_command {
  12391. + u_int16_t session_num;
  12392. + u_int16_t base_masks, cry_masks, mac_masks;
  12393. + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
  12394. + int cklen;
  12395. + int sloplen, slopidx;
  12396. +
  12397. + struct hifn_operand src;
  12398. + struct hifn_operand dst;
  12399. +
  12400. + struct hifn_softc *softc;
  12401. + struct cryptop *crp;
  12402. + struct cryptodesc *enccrd, *maccrd;
  12403. +};
  12404. +
  12405. +#define src_skb src.u.skb
  12406. +#define src_io src.u.io
  12407. +#define src_map src.map
  12408. +#define src_mapsize src.mapsize
  12409. +#define src_segs src.segs
  12410. +#define src_nsegs src.nsegs
  12411. +#define src_buf src.u.buf
  12412. +
  12413. +#define dst_skb dst.u.skb
  12414. +#define dst_io dst.u.io
  12415. +#define dst_map dst.map
  12416. +#define dst_mapsize dst.mapsize
  12417. +#define dst_segs dst.segs
  12418. +#define dst_nsegs dst.nsegs
  12419. +#define dst_buf dst.u.buf
  12420. +
  12421. +/*
  12422. + * Return values for hifn_crypto()
  12423. + */
  12424. +#define HIFN_CRYPTO_SUCCESS 0
  12425. +#define HIFN_CRYPTO_BAD_INPUT (-1)
  12426. +#define HIFN_CRYPTO_RINGS_FULL (-2)
  12427. +
  12428. +/**************************************************************************
  12429. + *
  12430. + * Function: hifn_crypto
  12431. + *
  12432. + * Purpose: Called by external drivers to begin an encryption on the
  12433. + * HIFN board.
  12434. + *
  12435. + * Blocking/Non-blocking Issues
  12436. + * ============================
  12437. + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
  12438. + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
  12439. + * room in any of the rings for the request to proceed.
  12440. + *
  12441. + * Return Values
  12442. + * =============
  12443. + * 0 for success, negative values on error
  12444. + *
  12445. + * Defines for negative error codes are:
  12446. + *
  12447. + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
  12448. + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
  12449. + * behaviour was requested.
  12450. + *
  12451. + *************************************************************************/
  12452. +
  12453. +/*
  12454. + * Convert back and forth from 'sid' to 'card' and 'session'
  12455. + */
  12456. +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
  12457. +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
  12458. +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
  12459. +
  12460. +#endif /* _KERNEL */
  12461. +
  12462. +struct hifn_stats {
  12463. + u_int64_t hst_ibytes;
  12464. + u_int64_t hst_obytes;
  12465. + u_int32_t hst_ipackets;
  12466. + u_int32_t hst_opackets;
  12467. + u_int32_t hst_invalid;
  12468. + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
  12469. + u_int32_t hst_abort;
  12470. + u_int32_t hst_noirq; /* IRQ for no reason */
  12471. + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
  12472. + u_int32_t hst_maxbatch; /* max ops submitted together */
  12473. + u_int32_t hst_unaligned; /* unaligned src caused copy */
  12474. + /*
  12475. + * The following divides hst_nomem into more specific buckets.
  12476. + */
  12477. + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
  12478. + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
  12479. + u_int32_t hst_nomem_mbuf; /* MGET* failed */
  12480. + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
  12481. + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
  12482. + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
  12483. +};
  12484. +
  12485. +#endif /* __HIFN7751VAR_H__ */
  12486. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.27.10/crypto/ocf/hifn/hifnHIPP.c
  12487. --- linux-2.6.27.10.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
  12488. +++ linux-2.6.27.10/crypto/ocf/hifn/hifnHIPP.c 2008-12-23 19:31:44.000000000 +0100
  12489. @@ -0,0 +1,420 @@
  12490. +/*-
  12491. + * Driver for Hifn HIPP-I/II chipset
  12492. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  12493. + *
  12494. + * Redistribution and use in source and binary forms, with or without
  12495. + * modification, are permitted provided that the following conditions
  12496. + * are met:
  12497. + *
  12498. + * 1. Redistributions of source code must retain the above copyright
  12499. + * notice, this list of conditions and the following disclaimer.
  12500. + * 2. Redistributions in binary form must reproduce the above copyright
  12501. + * notice, this list of conditions and the following disclaimer in the
  12502. + * documentation and/or other materials provided with the distribution.
  12503. + * 3. The name of the author may not be used to endorse or promote products
  12504. + * derived from this software without specific prior written permission.
  12505. + *
  12506. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12507. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12508. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12509. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12510. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12511. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12512. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12513. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12514. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12515. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12516. + *
  12517. + * Effort sponsored by Hifn Inc.
  12518. + *
  12519. + */
  12520. +
  12521. +/*
  12522. + * Driver for various Hifn encryption processors.
  12523. + */
  12524. +#ifndef AUTOCONF_INCLUDED
  12525. +#include <linux/config.h>
  12526. +#endif
  12527. +#include <linux/module.h>
  12528. +#include <linux/init.h>
  12529. +#include <linux/list.h>
  12530. +#include <linux/slab.h>
  12531. +#include <linux/wait.h>
  12532. +#include <linux/sched.h>
  12533. +#include <linux/pci.h>
  12534. +#include <linux/delay.h>
  12535. +#include <linux/interrupt.h>
  12536. +#include <linux/spinlock.h>
  12537. +#include <linux/random.h>
  12538. +#include <linux/version.h>
  12539. +#include <linux/skbuff.h>
  12540. +#include <linux/uio.h>
  12541. +#include <linux/sysfs.h>
  12542. +#include <linux/miscdevice.h>
  12543. +#include <asm/io.h>
  12544. +
  12545. +#include <cryptodev.h>
  12546. +
  12547. +#include "hifnHIPPreg.h"
  12548. +#include "hifnHIPPvar.h"
  12549. +
  12550. +#if 1
  12551. +#define DPRINTF(a...) if (hipp_debug) { \
  12552. + printk("%s: ", sc ? \
  12553. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  12554. + printk(a); \
  12555. + } else
  12556. +#else
  12557. +#define DPRINTF(a...)
  12558. +#endif
  12559. +
  12560. +typedef int bus_size_t;
  12561. +
  12562. +static inline int
  12563. +pci_get_revid(struct pci_dev *dev)
  12564. +{
  12565. + u8 rid = 0;
  12566. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  12567. + return rid;
  12568. +}
  12569. +
  12570. +#define debug hipp_debug
  12571. +int hipp_debug = 0;
  12572. +module_param(hipp_debug, int, 0644);
  12573. +MODULE_PARM_DESC(hipp_debug, "Enable debug");
  12574. +
  12575. +int hipp_maxbatch = 1;
  12576. +module_param(hipp_maxbatch, int, 0644);
  12577. +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
  12578. +
  12579. +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  12580. +static void hipp_remove(struct pci_dev *dev);
  12581. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  12582. +static irqreturn_t hipp_intr(int irq, void *arg);
  12583. +#else
  12584. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
  12585. +#endif
  12586. +
  12587. +static int hipp_num_chips = 0;
  12588. +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
  12589. +
  12590. +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
  12591. +static int hipp_freesession(device_t, u_int64_t);
  12592. +static int hipp_process(device_t, struct cryptop *, int);
  12593. +
  12594. +static device_method_t hipp_methods = {
  12595. + /* crypto device methods */
  12596. + DEVMETHOD(cryptodev_newsession, hipp_newsession),
  12597. + DEVMETHOD(cryptodev_freesession,hipp_freesession),
  12598. + DEVMETHOD(cryptodev_process, hipp_process),
  12599. +};
  12600. +
  12601. +static __inline u_int32_t
  12602. +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
  12603. +{
  12604. + u_int32_t v = readl(sc->sc_bar[barno] + reg);
  12605. + //sc->sc_bar0_lastreg = (bus_size_t) -1;
  12606. + return (v);
  12607. +}
  12608. +static __inline void
  12609. +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
  12610. +{
  12611. + writel(val, sc->sc_bar[barno] + reg);
  12612. +}
  12613. +
  12614. +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
  12615. +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
  12616. +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
  12617. +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
  12618. +
  12619. +static int
  12620. +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  12621. +{
  12622. + return EINVAL;
  12623. +}
  12624. +
  12625. +static int
  12626. +hipp_freesession(device_t dev, u_int64_t tid)
  12627. +{
  12628. + return EINVAL;
  12629. +}
  12630. +
  12631. +static int
  12632. +hipp_process(device_t dev, struct cryptop *crp, int hint)
  12633. +{
  12634. + return EINVAL;
  12635. +}
  12636. +
  12637. +static const char*
  12638. +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
  12639. +{
  12640. + char *n = NULL;
  12641. +
  12642. + switch (pci_get_vendor(sc->sc_pcidev)) {
  12643. + case PCI_VENDOR_HIFN:
  12644. + switch (pci_get_device(sc->sc_pcidev)) {
  12645. + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
  12646. + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
  12647. + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
  12648. + }
  12649. + }
  12650. +
  12651. + if(n==NULL) {
  12652. + snprintf(buf, blen, "VID=%02x,PID=%02x",
  12653. + pci_get_vendor(sc->sc_pcidev),
  12654. + pci_get_device(sc->sc_pcidev));
  12655. + } else {
  12656. + buf[0]='\0';
  12657. + strncat(buf, n, blen);
  12658. + }
  12659. + return buf;
  12660. +}
  12661. +
  12662. +struct hipp_fs_entry {
  12663. + struct attribute attr;
  12664. + /* other stuff */
  12665. +};
  12666. +
  12667. +
  12668. +static ssize_t
  12669. +cryptoid_show(struct device *dev,
  12670. + struct device_attribute *attr,
  12671. + char *buf)
  12672. +{
  12673. + struct hipp_softc *sc;
  12674. +
  12675. + sc = pci_get_drvdata(to_pci_dev (dev));
  12676. + return sprintf (buf, "%d\n", sc->sc_cid);
  12677. +}
  12678. +
  12679. +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
  12680. +
  12681. +/*
  12682. + * Attach an interface that successfully probed.
  12683. + */
  12684. +static int
  12685. +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  12686. +{
  12687. + struct hipp_softc *sc = NULL;
  12688. + int i;
  12689. + //char rbase;
  12690. + //u_int16_t ena;
  12691. + int rev;
  12692. + //int rseg;
  12693. + int rc;
  12694. +
  12695. + DPRINTF("%s()\n", __FUNCTION__);
  12696. +
  12697. + if (pci_enable_device(dev) < 0)
  12698. + return(-ENODEV);
  12699. +
  12700. + if (pci_set_mwi(dev))
  12701. + return(-ENODEV);
  12702. +
  12703. + if (!dev->irq) {
  12704. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  12705. + pci_disable_device(dev);
  12706. + return(-ENODEV);
  12707. + }
  12708. +
  12709. + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  12710. + if (!sc)
  12711. + return(-ENOMEM);
  12712. + memset(sc, 0, sizeof(*sc));
  12713. +
  12714. + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
  12715. +
  12716. + sc->sc_pcidev = dev;
  12717. + sc->sc_irq = -1;
  12718. + sc->sc_cid = -1;
  12719. + sc->sc_num = hipp_num_chips++;
  12720. +
  12721. + if (sc->sc_num < HIPP_MAX_CHIPS)
  12722. + hipp_chip_idx[sc->sc_num] = sc;
  12723. +
  12724. + pci_set_drvdata(sc->sc_pcidev, sc);
  12725. +
  12726. + spin_lock_init(&sc->sc_mtx);
  12727. +
  12728. + /*
  12729. + * Setup PCI resources.
  12730. + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
  12731. + * and WRITE_REG_1 macros throughout the driver are used
  12732. + * to permit better debugging.
  12733. + */
  12734. + for(i=0; i<4; i++) {
  12735. + unsigned long mem_start, mem_len;
  12736. + mem_start = pci_resource_start(sc->sc_pcidev, i);
  12737. + mem_len = pci_resource_len(sc->sc_pcidev, i);
  12738. + sc->sc_barphy[i] = (caddr_t)mem_start;
  12739. + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
  12740. + if (!sc->sc_bar[i]) {
  12741. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
  12742. + goto fail;
  12743. + }
  12744. + }
  12745. +
  12746. + //hipp_reset_board(sc, 0);
  12747. + pci_set_master(sc->sc_pcidev);
  12748. +
  12749. + /*
  12750. + * Arrange the interrupt line.
  12751. + */
  12752. + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
  12753. + if (rc) {
  12754. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  12755. + goto fail;
  12756. + }
  12757. + sc->sc_irq = dev->irq;
  12758. +
  12759. + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
  12760. +
  12761. + {
  12762. + char b[32];
  12763. + device_printf(sc->sc_dev, "%s, rev %u",
  12764. + hipp_partname(sc, b, sizeof(b)), rev);
  12765. + }
  12766. +
  12767. +#if 0
  12768. + if (sc->sc_flags & HIFN_IS_7956)
  12769. + printf(", pll=0x%x<%s clk, %ux mult>",
  12770. + sc->sc_pllconfig,
  12771. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  12772. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  12773. +#endif
  12774. + printf("\n");
  12775. +
  12776. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  12777. + if (sc->sc_cid < 0) {
  12778. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  12779. + goto fail;
  12780. + }
  12781. +
  12782. +#if 0 /* cannot work with a non-GPL module */
  12783. + /* make a sysfs entry to let the world know what entry we got */
  12784. + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
  12785. +#endif
  12786. +
  12787. +#if 0
  12788. + init_timer(&sc->sc_tickto);
  12789. + sc->sc_tickto.function = hifn_tick;
  12790. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  12791. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  12792. +#endif
  12793. +
  12794. +#if 0 /* no code here yet ?? */
  12795. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  12796. +#endif
  12797. +
  12798. + return (0);
  12799. +
  12800. +fail:
  12801. + if (sc->sc_cid >= 0)
  12802. + crypto_unregister_all(sc->sc_cid);
  12803. + if (sc->sc_irq != -1)
  12804. + free_irq(sc->sc_irq, sc);
  12805. +
  12806. +#if 0
  12807. + if (sc->sc_dma) {
  12808. + /* Turn off DMA polling */
  12809. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  12810. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  12811. +
  12812. + pci_free_consistent(sc->sc_pcidev,
  12813. + sizeof(*sc->sc_dma),
  12814. + sc->sc_dma, sc->sc_dma_physaddr);
  12815. + }
  12816. +#endif
  12817. + kfree(sc);
  12818. + return (-ENXIO);
  12819. +}
  12820. +
  12821. +/*
  12822. + * Detach an interface that successfully probed.
  12823. + */
  12824. +static void
  12825. +hipp_remove(struct pci_dev *dev)
  12826. +{
  12827. + struct hipp_softc *sc = pci_get_drvdata(dev);
  12828. + unsigned long l_flags;
  12829. +
  12830. + DPRINTF("%s()\n", __FUNCTION__);
  12831. +
  12832. + /* disable interrupts */
  12833. + HIPP_LOCK(sc);
  12834. +
  12835. +#if 0
  12836. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  12837. + HIFN_UNLOCK(sc);
  12838. +
  12839. + /*XXX other resources */
  12840. + del_timer_sync(&sc->sc_tickto);
  12841. +
  12842. + /* Turn off DMA polling */
  12843. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  12844. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  12845. +#endif
  12846. +
  12847. + crypto_unregister_all(sc->sc_cid);
  12848. +
  12849. + free_irq(sc->sc_irq, sc);
  12850. +
  12851. +#if 0
  12852. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  12853. + sc->sc_dma, sc->sc_dma_physaddr);
  12854. +#endif
  12855. +}
  12856. +
  12857. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  12858. +static irqreturn_t hipp_intr(int irq, void *arg)
  12859. +#else
  12860. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
  12861. +#endif
  12862. +{
  12863. + struct hipp_softc *sc = arg;
  12864. +
  12865. + sc = sc; /* shut up compiler */
  12866. +
  12867. + return IRQ_HANDLED;
  12868. +}
  12869. +
  12870. +static struct pci_device_id hipp_pci_tbl[] = {
  12871. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
  12872. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  12873. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
  12874. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  12875. +};
  12876. +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
  12877. +
  12878. +static struct pci_driver hipp_driver = {
  12879. + .name = "hipp",
  12880. + .id_table = hipp_pci_tbl,
  12881. + .probe = hipp_probe,
  12882. + .remove = hipp_remove,
  12883. + /* add PM stuff here one day */
  12884. +};
  12885. +
  12886. +static int __init hipp_init (void)
  12887. +{
  12888. + struct hipp_softc *sc = NULL;
  12889. + int rc;
  12890. +
  12891. + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
  12892. +
  12893. + rc = pci_register_driver(&hipp_driver);
  12894. + pci_register_driver_compat(&hipp_driver, rc);
  12895. +
  12896. + return rc;
  12897. +}
  12898. +
  12899. +static void __exit hipp_exit (void)
  12900. +{
  12901. + pci_unregister_driver(&hipp_driver);
  12902. +}
  12903. +
  12904. +module_init(hipp_init);
  12905. +module_exit(hipp_exit);
  12906. +
  12907. +MODULE_LICENSE("BSD");
  12908. +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
  12909. +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
  12910. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.27.10/crypto/ocf/hifn/hifnHIPPreg.h
  12911. --- linux-2.6.27.10.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
  12912. +++ linux-2.6.27.10/crypto/ocf/hifn/hifnHIPPreg.h 2008-12-23 19:31:44.000000000 +0100
  12913. @@ -0,0 +1,46 @@
  12914. +/*-
  12915. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  12916. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  12917. + *
  12918. + * Redistribution and use in source and binary forms, with or without
  12919. + * modification, are permitted provided that the following conditions
  12920. + * are met:
  12921. + *
  12922. + * 1. Redistributions of source code must retain the above copyright
  12923. + * notice, this list of conditions and the following disclaimer.
  12924. + * 2. Redistributions in binary form must reproduce the above copyright
  12925. + * notice, this list of conditions and the following disclaimer in the
  12926. + * documentation and/or other materials provided with the distribution.
  12927. + * 3. The name of the author may not be used to endorse or promote products
  12928. + * derived from this software without specific prior written permission.
  12929. + *
  12930. + *
  12931. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12932. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12933. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12934. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12935. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12936. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12937. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12938. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12939. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12940. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12941. + *
  12942. + * Effort sponsored by Hifn inc.
  12943. + *
  12944. + */
  12945. +
  12946. +#ifndef __HIFNHIPP_H__
  12947. +#define __HIFNHIPP_H__
  12948. +
  12949. +/*
  12950. + * PCI vendor and device identifiers
  12951. + */
  12952. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  12953. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  12954. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  12955. +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
  12956. +
  12957. +#define HIPP_1_REVID 0x01 /* BOGUS */
  12958. +
  12959. +#endif /* __HIPP_H__ */
  12960. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.27.10/crypto/ocf/hifn/hifnHIPPvar.h
  12961. --- linux-2.6.27.10.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
  12962. +++ linux-2.6.27.10/crypto/ocf/hifn/hifnHIPPvar.h 2008-12-23 19:31:44.000000000 +0100
  12963. @@ -0,0 +1,93 @@
  12964. +/*
  12965. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  12966. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
  12967. + *
  12968. + * Redistribution and use in source and binary forms, with or without
  12969. + * modification, are permitted provided that the following conditions
  12970. + * are met:
  12971. + *
  12972. + * 1. Redistributions of source code must retain the above copyright
  12973. + * notice, this list of conditions and the following disclaimer.
  12974. + * 2. Redistributions in binary form must reproduce the above copyright
  12975. + * notice, this list of conditions and the following disclaimer in the
  12976. + * documentation and/or other materials provided with the distribution.
  12977. + * 3. The name of the author may not be used to endorse or promote products
  12978. + * derived from this software without specific prior written permission.
  12979. + *
  12980. + *
  12981. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12982. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12983. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12984. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12985. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12986. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12987. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12988. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12989. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12990. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12991. + *
  12992. + * Effort sponsored by Hifn inc.
  12993. + *
  12994. + */
  12995. +
  12996. +#ifndef __HIFNHIPPVAR_H__
  12997. +#define __HIFNHIPPVAR_H__
  12998. +
  12999. +#define HIPP_MAX_CHIPS 8
  13000. +
  13001. +/*
  13002. + * Holds data specific to a single Hifn HIPP-I board.
  13003. + */
  13004. +struct hipp_softc {
  13005. + softc_device_decl sc_dev;
  13006. +
  13007. + struct pci_dev *sc_pcidev; /* device backpointer */
  13008. + ocf_iomem_t sc_bar[5];
  13009. + caddr_t sc_barphy[5]; /* physical address */
  13010. + int sc_num; /* for multiple devs */
  13011. + spinlock_t sc_mtx; /* per-instance lock */
  13012. + int32_t sc_cid;
  13013. + int sc_irq;
  13014. +
  13015. +#if 0
  13016. +
  13017. + u_int32_t sc_dmaier;
  13018. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  13019. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  13020. +
  13021. + struct hifn_dma *sc_dma;
  13022. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  13023. +
  13024. + int sc_dmansegs;
  13025. + int sc_maxses;
  13026. + int sc_nsessions;
  13027. + struct hifn_session *sc_sessions;
  13028. + int sc_ramsize;
  13029. + int sc_flags;
  13030. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  13031. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  13032. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  13033. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  13034. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  13035. +
  13036. + struct timer_list sc_tickto; /* for managing DMA */
  13037. +
  13038. + int sc_rngfirst;
  13039. + int sc_rnghz; /* RNG polling frequency */
  13040. +
  13041. + int sc_c_busy; /* command ring busy */
  13042. + int sc_s_busy; /* source data ring busy */
  13043. + int sc_d_busy; /* destination data ring busy */
  13044. + int sc_r_busy; /* result ring busy */
  13045. + int sc_active; /* for initial countdown */
  13046. + int sc_needwakeup; /* ops q'd wating on resources */
  13047. + int sc_curbatch; /* # ops submitted w/o int */
  13048. + int sc_suspended;
  13049. + struct miscdevice sc_miscdev;
  13050. +#endif
  13051. +};
  13052. +
  13053. +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  13054. +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  13055. +
  13056. +#endif /* __HIFNHIPPVAR_H__ */
  13057. diff -Nur linux-2.6.27.10.orig/crypto/ocf/hifn/Makefile linux-2.6.27.10/crypto/ocf/hifn/Makefile
  13058. --- linux-2.6.27.10.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
  13059. +++ linux-2.6.27.10/crypto/ocf/hifn/Makefile 2008-12-23 19:31:44.000000000 +0100
  13060. @@ -0,0 +1,13 @@
  13061. +# for SGlinux builds
  13062. +-include $(ROOTDIR)/modules/.config
  13063. +
  13064. +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
  13065. +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
  13066. +
  13067. +obj ?= .
  13068. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  13069. +
  13070. +ifdef TOPDIR
  13071. +-include $(TOPDIR)/Rules.make
  13072. +endif
  13073. +
  13074. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.27.10/crypto/ocf/ixp4xx/ixp4xx.c
  13075. --- linux-2.6.27.10.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
  13076. +++ linux-2.6.27.10/crypto/ocf/ixp4xx/ixp4xx.c 2008-12-23 19:31:44.000000000 +0100
  13077. @@ -0,0 +1,1328 @@
  13078. +/*
  13079. + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
  13080. + * This driver requires the IXP400 Access Library that is available
  13081. + * from Intel in order to operate (or compile).
  13082. + *
  13083. + * Written by David McCullough <david_mccullough@securecomputing.com>
  13084. + * Copyright (C) 2006-2007 David McCullough
  13085. + * Copyright (C) 2004-2005 Intel Corporation.
  13086. + *
  13087. + * LICENSE TERMS
  13088. + *
  13089. + * The free distribution and use of this software in both source and binary
  13090. + * form is allowed (with or without changes) provided that:
  13091. + *
  13092. + * 1. distributions of this source code include the above copyright
  13093. + * notice, this list of conditions and the following disclaimer;
  13094. + *
  13095. + * 2. distributions in binary form include the above copyright
  13096. + * notice, this list of conditions and the following disclaimer
  13097. + * in the documentation and/or other associated materials;
  13098. + *
  13099. + * 3. the copyright holder's name is not used to endorse products
  13100. + * built using this software without specific written permission.
  13101. + *
  13102. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  13103. + * may be distributed under the terms of the GNU General Public License (GPL),
  13104. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  13105. + *
  13106. + * DISCLAIMER
  13107. + *
  13108. + * This software is provided 'as is' with no explicit or implied warranties
  13109. + * in respect of its properties, including, but not limited to, correctness
  13110. + * and/or fitness for purpose.
  13111. + */
  13112. +
  13113. +#ifndef AUTOCONF_INCLUDED
  13114. +#include <linux/config.h>
  13115. +#endif
  13116. +#include <linux/module.h>
  13117. +#include <linux/init.h>
  13118. +#include <linux/list.h>
  13119. +#include <linux/slab.h>
  13120. +#include <linux/sched.h>
  13121. +#include <linux/wait.h>
  13122. +#include <linux/crypto.h>
  13123. +#include <linux/interrupt.h>
  13124. +#include <asm/scatterlist.h>
  13125. +
  13126. +#include <IxTypes.h>
  13127. +#include <IxOsBuffMgt.h>
  13128. +#include <IxNpeDl.h>
  13129. +#include <IxCryptoAcc.h>
  13130. +#include <IxQMgr.h>
  13131. +#include <IxOsServices.h>
  13132. +#include <IxOsCacheMMU.h>
  13133. +
  13134. +#include <cryptodev.h>
  13135. +#include <uio.h>
  13136. +
  13137. +#ifndef IX_MBUF_PRIV
  13138. +#define IX_MBUF_PRIV(x) ((x)->priv)
  13139. +#endif
  13140. +
  13141. +struct ixp_data;
  13142. +
  13143. +struct ixp_q {
  13144. + struct list_head ixp_q_list;
  13145. + struct ixp_data *ixp_q_data;
  13146. + struct cryptop *ixp_q_crp;
  13147. + struct cryptodesc *ixp_q_ccrd;
  13148. + struct cryptodesc *ixp_q_acrd;
  13149. + IX_MBUF ixp_q_mbuf;
  13150. + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
  13151. + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
  13152. + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
  13153. + unsigned char *ixp_q_iv;
  13154. +};
  13155. +
  13156. +struct ixp_data {
  13157. + int ixp_registered; /* is the context registered */
  13158. + int ixp_crd_flags; /* detect direction changes */
  13159. +
  13160. + int ixp_cipher_alg;
  13161. + int ixp_auth_alg;
  13162. +
  13163. + UINT32 ixp_ctx_id;
  13164. + UINT32 ixp_hash_key_id; /* used when hashing */
  13165. + IxCryptoAccCtx ixp_ctx;
  13166. + IX_MBUF ixp_pri_mbuf;
  13167. + IX_MBUF ixp_sec_mbuf;
  13168. +
  13169. + struct work_struct ixp_pending_work;
  13170. + struct work_struct ixp_registration_work;
  13171. + struct list_head ixp_q; /* unprocessed requests */
  13172. +};
  13173. +
  13174. +#ifdef __ixp46X
  13175. +
  13176. +#define MAX_IOP_SIZE 64 /* words */
  13177. +#define MAX_OOP_SIZE 128
  13178. +
  13179. +#define MAX_PARAMS 3
  13180. +
  13181. +struct ixp_pkq {
  13182. + struct list_head pkq_list;
  13183. + struct cryptkop *pkq_krp;
  13184. +
  13185. + IxCryptoAccPkeEauInOperands pkq_op;
  13186. + IxCryptoAccPkeEauOpResult pkq_result;
  13187. +
  13188. + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
  13189. + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
  13190. + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
  13191. + UINT32 pkq_obuf[MAX_OOP_SIZE];
  13192. +};
  13193. +
  13194. +static LIST_HEAD(ixp_pkq); /* current PK wait list */
  13195. +static struct ixp_pkq *ixp_pk_cur;
  13196. +static spinlock_t ixp_pkq_lock;
  13197. +
  13198. +#endif /* __ixp46X */
  13199. +
  13200. +static int ixp_blocked = 0;
  13201. +
  13202. +static int32_t ixp_id = -1;
  13203. +static struct ixp_data **ixp_sessions = NULL;
  13204. +static u_int32_t ixp_sesnum = 0;
  13205. +
  13206. +static int ixp_process(device_t, struct cryptop *, int);
  13207. +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
  13208. +static int ixp_freesession(device_t, u_int64_t);
  13209. +#ifdef __ixp46X
  13210. +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
  13211. +#endif
  13212. +
  13213. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  13214. +static kmem_cache_t *qcache;
  13215. +#else
  13216. +static struct kmem_cache *qcache;
  13217. +#endif
  13218. +
  13219. +#define debug ixp_debug
  13220. +static int ixp_debug = 0;
  13221. +module_param(ixp_debug, int, 0644);
  13222. +MODULE_PARM_DESC(ixp_debug, "Enable debug");
  13223. +
  13224. +static int ixp_init_crypto = 1;
  13225. +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
  13226. +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
  13227. +
  13228. +static void ixp_process_pending(void *arg);
  13229. +static void ixp_registration(void *arg);
  13230. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13231. +static void ixp_process_pending_wq(struct work_struct *work);
  13232. +static void ixp_registration_wq(struct work_struct *work);
  13233. +#endif
  13234. +
  13235. +/*
  13236. + * dummy device structure
  13237. + */
  13238. +
  13239. +static struct {
  13240. + softc_device_decl sc_dev;
  13241. +} ixpdev;
  13242. +
  13243. +static device_method_t ixp_methods = {
  13244. + /* crypto device methods */
  13245. + DEVMETHOD(cryptodev_newsession, ixp_newsession),
  13246. + DEVMETHOD(cryptodev_freesession,ixp_freesession),
  13247. + DEVMETHOD(cryptodev_process, ixp_process),
  13248. +#ifdef __ixp46X
  13249. + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
  13250. +#endif
  13251. +};
  13252. +
  13253. +/*
  13254. + * Generate a new software session.
  13255. + */
  13256. +static int
  13257. +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  13258. +{
  13259. + struct ixp_data *ixp;
  13260. + u_int32_t i;
  13261. +#define AUTH_LEN(cri, def) \
  13262. + (cri->cri_mlen ? cri->cri_mlen : (def))
  13263. +
  13264. + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
  13265. + if (sid == NULL || cri == NULL) {
  13266. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  13267. + return EINVAL;
  13268. + }
  13269. +
  13270. + if (ixp_sessions) {
  13271. + for (i = 1; i < ixp_sesnum; i++)
  13272. + if (ixp_sessions[i] == NULL)
  13273. + break;
  13274. + } else
  13275. + i = 1; /* NB: to silence compiler warning */
  13276. +
  13277. + if (ixp_sessions == NULL || i == ixp_sesnum) {
  13278. + struct ixp_data **ixpd;
  13279. +
  13280. + if (ixp_sessions == NULL) {
  13281. + i = 1; /* We leave ixp_sessions[0] empty */
  13282. + ixp_sesnum = CRYPTO_SW_SESSIONS;
  13283. + } else
  13284. + ixp_sesnum *= 2;
  13285. +
  13286. + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
  13287. + if (ixpd == NULL) {
  13288. + /* Reset session number */
  13289. + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
  13290. + ixp_sesnum = 0;
  13291. + else
  13292. + ixp_sesnum /= 2;
  13293. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  13294. + return ENOBUFS;
  13295. + }
  13296. + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
  13297. +
  13298. + /* Copy existing sessions */
  13299. + if (ixp_sessions) {
  13300. + memcpy(ixpd, ixp_sessions,
  13301. + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
  13302. + kfree(ixp_sessions);
  13303. + }
  13304. +
  13305. + ixp_sessions = ixpd;
  13306. + }
  13307. +
  13308. + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
  13309. + SLAB_ATOMIC);
  13310. + if (ixp_sessions[i] == NULL) {
  13311. + ixp_freesession(NULL, i);
  13312. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  13313. + return ENOBUFS;
  13314. + }
  13315. +
  13316. + *sid = i;
  13317. +
  13318. + ixp = ixp_sessions[i];
  13319. + memset(ixp, 0, sizeof(*ixp));
  13320. +
  13321. + ixp->ixp_cipher_alg = -1;
  13322. + ixp->ixp_auth_alg = -1;
  13323. + ixp->ixp_ctx_id = -1;
  13324. + INIT_LIST_HEAD(&ixp->ixp_q);
  13325. +
  13326. + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  13327. +
  13328. + while (cri) {
  13329. + switch (cri->cri_alg) {
  13330. + case CRYPTO_DES_CBC:
  13331. + ixp->ixp_cipher_alg = cri->cri_alg;
  13332. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
  13333. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  13334. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  13335. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  13336. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  13337. + IX_CRYPTO_ACC_DES_IV_64;
  13338. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  13339. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13340. + break;
  13341. +
  13342. + case CRYPTO_3DES_CBC:
  13343. + ixp->ixp_cipher_alg = cri->cri_alg;
  13344. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  13345. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  13346. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  13347. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  13348. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  13349. + IX_CRYPTO_ACC_DES_IV_64;
  13350. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  13351. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13352. + break;
  13353. +
  13354. + case CRYPTO_RIJNDAEL128_CBC:
  13355. + ixp->ixp_cipher_alg = cri->cri_alg;
  13356. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
  13357. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  13358. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  13359. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
  13360. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
  13361. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  13362. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13363. + break;
  13364. +
  13365. + case CRYPTO_MD5:
  13366. + case CRYPTO_MD5_HMAC:
  13367. + ixp->ixp_auth_alg = cri->cri_alg;
  13368. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
  13369. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
  13370. + ixp->ixp_ctx.authCtx.aadLen = 0;
  13371. + /* Only MD5_HMAC needs a key */
  13372. + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
  13373. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  13374. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  13375. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  13376. + printk(
  13377. + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
  13378. + cri->cri_klen);
  13379. + ixp_freesession(NULL, i);
  13380. + return EINVAL;
  13381. + }
  13382. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  13383. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13384. + }
  13385. + break;
  13386. +
  13387. + case CRYPTO_SHA1:
  13388. + case CRYPTO_SHA1_HMAC:
  13389. + ixp->ixp_auth_alg = cri->cri_alg;
  13390. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  13391. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
  13392. + ixp->ixp_ctx.authCtx.aadLen = 0;
  13393. + /* Only SHA1_HMAC needs a key */
  13394. + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
  13395. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  13396. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  13397. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  13398. + printk(
  13399. + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
  13400. + cri->cri_klen);
  13401. + ixp_freesession(NULL, i);
  13402. + return EINVAL;
  13403. + }
  13404. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  13405. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13406. + }
  13407. + break;
  13408. +
  13409. + default:
  13410. + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
  13411. + ixp_freesession(NULL, i);
  13412. + return EINVAL;
  13413. + }
  13414. + cri = cri->cri_next;
  13415. + }
  13416. +
  13417. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13418. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
  13419. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
  13420. +#else
  13421. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
  13422. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
  13423. +#endif
  13424. +
  13425. + return 0;
  13426. +}
  13427. +
  13428. +
  13429. +/*
  13430. + * Free a session.
  13431. + */
  13432. +static int
  13433. +ixp_freesession(device_t dev, u_int64_t tid)
  13434. +{
  13435. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  13436. +
  13437. + dprintk("%s()\n", __FUNCTION__);
  13438. + if (sid > ixp_sesnum || ixp_sessions == NULL ||
  13439. + ixp_sessions[sid] == NULL) {
  13440. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  13441. + return EINVAL;
  13442. + }
  13443. +
  13444. + /* Silently accept and return */
  13445. + if (sid == 0)
  13446. + return 0;
  13447. +
  13448. + if (ixp_sessions[sid]) {
  13449. + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
  13450. + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
  13451. + ixp_sessions[sid]->ixp_ctx_id = -1;
  13452. + }
  13453. +
  13454. + flush_scheduled_work();
  13455. +
  13456. + kfree(ixp_sessions[sid]);
  13457. + }
  13458. + ixp_sessions[sid] = NULL;
  13459. + if (ixp_blocked) {
  13460. + ixp_blocked = 0;
  13461. + crypto_unblock(ixp_id, CRYPTO_SYMQ);
  13462. + }
  13463. + return 0;
  13464. +}
  13465. +
  13466. +
  13467. +/*
  13468. + * callback for when hash processing is complete
  13469. + */
  13470. +
  13471. +static void
  13472. +ixp_hash_perform_cb(
  13473. + UINT32 hash_key_id,
  13474. + IX_MBUF *bufp,
  13475. + IxCryptoAccStatus status)
  13476. +{
  13477. + struct ixp_q *q;
  13478. +
  13479. + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
  13480. +
  13481. + if (bufp == NULL) {
  13482. + printk("ixp: NULL buf in %s\n", __FUNCTION__);
  13483. + return;
  13484. + }
  13485. +
  13486. + q = IX_MBUF_PRIV(bufp);
  13487. + if (q == NULL) {
  13488. + printk("ixp: NULL priv in %s\n", __FUNCTION__);
  13489. + return;
  13490. + }
  13491. +
  13492. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  13493. + /* On success, need to copy hash back into original client buffer */
  13494. + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
  13495. + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
  13496. + SHA1_HASH_LEN : MD5_HASH_LEN);
  13497. + }
  13498. + else {
  13499. + printk("ixp: hash perform failed status=%d\n", status);
  13500. + q->ixp_q_crp->crp_etype = EINVAL;
  13501. + }
  13502. +
  13503. + /* Free internal buffer used for hashing */
  13504. + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
  13505. +
  13506. + crypto_done(q->ixp_q_crp);
  13507. + kmem_cache_free(qcache, q);
  13508. +}
  13509. +
  13510. +/*
  13511. + * setup a request and perform it
  13512. + */
  13513. +static void
  13514. +ixp_q_process(struct ixp_q *q)
  13515. +{
  13516. + IxCryptoAccStatus status;
  13517. + struct ixp_data *ixp = q->ixp_q_data;
  13518. + int auth_off = 0;
  13519. + int auth_len = 0;
  13520. + int crypt_off = 0;
  13521. + int crypt_len = 0;
  13522. + int icv_off = 0;
  13523. + char *crypt_func;
  13524. +
  13525. + dprintk("%s(%p)\n", __FUNCTION__, q);
  13526. +
  13527. + if (q->ixp_q_ccrd) {
  13528. + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  13529. + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
  13530. + } else {
  13531. + q->ixp_q_iv = q->ixp_q_iv_data;
  13532. + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
  13533. + q->ixp_q_ccrd->crd_inject,
  13534. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
  13535. + (caddr_t) q->ixp_q_iv);
  13536. + }
  13537. +
  13538. + if (q->ixp_q_acrd) {
  13539. + auth_off = q->ixp_q_acrd->crd_skip;
  13540. + auth_len = q->ixp_q_acrd->crd_len;
  13541. + icv_off = q->ixp_q_acrd->crd_inject;
  13542. + }
  13543. +
  13544. + crypt_off = q->ixp_q_ccrd->crd_skip;
  13545. + crypt_len = q->ixp_q_ccrd->crd_len;
  13546. + } else { /* if (q->ixp_q_acrd) */
  13547. + auth_off = q->ixp_q_acrd->crd_skip;
  13548. + auth_len = q->ixp_q_acrd->crd_len;
  13549. + icv_off = q->ixp_q_acrd->crd_inject;
  13550. + }
  13551. +
  13552. + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
  13553. + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
  13554. + if (skb_shinfo(skb)->nr_frags) {
  13555. + /*
  13556. + * DAVIDM fix this limitation one day by using
  13557. + * a buffer pool and chaining, it is not currently
  13558. + * needed for current user/kernel space acceleration
  13559. + */
  13560. + printk("ixp: Cannot handle fragmented skb's yet !\n");
  13561. + q->ixp_q_crp->crp_etype = ENOENT;
  13562. + goto done;
  13563. + }
  13564. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  13565. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
  13566. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
  13567. + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
  13568. + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
  13569. + if (uiop->uio_iovcnt != 1) {
  13570. + /*
  13571. + * DAVIDM fix this limitation one day by using
  13572. + * a buffer pool and chaining, it is not currently
  13573. + * needed for current user/kernel space acceleration
  13574. + */
  13575. + printk("ixp: Cannot handle more than 1 iovec yet !\n");
  13576. + q->ixp_q_crp->crp_etype = ENOENT;
  13577. + goto done;
  13578. + }
  13579. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  13580. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
  13581. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
  13582. + } else /* contig buffer */ {
  13583. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  13584. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
  13585. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
  13586. + }
  13587. +
  13588. + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
  13589. +
  13590. + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
  13591. + /*
  13592. + * For SHA1 and MD5 hash, need to create an internal buffer that is big
  13593. + * enough to hold the original data + the appropriate padding for the
  13594. + * hash algorithm.
  13595. + */
  13596. + UINT8 *tbuf = NULL;
  13597. +
  13598. + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
  13599. + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
  13600. + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
  13601. +
  13602. + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
  13603. + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
  13604. + IX_MBUF_MLEN(&q->ixp_q_mbuf));
  13605. + q->ixp_q_crp->crp_etype = ENOMEM;
  13606. + goto done;
  13607. + }
  13608. + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
  13609. +
  13610. + /* Set location in client buffer to copy hash into */
  13611. + q->ixp_hash_dest =
  13612. + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
  13613. +
  13614. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
  13615. +
  13616. + /* Set location in internal buffer for where hash starts */
  13617. + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
  13618. +
  13619. + crypt_func = "ixCryptoAccHashPerform";
  13620. + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
  13621. + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
  13622. + &ixp->ixp_hash_key_id);
  13623. + }
  13624. + else {
  13625. + crypt_func = "ixCryptoAccAuthCryptPerform";
  13626. + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
  13627. + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
  13628. + q->ixp_q_iv);
  13629. + }
  13630. +
  13631. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  13632. + return;
  13633. +
  13634. + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
  13635. + q->ixp_q_crp->crp_etype = ENOMEM;
  13636. + goto done;
  13637. + }
  13638. +
  13639. + printk("ixp: %s failed %u\n", crypt_func, status);
  13640. + q->ixp_q_crp->crp_etype = EINVAL;
  13641. +
  13642. +done:
  13643. + crypto_done(q->ixp_q_crp);
  13644. + kmem_cache_free(qcache, q);
  13645. +}
  13646. +
  13647. +
  13648. +/*
  13649. + * because we cannot process the Q from the Register callback
  13650. + * we do it here on a task Q.
  13651. + */
  13652. +
  13653. +static void
  13654. +ixp_process_pending(void *arg)
  13655. +{
  13656. + struct ixp_data *ixp = arg;
  13657. + struct ixp_q *q = NULL;
  13658. +
  13659. + dprintk("%s(%p)\n", __FUNCTION__, arg);
  13660. +
  13661. + if (!ixp)
  13662. + return;
  13663. +
  13664. + while (!list_empty(&ixp->ixp_q)) {
  13665. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  13666. + list_del(&q->ixp_q_list);
  13667. + ixp_q_process(q);
  13668. + }
  13669. +}
  13670. +
  13671. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13672. +static void
  13673. +ixp_process_pending_wq(struct work_struct *work)
  13674. +{
  13675. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  13676. + ixp_pending_work);
  13677. + ixp_process_pending(ixp);
  13678. +}
  13679. +#endif
  13680. +
  13681. +/*
  13682. + * callback for when context registration is complete
  13683. + */
  13684. +
  13685. +static void
  13686. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  13687. +{
  13688. + int i;
  13689. + struct ixp_data *ixp;
  13690. + struct ixp_q *q;
  13691. +
  13692. + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
  13693. +
  13694. + /*
  13695. + * free any buffer passed in to this routine
  13696. + */
  13697. + if (bufp) {
  13698. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  13699. + kfree(IX_MBUF_MDATA(bufp));
  13700. + IX_MBUF_MDATA(bufp) = NULL;
  13701. + }
  13702. +
  13703. + for (i = 0; i < ixp_sesnum; i++) {
  13704. + ixp = ixp_sessions[i];
  13705. + if (ixp && ixp->ixp_ctx_id == ctx_id)
  13706. + break;
  13707. + }
  13708. + if (i >= ixp_sesnum) {
  13709. + printk("ixp: invalid context id %d\n", ctx_id);
  13710. + return;
  13711. + }
  13712. +
  13713. + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
  13714. + /* this is normal to free the first of two buffers */
  13715. + dprintk("ixp: register not finished yet.\n");
  13716. + return;
  13717. + }
  13718. +
  13719. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  13720. + printk("ixp: register failed 0x%x\n", status);
  13721. + while (!list_empty(&ixp->ixp_q)) {
  13722. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  13723. + list_del(&q->ixp_q_list);
  13724. + q->ixp_q_crp->crp_etype = EINVAL;
  13725. + crypto_done(q->ixp_q_crp);
  13726. + kmem_cache_free(qcache, q);
  13727. + }
  13728. + return;
  13729. + }
  13730. +
  13731. + /*
  13732. + * we are now registered, we cannot start processing the Q here
  13733. + * or we get strange errors with AES (DES/3DES seem to be ok).
  13734. + */
  13735. + ixp->ixp_registered = 1;
  13736. + schedule_work(&ixp->ixp_pending_work);
  13737. +}
  13738. +
  13739. +
  13740. +/*
  13741. + * callback for when data processing is complete
  13742. + */
  13743. +
  13744. +static void
  13745. +ixp_perform_cb(
  13746. + UINT32 ctx_id,
  13747. + IX_MBUF *sbufp,
  13748. + IX_MBUF *dbufp,
  13749. + IxCryptoAccStatus status)
  13750. +{
  13751. + struct ixp_q *q;
  13752. +
  13753. + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
  13754. + dbufp, status);
  13755. +
  13756. + if (sbufp == NULL) {
  13757. + printk("ixp: NULL sbuf in ixp_perform_cb\n");
  13758. + return;
  13759. + }
  13760. +
  13761. + q = IX_MBUF_PRIV(sbufp);
  13762. + if (q == NULL) {
  13763. + printk("ixp: NULL priv in ixp_perform_cb\n");
  13764. + return;
  13765. + }
  13766. +
  13767. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  13768. + printk("ixp: perform failed status=%d\n", status);
  13769. + q->ixp_q_crp->crp_etype = EINVAL;
  13770. + }
  13771. +
  13772. + crypto_done(q->ixp_q_crp);
  13773. + kmem_cache_free(qcache, q);
  13774. +}
  13775. +
  13776. +
  13777. +/*
  13778. + * registration is not callable at IRQ time, so we defer
  13779. + * to a task queue, this routines completes the registration for us
  13780. + * when the task queue runs
  13781. + *
  13782. + * Unfortunately this means we cannot tell OCF that the driver is blocked,
  13783. + * we do that on the next request.
  13784. + */
  13785. +
  13786. +static void
  13787. +ixp_registration(void *arg)
  13788. +{
  13789. + struct ixp_data *ixp = arg;
  13790. + struct ixp_q *q = NULL;
  13791. + IX_MBUF *pri = NULL, *sec = NULL;
  13792. + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
  13793. +
  13794. + if (!ixp) {
  13795. + printk("ixp: ixp_registration with no arg\n");
  13796. + return;
  13797. + }
  13798. +
  13799. + if (ixp->ixp_ctx_id != -1) {
  13800. + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
  13801. + ixp->ixp_ctx_id = -1;
  13802. + }
  13803. +
  13804. + if (list_empty(&ixp->ixp_q)) {
  13805. + printk("ixp: ixp_registration with no Q\n");
  13806. + return;
  13807. + }
  13808. +
  13809. + /*
  13810. + * setup the primary and secondary buffers
  13811. + */
  13812. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  13813. + if (q->ixp_q_acrd) {
  13814. + pri = &ixp->ixp_pri_mbuf;
  13815. + sec = &ixp->ixp_sec_mbuf;
  13816. + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
  13817. + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  13818. + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
  13819. + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  13820. + }
  13821. +
  13822. + /* Only need to register if a crypt op or HMAC op */
  13823. + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
  13824. + ixp->ixp_auth_alg == CRYPTO_MD5)) {
  13825. + status = ixCryptoAccCtxRegister(
  13826. + &ixp->ixp_ctx,
  13827. + pri, sec,
  13828. + ixp_register_cb,
  13829. + ixp_perform_cb,
  13830. + &ixp->ixp_ctx_id);
  13831. + }
  13832. + else {
  13833. + /* Otherwise we start processing pending q */
  13834. + schedule_work(&ixp->ixp_pending_work);
  13835. + }
  13836. +
  13837. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  13838. + return;
  13839. +
  13840. + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
  13841. + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
  13842. + ixp_blocked = 1;
  13843. + /* perhaps we should return EGAIN on queued ops ? */
  13844. + return;
  13845. + }
  13846. +
  13847. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  13848. + ixp->ixp_ctx_id = -1;
  13849. +
  13850. + /*
  13851. + * everything waiting is toasted
  13852. + */
  13853. + while (!list_empty(&ixp->ixp_q)) {
  13854. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  13855. + list_del(&q->ixp_q_list);
  13856. + q->ixp_q_crp->crp_etype = ENOENT;
  13857. + crypto_done(q->ixp_q_crp);
  13858. + kmem_cache_free(qcache, q);
  13859. + }
  13860. +}
  13861. +
  13862. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13863. +static void
  13864. +ixp_registration_wq(struct work_struct *work)
  13865. +{
  13866. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  13867. + ixp_registration_work);
  13868. + ixp_registration(ixp);
  13869. +}
  13870. +#endif
  13871. +
  13872. +/*
  13873. + * Process a request.
  13874. + */
  13875. +static int
  13876. +ixp_process(device_t dev, struct cryptop *crp, int hint)
  13877. +{
  13878. + struct ixp_data *ixp;
  13879. + unsigned int lid;
  13880. + struct ixp_q *q = NULL;
  13881. + int status;
  13882. +
  13883. + dprintk("%s()\n", __FUNCTION__);
  13884. +
  13885. + /* Sanity check */
  13886. + if (crp == NULL) {
  13887. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  13888. + return EINVAL;
  13889. + }
  13890. +
  13891. + crp->crp_etype = 0;
  13892. +
  13893. + if (ixp_blocked)
  13894. + return ERESTART;
  13895. +
  13896. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  13897. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  13898. + crp->crp_etype = EINVAL;
  13899. + goto done;
  13900. + }
  13901. +
  13902. + /*
  13903. + * find the session we are using
  13904. + */
  13905. +
  13906. + lid = crp->crp_sid & 0xffffffff;
  13907. + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
  13908. + ixp_sessions[lid] == NULL) {
  13909. + crp->crp_etype = ENOENT;
  13910. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  13911. + goto done;
  13912. + }
  13913. + ixp = ixp_sessions[lid];
  13914. +
  13915. + /*
  13916. + * setup a new request ready for queuing
  13917. + */
  13918. + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
  13919. + if (q == NULL) {
  13920. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  13921. + crp->crp_etype = ENOMEM;
  13922. + goto done;
  13923. + }
  13924. + /*
  13925. + * save some cycles by only zeroing the important bits
  13926. + */
  13927. + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
  13928. + q->ixp_q_ccrd = NULL;
  13929. + q->ixp_q_acrd = NULL;
  13930. + q->ixp_q_crp = crp;
  13931. + q->ixp_q_data = ixp;
  13932. +
  13933. + /*
  13934. + * point the cipher and auth descriptors appropriately
  13935. + * check that we have something to do
  13936. + */
  13937. + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
  13938. + q->ixp_q_ccrd = crp->crp_desc;
  13939. + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
  13940. + q->ixp_q_acrd = crp->crp_desc;
  13941. + else {
  13942. + crp->crp_etype = ENOENT;
  13943. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  13944. + goto done;
  13945. + }
  13946. + if (crp->crp_desc->crd_next) {
  13947. + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
  13948. + q->ixp_q_ccrd = crp->crp_desc->crd_next;
  13949. + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
  13950. + q->ixp_q_acrd = crp->crp_desc->crd_next;
  13951. + else {
  13952. + crp->crp_etype = ENOENT;
  13953. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  13954. + goto done;
  13955. + }
  13956. + }
  13957. +
  13958. + /*
  13959. + * If there is a direction change for this context then we mark it as
  13960. + * unregistered and re-register is for the new direction. This is not
  13961. + * a very expensive operation and currently only tends to happen when
  13962. + * user-space application are doing benchmarks
  13963. + *
  13964. + * DM - we should be checking for pending requests before unregistering.
  13965. + */
  13966. + if (q->ixp_q_ccrd && ixp->ixp_registered &&
  13967. + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
  13968. + dprintk("%s - detected direction change on session\n", __FUNCTION__);
  13969. + ixp->ixp_registered = 0;
  13970. + }
  13971. +
  13972. + /*
  13973. + * if we are registered, call straight into the perform code
  13974. + */
  13975. + if (ixp->ixp_registered) {
  13976. + ixp_q_process(q);
  13977. + return 0;
  13978. + }
  13979. +
  13980. + /*
  13981. + * the only part of the context not set in newsession is the direction
  13982. + * dependent parts
  13983. + */
  13984. + if (q->ixp_q_ccrd) {
  13985. + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
  13986. + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
  13987. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  13988. + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
  13989. + } else {
  13990. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  13991. + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
  13992. + }
  13993. + } else {
  13994. + /* q->ixp_q_acrd must be set if we are here */
  13995. + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
  13996. + }
  13997. +
  13998. + status = list_empty(&ixp->ixp_q);
  13999. + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
  14000. + if (status)
  14001. + schedule_work(&ixp->ixp_registration_work);
  14002. + return 0;
  14003. +
  14004. +done:
  14005. + if (q)
  14006. + kmem_cache_free(qcache, q);
  14007. + crypto_done(crp);
  14008. + return 0;
  14009. +}
  14010. +
  14011. +
  14012. +#ifdef __ixp46X
  14013. +/*
  14014. + * key processing support for the ixp465
  14015. + */
  14016. +
  14017. +
  14018. +/*
  14019. + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
  14020. + * assume zeroed and only copy bits that are significant
  14021. + */
  14022. +
  14023. +static int
  14024. +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
  14025. +{
  14026. + unsigned char *src = (unsigned char *) p->crp_p;
  14027. + unsigned char *dst;
  14028. + int len, bits = p->crp_nbits;
  14029. +
  14030. + dprintk("%s()\n", __FUNCTION__);
  14031. +
  14032. + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
  14033. + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
  14034. + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
  14035. + return -1;
  14036. + }
  14037. +
  14038. + len = (bits + 31) / 32; /* the number UINT32's needed */
  14039. +
  14040. + dst = (unsigned char *) &buf[len];
  14041. + dst--;
  14042. +
  14043. + while (bits > 0) {
  14044. + *dst-- = *src++;
  14045. + bits -= 8;
  14046. + }
  14047. +
  14048. +#if 0 /* no need to zero remaining bits as it is done during request alloc */
  14049. + while (dst > (unsigned char *) buf)
  14050. + *dst-- = '\0';
  14051. +#endif
  14052. +
  14053. + op->pData = buf;
  14054. + op->dataLen = len;
  14055. + return 0;
  14056. +}
  14057. +
  14058. +/*
  14059. + * copy out the result, be as forgiving as we can about small output buffers
  14060. + */
  14061. +
  14062. +static int
  14063. +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
  14064. +{
  14065. + unsigned char *dst = (unsigned char *) p->crp_p;
  14066. + unsigned char *src = (unsigned char *) buf;
  14067. + int len, z, bits = p->crp_nbits;
  14068. +
  14069. + dprintk("%s()\n", __FUNCTION__);
  14070. +
  14071. + len = op->dataLen * sizeof(UINT32);
  14072. +
  14073. + /* skip leading zeroes to be small buffer friendly */
  14074. + z = 0;
  14075. + while (z < len && src[z] == '\0')
  14076. + z++;
  14077. +
  14078. + src += len;
  14079. + src--;
  14080. + len -= z;
  14081. +
  14082. + while (len > 0 && bits > 0) {
  14083. + *dst++ = *src--;
  14084. + len--;
  14085. + bits -= 8;
  14086. + }
  14087. +
  14088. + while (bits > 0) {
  14089. + *dst++ = '\0';
  14090. + bits -= 8;
  14091. + }
  14092. +
  14093. + if (len > 0) {
  14094. + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
  14095. + __FUNCTION__, len, z, p->crp_nbits / 8);
  14096. + return -1;
  14097. + }
  14098. +
  14099. + return 0;
  14100. +}
  14101. +
  14102. +
  14103. +/*
  14104. + * the parameter offsets for exp_mod
  14105. + */
  14106. +
  14107. +#define IXP_PARAM_BASE 0
  14108. +#define IXP_PARAM_EXP 1
  14109. +#define IXP_PARAM_MOD 2
  14110. +#define IXP_PARAM_RES 3
  14111. +
  14112. +/*
  14113. + * key processing complete callback, is also used to start processing
  14114. + * by passing a NULL for pResult
  14115. + */
  14116. +
  14117. +static void
  14118. +ixp_kperform_cb(
  14119. + IxCryptoAccPkeEauOperation operation,
  14120. + IxCryptoAccPkeEauOpResult *pResult,
  14121. + BOOL carryOrBorrow,
  14122. + IxCryptoAccStatus status)
  14123. +{
  14124. + struct ixp_pkq *q, *tmp;
  14125. + unsigned long flags;
  14126. +
  14127. + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
  14128. + carryOrBorrow, status);
  14129. +
  14130. + /* handle a completed request */
  14131. + if (pResult) {
  14132. + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
  14133. + q = ixp_pk_cur;
  14134. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14135. + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
  14136. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  14137. + } else {
  14138. + /* copy out the result */
  14139. + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
  14140. + &q->pkq_result, q->pkq_obuf))
  14141. + q->pkq_krp->krp_status = ERANGE;
  14142. + }
  14143. + crypto_kdone(q->pkq_krp);
  14144. + kfree(q);
  14145. + ixp_pk_cur = NULL;
  14146. + } else
  14147. + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
  14148. + }
  14149. +
  14150. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  14151. + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
  14152. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14153. + return;
  14154. + }
  14155. +
  14156. + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
  14157. +
  14158. + list_del(&q->pkq_list);
  14159. + ixp_pk_cur = q;
  14160. +
  14161. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14162. +
  14163. + status = ixCryptoAccPkeEauPerform(
  14164. + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
  14165. + &q->pkq_op,
  14166. + ixp_kperform_cb,
  14167. + &q->pkq_result);
  14168. +
  14169. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14170. + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
  14171. + return; /* callback will return here for callback */
  14172. + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
  14173. + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
  14174. + } else {
  14175. + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
  14176. + __FUNCTION__, status);
  14177. + }
  14178. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  14179. + crypto_kdone(q->pkq_krp);
  14180. + kfree(q);
  14181. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  14182. + }
  14183. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14184. +}
  14185. +
  14186. +
  14187. +static int
  14188. +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
  14189. +{
  14190. + struct ixp_pkq *q;
  14191. + int rc = 0;
  14192. + unsigned long flags;
  14193. +
  14194. + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
  14195. + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
  14196. + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
  14197. + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
  14198. + krp->krp_param[IXP_PARAM_RES].crp_nbits);
  14199. +
  14200. +
  14201. + if (krp->krp_op != CRK_MOD_EXP) {
  14202. + krp->krp_status = EOPNOTSUPP;
  14203. + goto err;
  14204. + }
  14205. +
  14206. + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  14207. + if (q == NULL) {
  14208. + krp->krp_status = ENOMEM;
  14209. + goto err;
  14210. + }
  14211. +
  14212. + /*
  14213. + * The PKE engine does not appear to zero the output buffer
  14214. + * appropriately, so we need to do it all here.
  14215. + */
  14216. + memset(q, 0, sizeof(*q));
  14217. +
  14218. + q->pkq_krp = krp;
  14219. + INIT_LIST_HEAD(&q->pkq_list);
  14220. +
  14221. + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
  14222. + q->pkq_ibuf0))
  14223. + rc = 1;
  14224. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
  14225. + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
  14226. + rc = 2;
  14227. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
  14228. + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
  14229. + rc = 3;
  14230. +
  14231. + if (rc) {
  14232. + kfree(q);
  14233. + krp->krp_status = ERANGE;
  14234. + goto err;
  14235. + }
  14236. +
  14237. + q->pkq_result.pData = q->pkq_obuf;
  14238. + q->pkq_result.dataLen =
  14239. + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
  14240. +
  14241. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  14242. + list_add_tail(&q->pkq_list, &ixp_pkq);
  14243. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14244. +
  14245. + if (!ixp_pk_cur)
  14246. + ixp_kperform_cb(0, NULL, 0, 0);
  14247. + return (0);
  14248. +
  14249. +err:
  14250. + crypto_kdone(krp);
  14251. + return (0);
  14252. +}
  14253. +
  14254. +
  14255. +
  14256. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14257. +/*
  14258. + * We run the random number generator output through SHA so that it
  14259. + * is FIPS compliant.
  14260. + */
  14261. +
  14262. +static volatile int sha_done = 0;
  14263. +static unsigned char sha_digest[20];
  14264. +
  14265. +static void
  14266. +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
  14267. +{
  14268. + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
  14269. + if (sha_digest != digest)
  14270. + printk("digest error\n");
  14271. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  14272. + sha_done = 1;
  14273. + else
  14274. + sha_done = -status;
  14275. +}
  14276. +
  14277. +static int
  14278. +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
  14279. +{
  14280. + IxCryptoAccStatus status;
  14281. + int i, n, rc;
  14282. +
  14283. + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
  14284. + memset(buf, 0, maxwords * sizeof(*buf));
  14285. + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
  14286. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14287. + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
  14288. + __FUNCTION__, status);
  14289. + return 0;
  14290. + }
  14291. +
  14292. + /*
  14293. + * run the random data through SHA to make it look more random
  14294. + */
  14295. +
  14296. + n = sizeof(sha_digest); /* process digest bytes at a time */
  14297. +
  14298. + rc = 0;
  14299. + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
  14300. + if ((maxwords - i) * sizeof(*buf) < n)
  14301. + n = (maxwords - i) * sizeof(*buf);
  14302. + sha_done = 0;
  14303. + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
  14304. + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
  14305. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14306. + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
  14307. + return -EIO;
  14308. + }
  14309. + while (!sha_done)
  14310. + schedule();
  14311. + if (sha_done < 0) {
  14312. + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
  14313. + return 0;
  14314. + }
  14315. + memcpy(&buf[i], sha_digest, n);
  14316. + rc += n / sizeof(*buf);;
  14317. + }
  14318. +
  14319. + return rc;
  14320. +}
  14321. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  14322. +
  14323. +#endif /* __ixp46X */
  14324. +
  14325. +
  14326. +
  14327. +/*
  14328. + * our driver startup and shutdown routines
  14329. + */
  14330. +
  14331. +static int
  14332. +ixp_init(void)
  14333. +{
  14334. + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
  14335. +
  14336. + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
  14337. + printk("ixCryptoAccInit failed, assuming already initialised!\n");
  14338. +
  14339. + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
  14340. + SLAB_HWCACHE_ALIGN, NULL
  14341. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  14342. + , NULL
  14343. +#endif
  14344. + );
  14345. + if (!qcache) {
  14346. + printk("failed to create Qcache\n");
  14347. + return -ENOENT;
  14348. + }
  14349. +
  14350. + memset(&ixpdev, 0, sizeof(ixpdev));
  14351. + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
  14352. +
  14353. + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
  14354. + CRYPTOCAP_F_HARDWARE);
  14355. + if (ixp_id < 0)
  14356. + panic("IXP/OCF crypto device cannot initialize!");
  14357. +
  14358. +#define REGISTER(alg) \
  14359. + crypto_register(ixp_id,alg,0,0)
  14360. +
  14361. + REGISTER(CRYPTO_DES_CBC);
  14362. + REGISTER(CRYPTO_3DES_CBC);
  14363. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  14364. +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
  14365. + REGISTER(CRYPTO_MD5);
  14366. + REGISTER(CRYPTO_SHA1);
  14367. +#endif
  14368. + REGISTER(CRYPTO_MD5_HMAC);
  14369. + REGISTER(CRYPTO_SHA1_HMAC);
  14370. +#undef REGISTER
  14371. +
  14372. +#ifdef __ixp46X
  14373. + spin_lock_init(&ixp_pkq_lock);
  14374. + /*
  14375. + * we do not enable the go fast options here as they can potentially
  14376. + * allow timing based attacks
  14377. + *
  14378. + * http://www.openssl.org/news/secadv_20030219.txt
  14379. + */
  14380. + ixCryptoAccPkeEauExpConfig(0, 0);
  14381. + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
  14382. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14383. + crypto_rregister(ixp_id, ixp_read_random, NULL);
  14384. +#endif
  14385. +#endif
  14386. +
  14387. + return 0;
  14388. +}
  14389. +
  14390. +static void
  14391. +ixp_exit(void)
  14392. +{
  14393. + dprintk("%s()\n", __FUNCTION__);
  14394. + crypto_unregister_all(ixp_id);
  14395. + ixp_id = -1;
  14396. + kmem_cache_destroy(qcache);
  14397. + qcache = NULL;
  14398. +}
  14399. +
  14400. +module_init(ixp_init);
  14401. +module_exit(ixp_exit);
  14402. +
  14403. +MODULE_LICENSE("Dual BSD/GPL");
  14404. +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
  14405. +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
  14406. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.27.10/crypto/ocf/ixp4xx/Makefile
  14407. --- linux-2.6.27.10.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  14408. +++ linux-2.6.27.10/crypto/ocf/ixp4xx/Makefile 2008-12-23 19:31:44.000000000 +0100
  14409. @@ -0,0 +1,104 @@
  14410. +# for SGlinux builds
  14411. +-include $(ROOTDIR)/modules/.config
  14412. +
  14413. +#
  14414. +# You will need to point this at your Intel ixp425 includes, this portion
  14415. +# of the Makefile only really works under SGLinux with the appropriate libs
  14416. +# installed. They can be downloaded from http://www.snapgear.org/
  14417. +#
  14418. +ifeq ($(CONFIG_CPU_IXP46X),y)
  14419. +IXPLATFORM = ixp46X
  14420. +else
  14421. +ifeq ($(CONFIG_CPU_IXP43X),y)
  14422. +IXPLATFORM = ixp43X
  14423. +else
  14424. +IXPLATFORM = ixp42X
  14425. +endif
  14426. +endif
  14427. +
  14428. +ifdef CONFIG_IXP400_LIB_2_4
  14429. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
  14430. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
  14431. +endif
  14432. +ifdef CONFIG_IXP400_LIB_2_1
  14433. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
  14434. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
  14435. +endif
  14436. +ifdef CONFIG_IXP400_LIB_2_0
  14437. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
  14438. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
  14439. +endif
  14440. +ifdef IX_XSCALE_SW
  14441. +ifdef CONFIG_IXP400_LIB_2_4
  14442. +IXP_CFLAGS = \
  14443. + -I$(ROOTDIR)/. \
  14444. + -I$(IX_XSCALE_SW)/src/include \
  14445. + -I$(OSAL_DIR)/common/include/ \
  14446. + -I$(OSAL_DIR)/common/include/modules/ \
  14447. + -I$(OSAL_DIR)/common/include/modules/ddk/ \
  14448. + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
  14449. + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
  14450. + -I$(OSAL_DIR)/common/os/linux/include/ \
  14451. + -I$(OSAL_DIR)/common/os/linux/include/core/ \
  14452. + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
  14453. + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
  14454. + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
  14455. + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
  14456. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
  14457. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
  14458. + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
  14459. + -DUSE_IXP4XX_CRYPTO
  14460. +else
  14461. +IXP_CFLAGS = \
  14462. + -I$(ROOTDIR)/. \
  14463. + -I$(IX_XSCALE_SW)/src/include \
  14464. + -I$(OSAL_DIR)/ \
  14465. + -I$(OSAL_DIR)/os/linux/include/ \
  14466. + -I$(OSAL_DIR)/os/linux/include/modules/ \
  14467. + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
  14468. + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
  14469. + -I$(OSAL_DIR)/os/linux/include/core/ \
  14470. + -I$(OSAL_DIR)/os/linux/include/platforms/ \
  14471. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
  14472. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
  14473. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
  14474. + -I$(OSAL_DIR)/os/linux/include/core/ \
  14475. + -I$(OSAL_DIR)/include/ \
  14476. + -I$(OSAL_DIR)/include/modules/ \
  14477. + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
  14478. + -I$(OSAL_DIR)/include/modules/ioMem/ \
  14479. + -I$(OSAL_DIR)/include/platforms/ \
  14480. + -I$(OSAL_DIR)/include/platforms/ixp400/ \
  14481. + -DUSE_IXP4XX_CRYPTO
  14482. +endif
  14483. +endif
  14484. +ifdef CONFIG_IXP400_LIB_1_4
  14485. +IXP_CFLAGS = \
  14486. + -I$(ROOTDIR)/. \
  14487. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
  14488. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
  14489. + -DUSE_IXP4XX_CRYPTO
  14490. +endif
  14491. +ifndef IXPDIR
  14492. +IXPDIR = ixp-version-is-not-supported
  14493. +endif
  14494. +
  14495. +ifeq ($(CONFIG_CPU_IXP46X),y)
  14496. +IXP_CFLAGS += -D__ixp46X
  14497. +else
  14498. +ifeq ($(CONFIG_CPU_IXP43X),y)
  14499. +IXP_CFLAGS += -D__ixp43X
  14500. +else
  14501. +IXP_CFLAGS += -D__ixp42X
  14502. +endif
  14503. +endif
  14504. +
  14505. +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
  14506. +
  14507. +obj ?= .
  14508. +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
  14509. +
  14510. +ifdef TOPDIR
  14511. +-include $(TOPDIR)/Rules.make
  14512. +endif
  14513. +
  14514. diff -Nur linux-2.6.27.10.orig/crypto/ocf/Kconfig linux-2.6.27.10/crypto/ocf/Kconfig
  14515. --- linux-2.6.27.10.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
  14516. +++ linux-2.6.27.10/crypto/ocf/Kconfig 2008-12-23 19:31:44.000000000 +0100
  14517. @@ -0,0 +1,101 @@
  14518. +menu "OCF Configuration"
  14519. +
  14520. +config OCF_OCF
  14521. + tristate "OCF (Open Cryptograhic Framework)"
  14522. + help
  14523. + A linux port of the OpenBSD/FreeBSD crypto framework.
  14524. +
  14525. +config OCF_RANDOMHARVEST
  14526. + bool "crypto random --- harvest entropy for /dev/random"
  14527. + depends on OCF_OCF
  14528. + help
  14529. + Includes code to harvest random numbers from devices that support it.
  14530. +
  14531. +config OCF_FIPS
  14532. + bool "enable fips RNG checks"
  14533. + depends on OCF_OCF && OCF_RANDOMHARVEST
  14534. + help
  14535. + Run all RNG provided data through a fips check before
  14536. + adding it /dev/random's entropy pool.
  14537. +
  14538. +config OCF_CRYPTODEV
  14539. + tristate "cryptodev (user space support)"
  14540. + depends on OCF_OCF
  14541. + help
  14542. + The user space API to access crypto hardware.
  14543. +
  14544. +config OCF_CRYPTOSOFT
  14545. + tristate "cryptosoft (software crypto engine)"
  14546. + depends on OCF_OCF
  14547. + help
  14548. + A software driver for the OCF framework that uses
  14549. + the kernel CryptoAPI.
  14550. +
  14551. +config OCF_SAFE
  14552. + tristate "safenet (HW crypto engine)"
  14553. + depends on OCF_OCF
  14554. + help
  14555. + A driver for a number of the safenet Excel crypto accelerators.
  14556. + Currently tested and working on the 1141 and 1741.
  14557. +
  14558. +config OCF_IXP4XX
  14559. + tristate "IXP4xx (HW crypto engine)"
  14560. + depends on OCF_OCF
  14561. + help
  14562. + XScale IXP4xx crypto accelerator driver. Requires the
  14563. + Intel Access library.
  14564. +
  14565. +config OCF_IXP4XX_SHA1_MD5
  14566. + bool "IXP4xx SHA1 and MD5 Hashing"
  14567. + depends on OCF_IXP4XX
  14568. + help
  14569. + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
  14570. + Note: this is MUCH slower than using cryptosoft (software crypto engine).
  14571. +
  14572. +config OCF_HIFN
  14573. + tristate "hifn (HW crypto engine)"
  14574. + depends on OCF_OCF
  14575. + help
  14576. + OCF driver for various HIFN based crypto accelerators.
  14577. + (7951, 7955, 7956, 7751, 7811)
  14578. +
  14579. +config OCF_HIFNHIPP
  14580. + tristate "Hifn HIPP (HW packet crypto engine)"
  14581. + depends on OCF_OCF
  14582. + help
  14583. + OCF driver for various HIFN (HIPP) based crypto accelerators
  14584. + (7855)
  14585. +
  14586. +config OCF_TALITOS
  14587. + tristate "talitos (HW crypto engine)"
  14588. + depends on OCF_OCF
  14589. + help
  14590. + OCF driver for Freescale's security engine (SEC/talitos).
  14591. +
  14592. +config OCF_PASEMI
  14593. + tristate "pasemi (HW crypto engine)"
  14594. + depends on OCF_OCF && PPC_PASEMI
  14595. + help
  14596. + OCF driver for the PA Semi PWRficient DMA Engine
  14597. +
  14598. +config OCF_EP80579
  14599. + tristate "ep80579 (HW crypto engine)"
  14600. + depends on OCF_OCF
  14601. + help
  14602. + OCF driver for the Intel EP80579 Integrated Processor Product Line.
  14603. +
  14604. +config OCF_OCFNULL
  14605. + tristate "ocfnull (fake crypto engine)"
  14606. + depends on OCF_OCF
  14607. + help
  14608. + OCF driver for measuring ipsec overheads (does no crypto)
  14609. +
  14610. +config OCF_BENCH
  14611. + tristate "ocf-bench (HW crypto in-kernel benchmark)"
  14612. + depends on OCF_OCF
  14613. + help
  14614. + A very simple encryption test for the in-kernel interface
  14615. + of OCF. Also includes code to benchmark the IXP Access library
  14616. + for comparison.
  14617. +
  14618. +endmenu
  14619. diff -Nur linux-2.6.27.10.orig/crypto/ocf/Makefile linux-2.6.27.10/crypto/ocf/Makefile
  14620. --- linux-2.6.27.10.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
  14621. +++ linux-2.6.27.10/crypto/ocf/Makefile 2008-12-23 19:31:44.000000000 +0100
  14622. @@ -0,0 +1,121 @@
  14623. +# for SGlinux builds
  14624. +-include $(ROOTDIR)/modules/.config
  14625. +
  14626. +OCF_OBJS = crypto.o criov.o
  14627. +
  14628. +ifdef CONFIG_OCF_RANDOMHARVEST
  14629. + OCF_OBJS += random.o
  14630. +endif
  14631. +
  14632. +ifdef CONFIG_OCF_FIPS
  14633. + OCF_OBJS += rndtest.o
  14634. +endif
  14635. +
  14636. +# Add in autoconf.h to get #defines for CONFIG_xxx
  14637. +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
  14638. +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
  14639. + EXTRA_CFLAGS += -include $(AUTOCONF_H)
  14640. + export EXTRA_CFLAGS
  14641. +endif
  14642. +
  14643. +ifndef obj
  14644. + obj ?= .
  14645. + _obj = subdir
  14646. + mod-subdirs := safe hifn ixp4xx talitos ocfnull
  14647. + export-objs += crypto.o criov.o random.o
  14648. + list-multi += ocf.o
  14649. + _slash :=
  14650. +else
  14651. + _obj = obj
  14652. + _slash := /
  14653. +endif
  14654. +
  14655. +EXTRA_CFLAGS += -I$(obj)/.
  14656. +
  14657. +obj-$(CONFIG_OCF_OCF) += ocf.o
  14658. +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
  14659. +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
  14660. +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
  14661. +
  14662. +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
  14663. +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
  14664. +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
  14665. +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
  14666. +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
  14667. +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
  14668. +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
  14669. +
  14670. +ocf-objs := $(OCF_OBJS)
  14671. +
  14672. +$(list-multi) dummy1: $(ocf-objs)
  14673. + $(LD) -r -o $@ $(ocf-objs)
  14674. +
  14675. +.PHONY:
  14676. +clean:
  14677. + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
  14678. + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
  14679. +
  14680. +ifdef TOPDIR
  14681. +-include $(TOPDIR)/Rules.make
  14682. +endif
  14683. +
  14684. +#
  14685. +# release gen targets
  14686. +#
  14687. +
  14688. +.PHONY: patch
  14689. +patch:
  14690. + REL=`date +%Y%m%d`; \
  14691. + patch=ocf-linux-$$REL.patch; \
  14692. + patch24=ocf-linux-24-$$REL.patch; \
  14693. + patch26=ocf-linux-26-$$REL.patch; \
  14694. + ( \
  14695. + find . -name Makefile; \
  14696. + find . -name Config.in; \
  14697. + find . -name Kconfig; \
  14698. + find . -name README; \
  14699. + find . -name '*.[ch]' | grep -v '.mod.c'; \
  14700. + ) | while read t; do \
  14701. + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
  14702. + done > $$patch; \
  14703. + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
  14704. + cat patches/linux-2.6.26-ocf.patch $$patch > $$patch26
  14705. +
  14706. +.PHONY: tarball
  14707. +tarball:
  14708. + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
  14709. + CURDIR=`pwd`; \
  14710. + rm -rf /tmp/ocf-linux-$$REL*; \
  14711. + mkdir -p $$RELDIR/tools; \
  14712. + cp README* $$RELDIR; \
  14713. + cp patches/openss*.patch $$RELDIR; \
  14714. + cp patches/crypto-tools.patch $$RELDIR; \
  14715. + cp tools/[!C]* $$RELDIR/tools; \
  14716. + cd ..; \
  14717. + tar cvf $$RELDIR/ocf-linux.tar \
  14718. + --exclude=CVS \
  14719. + --exclude=.* \
  14720. + --exclude=*.o \
  14721. + --exclude=*.ko \
  14722. + --exclude=*.mod.* \
  14723. + --exclude=README* \
  14724. + --exclude=ocf-*.patch \
  14725. + --exclude=ocf/patches/openss*.patch \
  14726. + --exclude=ocf/patches/crypto-tools.patch \
  14727. + --exclude=ocf/tools \
  14728. + ocf; \
  14729. + gzip -9 $$RELDIR/ocf-linux.tar; \
  14730. + cd /tmp; \
  14731. + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
  14732. + gzip -9 ocf-linux-$$REL.tar; \
  14733. + cd $$CURDIR/../../user; \
  14734. + rm -rf /tmp/crypto-tools-$$REL*; \
  14735. + tar cvf /tmp/crypto-tools-$$REL.tar \
  14736. + --exclude=CVS \
  14737. + --exclude=.* \
  14738. + --exclude=*.o \
  14739. + --exclude=cryptotest \
  14740. + --exclude=cryptokeytest \
  14741. + crypto-tools; \
  14742. + gzip -9 /tmp/crypto-tools-$$REL.tar
  14743. +
  14744. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ocf-bench.c linux-2.6.27.10/crypto/ocf/ocf-bench.c
  14745. --- linux-2.6.27.10.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
  14746. +++ linux-2.6.27.10/crypto/ocf/ocf-bench.c 2008-12-23 19:31:44.000000000 +0100
  14747. @@ -0,0 +1,436 @@
  14748. +/*
  14749. + * A loadable module that benchmarks the OCF crypto speed from kernel space.
  14750. + *
  14751. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
  14752. + *
  14753. + * LICENSE TERMS
  14754. + *
  14755. + * The free distribution and use of this software in both source and binary
  14756. + * form is allowed (with or without changes) provided that:
  14757. + *
  14758. + * 1. distributions of this source code include the above copyright
  14759. + * notice, this list of conditions and the following disclaimer;
  14760. + *
  14761. + * 2. distributions in binary form include the above copyright
  14762. + * notice, this list of conditions and the following disclaimer
  14763. + * in the documentation and/or other associated materials;
  14764. + *
  14765. + * 3. the copyright holder's name is not used to endorse products
  14766. + * built using this software without specific written permission.
  14767. + *
  14768. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  14769. + * may be distributed under the terms of the GNU General Public License (GPL),
  14770. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  14771. + *
  14772. + * DISCLAIMER
  14773. + *
  14774. + * This software is provided 'as is' with no explicit or implied warranties
  14775. + * in respect of its properties, including, but not limited to, correctness
  14776. + * and/or fitness for purpose.
  14777. + */
  14778. +
  14779. +
  14780. +#ifndef AUTOCONF_INCLUDED
  14781. +#include <linux/config.h>
  14782. +#endif
  14783. +#include <linux/module.h>
  14784. +#include <linux/init.h>
  14785. +#include <linux/list.h>
  14786. +#include <linux/slab.h>
  14787. +#include <linux/wait.h>
  14788. +#include <linux/sched.h>
  14789. +#include <linux/spinlock.h>
  14790. +#include <linux/version.h>
  14791. +#include <linux/interrupt.h>
  14792. +#include <cryptodev.h>
  14793. +
  14794. +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
  14795. +#define BENCH_IXP_ACCESS_LIB 1
  14796. +#endif
  14797. +#ifdef BENCH_IXP_ACCESS_LIB
  14798. +#include <IxTypes.h>
  14799. +#include <IxOsBuffMgt.h>
  14800. +#include <IxNpeDl.h>
  14801. +#include <IxCryptoAcc.h>
  14802. +#include <IxQMgr.h>
  14803. +#include <IxOsServices.h>
  14804. +#include <IxOsCacheMMU.h>
  14805. +#endif
  14806. +
  14807. +/*
  14808. + * support for access lib version 1.4
  14809. + */
  14810. +#ifndef IX_MBUF_PRIV
  14811. +#define IX_MBUF_PRIV(x) ((x)->priv)
  14812. +#endif
  14813. +
  14814. +/*
  14815. + * the number of simultaneously active requests
  14816. + */
  14817. +static int request_q_len = 20;
  14818. +module_param(request_q_len, int, 0);
  14819. +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
  14820. +/*
  14821. + * how many requests we want to have processed
  14822. + */
  14823. +static int request_num = 1024;
  14824. +module_param(request_num, int, 0);
  14825. +MODULE_PARM_DESC(request_num, "run for at least this many requests");
  14826. +/*
  14827. + * the size of each request
  14828. + */
  14829. +static int request_size = 1500;
  14830. +module_param(request_size, int, 0);
  14831. +MODULE_PARM_DESC(request_size, "size of each request");
  14832. +
  14833. +/*
  14834. + * a structure for each request
  14835. + */
  14836. +typedef struct {
  14837. + struct work_struct work;
  14838. +#ifdef BENCH_IXP_ACCESS_LIB
  14839. + IX_MBUF mbuf;
  14840. +#endif
  14841. + unsigned char *buffer;
  14842. +} request_t;
  14843. +
  14844. +static request_t *requests;
  14845. +
  14846. +static int outstanding;
  14847. +static int total;
  14848. +
  14849. +/*************************************************************************/
  14850. +/*
  14851. + * OCF benchmark routines
  14852. + */
  14853. +
  14854. +static uint64_t ocf_cryptoid;
  14855. +static int ocf_init(void);
  14856. +static int ocf_cb(struct cryptop *crp);
  14857. +static void ocf_request(void *arg);
  14858. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  14859. +static void ocf_request_wq(struct work_struct *work);
  14860. +#endif
  14861. +
  14862. +static int
  14863. +ocf_init(void)
  14864. +{
  14865. + int error;
  14866. + struct cryptoini crie, cria;
  14867. + struct cryptodesc crda, crde;
  14868. +
  14869. + memset(&crie, 0, sizeof(crie));
  14870. + memset(&cria, 0, sizeof(cria));
  14871. + memset(&crde, 0, sizeof(crde));
  14872. + memset(&crda, 0, sizeof(crda));
  14873. +
  14874. + cria.cri_alg = CRYPTO_SHA1_HMAC;
  14875. + cria.cri_klen = 20 * 8;
  14876. + cria.cri_key = "0123456789abcdefghij";
  14877. +
  14878. + crie.cri_alg = CRYPTO_3DES_CBC;
  14879. + crie.cri_klen = 24 * 8;
  14880. + crie.cri_key = "0123456789abcdefghijklmn";
  14881. +
  14882. + crie.cri_next = &cria;
  14883. +
  14884. + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
  14885. + if (error) {
  14886. + printk("crypto_newsession failed %d\n", error);
  14887. + return -1;
  14888. + }
  14889. + return 0;
  14890. +}
  14891. +
  14892. +static int
  14893. +ocf_cb(struct cryptop *crp)
  14894. +{
  14895. + request_t *r = (request_t *) crp->crp_opaque;
  14896. +
  14897. + if (crp->crp_etype)
  14898. + printk("Error in OCF processing: %d\n", crp->crp_etype);
  14899. + total++;
  14900. + crypto_freereq(crp);
  14901. + crp = NULL;
  14902. +
  14903. + if (total > request_num) {
  14904. + outstanding--;
  14905. + return 0;
  14906. + }
  14907. +
  14908. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  14909. + INIT_WORK(&r->work, ocf_request_wq);
  14910. +#else
  14911. + INIT_WORK(&r->work, ocf_request, r);
  14912. +#endif
  14913. + schedule_work(&r->work);
  14914. + return 0;
  14915. +}
  14916. +
  14917. +
  14918. +static void
  14919. +ocf_request(void *arg)
  14920. +{
  14921. + request_t *r = arg;
  14922. + struct cryptop *crp = crypto_getreq(2);
  14923. + struct cryptodesc *crde, *crda;
  14924. +
  14925. + if (!crp) {
  14926. + outstanding--;
  14927. + return;
  14928. + }
  14929. +
  14930. + crde = crp->crp_desc;
  14931. + crda = crde->crd_next;
  14932. +
  14933. + crda->crd_skip = 0;
  14934. + crda->crd_flags = 0;
  14935. + crda->crd_len = request_size;
  14936. + crda->crd_inject = request_size;
  14937. + crda->crd_alg = CRYPTO_SHA1_HMAC;
  14938. + crda->crd_key = "0123456789abcdefghij";
  14939. + crda->crd_klen = 20 * 8;
  14940. +
  14941. + crde->crd_skip = 0;
  14942. + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
  14943. + crde->crd_len = request_size;
  14944. + crde->crd_inject = request_size;
  14945. + crde->crd_alg = CRYPTO_3DES_CBC;
  14946. + crde->crd_key = "0123456789abcdefghijklmn";
  14947. + crde->crd_klen = 24 * 8;
  14948. +
  14949. + crp->crp_ilen = request_size + 64;
  14950. + crp->crp_flags = CRYPTO_F_CBIMM;
  14951. + crp->crp_buf = (caddr_t) r->buffer;
  14952. + crp->crp_callback = ocf_cb;
  14953. + crp->crp_sid = ocf_cryptoid;
  14954. + crp->crp_opaque = (caddr_t) r;
  14955. + crypto_dispatch(crp);
  14956. +}
  14957. +
  14958. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  14959. +static void
  14960. +ocf_request_wq(struct work_struct *work)
  14961. +{
  14962. + request_t *r = container_of(work, request_t, work);
  14963. + ocf_request(r);
  14964. +}
  14965. +#endif
  14966. +
  14967. +/*************************************************************************/
  14968. +#ifdef BENCH_IXP_ACCESS_LIB
  14969. +/*************************************************************************/
  14970. +/*
  14971. + * CryptoAcc benchmark routines
  14972. + */
  14973. +
  14974. +static IxCryptoAccCtx ixp_ctx;
  14975. +static UINT32 ixp_ctx_id;
  14976. +static IX_MBUF ixp_pri;
  14977. +static IX_MBUF ixp_sec;
  14978. +static int ixp_registered = 0;
  14979. +
  14980. +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
  14981. + IxCryptoAccStatus status);
  14982. +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
  14983. + IxCryptoAccStatus status);
  14984. +static void ixp_request(void *arg);
  14985. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  14986. +static void ixp_request_wq(struct work_struct *work);
  14987. +#endif
  14988. +
  14989. +static int
  14990. +ixp_init(void)
  14991. +{
  14992. + IxCryptoAccStatus status;
  14993. +
  14994. + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  14995. + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  14996. + ixp_ctx.cipherCtx.cipherKeyLen = 24;
  14997. + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  14998. + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
  14999. + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
  15000. +
  15001. + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  15002. + ixp_ctx.authCtx.authDigestLen = 12;
  15003. + ixp_ctx.authCtx.aadLen = 0;
  15004. + ixp_ctx.authCtx.authKeyLen = 20;
  15005. + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
  15006. +
  15007. + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  15008. + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
  15009. +
  15010. + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
  15011. + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  15012. + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
  15013. + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  15014. +
  15015. + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
  15016. + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
  15017. +
  15018. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
  15019. + while (!ixp_registered)
  15020. + schedule();
  15021. + return ixp_registered < 0 ? -1 : 0;
  15022. + }
  15023. +
  15024. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  15025. + return -1;
  15026. +}
  15027. +
  15028. +static void
  15029. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  15030. +{
  15031. + if (bufp) {
  15032. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  15033. + kfree(IX_MBUF_MDATA(bufp));
  15034. + IX_MBUF_MDATA(bufp) = NULL;
  15035. + }
  15036. +
  15037. + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
  15038. + return;
  15039. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  15040. + ixp_registered = 1;
  15041. + else
  15042. + ixp_registered = -1;
  15043. +}
  15044. +
  15045. +static void
  15046. +ixp_perform_cb(
  15047. + UINT32 ctx_id,
  15048. + IX_MBUF *sbufp,
  15049. + IX_MBUF *dbufp,
  15050. + IxCryptoAccStatus status)
  15051. +{
  15052. + request_t *r = NULL;
  15053. +
  15054. + total++;
  15055. + if (total > request_num) {
  15056. + outstanding--;
  15057. + return;
  15058. + }
  15059. +
  15060. + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
  15061. + printk("crappo %p %p\n", sbufp, r);
  15062. + outstanding--;
  15063. + return;
  15064. + }
  15065. +
  15066. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15067. + INIT_WORK(&r->work, ixp_request_wq);
  15068. +#else
  15069. + INIT_WORK(&r->work, ixp_request, r);
  15070. +#endif
  15071. + schedule_work(&r->work);
  15072. +}
  15073. +
  15074. +static void
  15075. +ixp_request(void *arg)
  15076. +{
  15077. + request_t *r = arg;
  15078. + IxCryptoAccStatus status;
  15079. +
  15080. + memset(&r->mbuf, 0, sizeof(r->mbuf));
  15081. + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
  15082. + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
  15083. + IX_MBUF_PRIV(&r->mbuf) = r;
  15084. + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
  15085. + 0, request_size, 0, request_size, request_size, r->buffer);
  15086. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  15087. + printk("status1 = %d\n", status);
  15088. + outstanding--;
  15089. + return;
  15090. + }
  15091. + return;
  15092. +}
  15093. +
  15094. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15095. +static void
  15096. +ixp_request_wq(struct work_struct *work)
  15097. +{
  15098. + request_t *r = container_of(work, request_t, work);
  15099. + ixp_request(r);
  15100. +}
  15101. +#endif
  15102. +
  15103. +/*************************************************************************/
  15104. +#endif /* BENCH_IXP_ACCESS_LIB */
  15105. +/*************************************************************************/
  15106. +
  15107. +int
  15108. +ocfbench_init(void)
  15109. +{
  15110. + int i, jstart, jstop;
  15111. +
  15112. + printk("Crypto Speed tests\n");
  15113. +
  15114. + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
  15115. + if (!requests) {
  15116. + printk("malloc failed\n");
  15117. + return -EINVAL;
  15118. + }
  15119. +
  15120. + for (i = 0; i < request_q_len; i++) {
  15121. + /* +64 for return data */
  15122. + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
  15123. + if (!requests[i].buffer) {
  15124. + printk("malloc failed\n");
  15125. + return -EINVAL;
  15126. + }
  15127. + memset(requests[i].buffer, '0' + i, request_size + 128);
  15128. + }
  15129. +
  15130. + /*
  15131. + * OCF benchmark
  15132. + */
  15133. + printk("OCF: testing ...\n");
  15134. + ocf_init();
  15135. + total = outstanding = 0;
  15136. + jstart = jiffies;
  15137. + for (i = 0; i < request_q_len; i++) {
  15138. + outstanding++;
  15139. + ocf_request(&requests[i]);
  15140. + }
  15141. + while (outstanding > 0)
  15142. + schedule();
  15143. + jstop = jiffies;
  15144. +
  15145. + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
  15146. + jstop - jstart);
  15147. +
  15148. +#ifdef BENCH_IXP_ACCESS_LIB
  15149. + /*
  15150. + * IXP benchmark
  15151. + */
  15152. + printk("IXP: testing ...\n");
  15153. + ixp_init();
  15154. + total = outstanding = 0;
  15155. + jstart = jiffies;
  15156. + for (i = 0; i < request_q_len; i++) {
  15157. + outstanding++;
  15158. + ixp_request(&requests[i]);
  15159. + }
  15160. + while (outstanding > 0)
  15161. + schedule();
  15162. + jstop = jiffies;
  15163. +
  15164. + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
  15165. + jstop - jstart);
  15166. +#endif /* BENCH_IXP_ACCESS_LIB */
  15167. +
  15168. + for (i = 0; i < request_q_len; i++)
  15169. + kfree(requests[i].buffer);
  15170. + kfree(requests);
  15171. + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
  15172. +}
  15173. +
  15174. +static void __exit ocfbench_exit(void)
  15175. +{
  15176. +}
  15177. +
  15178. +module_init(ocfbench_init);
  15179. +module_exit(ocfbench_exit);
  15180. +
  15181. +MODULE_LICENSE("BSD");
  15182. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  15183. +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
  15184. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ocf-compat.h linux-2.6.27.10/crypto/ocf/ocf-compat.h
  15185. --- linux-2.6.27.10.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
  15186. +++ linux-2.6.27.10/crypto/ocf/ocf-compat.h 2008-12-23 19:31:44.000000000 +0100
  15187. @@ -0,0 +1,270 @@
  15188. +#ifndef _BSD_COMPAT_H_
  15189. +#define _BSD_COMPAT_H_ 1
  15190. +/****************************************************************************/
  15191. +/*
  15192. + * Provide compat routines for older linux kernels and BSD kernels
  15193. + *
  15194. + * Written by David McCullough <david_mccullough@securecomputing.com>
  15195. + * Copyright (C) 2007 David McCullough <david_mccullough@securecomputing.com>
  15196. + *
  15197. + * LICENSE TERMS
  15198. + *
  15199. + * The free distribution and use of this software in both source and binary
  15200. + * form is allowed (with or without changes) provided that:
  15201. + *
  15202. + * 1. distributions of this source code include the above copyright
  15203. + * notice, this list of conditions and the following disclaimer;
  15204. + *
  15205. + * 2. distributions in binary form include the above copyright
  15206. + * notice, this list of conditions and the following disclaimer
  15207. + * in the documentation and/or other associated materials;
  15208. + *
  15209. + * 3. the copyright holder's name is not used to endorse products
  15210. + * built using this software without specific written permission.
  15211. + *
  15212. + * ALTERNATIVELY, provided that this notice is retained in full, this file
  15213. + * may be distributed under the terms of the GNU General Public License (GPL),
  15214. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  15215. + *
  15216. + * DISCLAIMER
  15217. + *
  15218. + * This software is provided 'as is' with no explicit or implied warranties
  15219. + * in respect of its properties, including, but not limited to, correctness
  15220. + * and/or fitness for purpose.
  15221. + */
  15222. +/****************************************************************************/
  15223. +#ifdef __KERNEL__
  15224. +/*
  15225. + * fake some BSD driver interface stuff specifically for OCF use
  15226. + */
  15227. +
  15228. +typedef struct ocf_device *device_t;
  15229. +
  15230. +typedef struct {
  15231. + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
  15232. + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
  15233. + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
  15234. + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
  15235. +} device_method_t;
  15236. +#define DEVMETHOD(id, func) id: func
  15237. +
  15238. +struct ocf_device {
  15239. + char name[32]; /* the driver name */
  15240. + char nameunit[32]; /* the driver name + HW instance */
  15241. + int unit;
  15242. + device_method_t methods;
  15243. + void *softc;
  15244. +};
  15245. +
  15246. +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
  15247. + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
  15248. +#define CRYPTODEV_FREESESSION(dev, sid) \
  15249. + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
  15250. +#define CRYPTODEV_PROCESS(dev, crp, hint) \
  15251. + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
  15252. +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
  15253. + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
  15254. +
  15255. +#define device_get_name(dev) ((dev)->name)
  15256. +#define device_get_nameunit(dev) ((dev)->nameunit)
  15257. +#define device_get_unit(dev) ((dev)->unit)
  15258. +#define device_get_softc(dev) ((dev)->softc)
  15259. +
  15260. +#define softc_device_decl \
  15261. + struct ocf_device _device; \
  15262. + device_t
  15263. +
  15264. +#define softc_device_init(_sc, _name, _unit, _methods) \
  15265. + if (1) {\
  15266. + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
  15267. + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
  15268. + (_sc)->_device.unit = _unit; \
  15269. + (_sc)->_device.methods = _methods; \
  15270. + (_sc)->_device.softc = (void *) _sc; \
  15271. + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
  15272. + } else
  15273. +
  15274. +#define softc_get_device(_sc) (&(_sc)->_device)
  15275. +
  15276. +/*
  15277. + * iomem support for 2.4 and 2.6 kernels
  15278. + */
  15279. +#include <linux/version.h>
  15280. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  15281. +#define ocf_iomem_t unsigned long
  15282. +
  15283. +/*
  15284. + * implement simple workqueue like support for older kernels
  15285. + */
  15286. +
  15287. +#include <linux/tqueue.h>
  15288. +
  15289. +#define work_struct tq_struct
  15290. +
  15291. +#define INIT_WORK(wp, fp, ap) \
  15292. + do { \
  15293. + (wp)->sync = 0; \
  15294. + (wp)->routine = (fp); \
  15295. + (wp)->data = (ap); \
  15296. + } while (0)
  15297. +
  15298. +#define schedule_work(wp) \
  15299. + do { \
  15300. + queue_task((wp), &tq_immediate); \
  15301. + mark_bh(IMMEDIATE_BH); \
  15302. + } while (0)
  15303. +
  15304. +#define flush_scheduled_work() run_task_queue(&tq_immediate)
  15305. +
  15306. +#else
  15307. +#define ocf_iomem_t void __iomem *
  15308. +
  15309. +#include <linux/workqueue.h>
  15310. +
  15311. +#endif
  15312. +
  15313. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
  15314. +#include <linux/fdtable.h>
  15315. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
  15316. +#define files_fdtable(files) (files)
  15317. +#endif
  15318. +
  15319. +#ifdef MODULE_PARM
  15320. +#undef module_param /* just in case */
  15321. +#define module_param(a,b,c) MODULE_PARM(a,"i")
  15322. +#endif
  15323. +
  15324. +#define bzero(s,l) memset(s,0,l)
  15325. +#define bcopy(s,d,l) memcpy(d,s,l)
  15326. +#define bcmp(x, y, l) memcmp(x,y,l)
  15327. +
  15328. +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  15329. +
  15330. +#define device_printf(dev, a...) ({ \
  15331. + printk("%s: ", device_get_nameunit(dev)); printk(a); \
  15332. + })
  15333. +
  15334. +#undef printf
  15335. +#define printf(fmt...) printk(fmt)
  15336. +
  15337. +#define KASSERT(c,p) if (!(c)) { printk p ; } else
  15338. +
  15339. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  15340. +#define ocf_daemonize(str) \
  15341. + daemonize(); \
  15342. + spin_lock_irq(&current->sigmask_lock); \
  15343. + sigemptyset(&current->blocked); \
  15344. + recalc_sigpending(current); \
  15345. + spin_unlock_irq(&current->sigmask_lock); \
  15346. + sprintf(current->comm, str);
  15347. +#else
  15348. +#define ocf_daemonize(str) daemonize(str);
  15349. +#endif
  15350. +
  15351. +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
  15352. +#define TAILQ_EMPTY(q) list_empty(q)
  15353. +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
  15354. +
  15355. +#define read_random(p,l) get_random_bytes(p,l)
  15356. +
  15357. +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
  15358. +#define strtoul simple_strtoul
  15359. +
  15360. +#define pci_get_vendor(dev) ((dev)->vendor)
  15361. +#define pci_get_device(dev) ((dev)->device)
  15362. +
  15363. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  15364. +#define pci_set_consistent_dma_mask(dev, mask) (0)
  15365. +#endif
  15366. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  15367. +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
  15368. +#endif
  15369. +
  15370. +#ifndef DMA_32BIT_MASK
  15371. +#define DMA_32BIT_MASK 0x00000000ffffffffULL
  15372. +#endif
  15373. +
  15374. +#define htole32(x) cpu_to_le32(x)
  15375. +#define htobe32(x) cpu_to_be32(x)
  15376. +#define htole16(x) cpu_to_le16(x)
  15377. +#define htobe16(x) cpu_to_be16(x)
  15378. +
  15379. +/* older kernels don't have these */
  15380. +
  15381. +#ifndef IRQ_NONE
  15382. +#define IRQ_NONE
  15383. +#define IRQ_HANDLED
  15384. +#define irqreturn_t void
  15385. +#endif
  15386. +#ifndef IRQF_SHARED
  15387. +#define IRQF_SHARED SA_SHIRQ
  15388. +#endif
  15389. +
  15390. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  15391. +# define strlcpy(dest,src,len) \
  15392. + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
  15393. +#endif
  15394. +
  15395. +#ifndef MAX_ERRNO
  15396. +#define MAX_ERRNO 4095
  15397. +#endif
  15398. +#ifndef IS_ERR_VALUE
  15399. +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
  15400. +#endif
  15401. +
  15402. +/*
  15403. + * common debug for all
  15404. + */
  15405. +#if 1
  15406. +#define dprintk(a...) do { if (debug) printk(a); } while(0)
  15407. +#else
  15408. +#define dprintk(a...)
  15409. +#endif
  15410. +
  15411. +#ifndef SLAB_ATOMIC
  15412. +/* Changed in 2.6.20, must use GFP_ATOMIC now */
  15413. +#define SLAB_ATOMIC GFP_ATOMIC
  15414. +#endif
  15415. +
  15416. +/*
  15417. + * need some additional support for older kernels */
  15418. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
  15419. +#define pci_register_driver_compat(driver, rc) \
  15420. + do { \
  15421. + if ((rc) > 0) { \
  15422. + (rc) = 0; \
  15423. + } else if (rc == 0) { \
  15424. + (rc) = -ENODEV; \
  15425. + } else { \
  15426. + pci_unregister_driver(driver); \
  15427. + } \
  15428. + } while (0)
  15429. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  15430. +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
  15431. +#else
  15432. +#define pci_register_driver_compat(driver,rc)
  15433. +#endif
  15434. +
  15435. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  15436. +
  15437. +#include <asm/scatterlist.h>
  15438. +
  15439. +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
  15440. + unsigned int len, unsigned int offset)
  15441. +{
  15442. + sg->page = page;
  15443. + sg->offset = offset;
  15444. + sg->length = len;
  15445. +}
  15446. +
  15447. +static inline void *sg_virt(struct scatterlist *sg)
  15448. +{
  15449. + return page_address(sg->page) + sg->offset;
  15450. +}
  15451. +
  15452. +#endif
  15453. +
  15454. +#endif /* __KERNEL__ */
  15455. +
  15456. +/****************************************************************************/
  15457. +#endif /* _BSD_COMPAT_H_ */
  15458. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ocfnull/Makefile linux-2.6.27.10/crypto/ocf/ocfnull/Makefile
  15459. --- linux-2.6.27.10.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
  15460. +++ linux-2.6.27.10/crypto/ocf/ocfnull/Makefile 2008-12-23 19:31:44.000000000 +0100
  15461. @@ -0,0 +1,12 @@
  15462. +# for SGlinux builds
  15463. +-include $(ROOTDIR)/modules/.config
  15464. +
  15465. +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
  15466. +
  15467. +obj ?= .
  15468. +EXTRA_CFLAGS += -I$(obj)/..
  15469. +
  15470. +ifdef TOPDIR
  15471. +-include $(TOPDIR)/Rules.make
  15472. +endif
  15473. +
  15474. diff -Nur linux-2.6.27.10.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.27.10/crypto/ocf/ocfnull/ocfnull.c
  15475. --- linux-2.6.27.10.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
  15476. +++ linux-2.6.27.10/crypto/ocf/ocfnull/ocfnull.c 2008-12-23 19:31:44.000000000 +0100
  15477. @@ -0,0 +1,203 @@
  15478. +/*
  15479. + * An OCF module for determining the cost of crypto versus the cost of
  15480. + * IPSec processing outside of OCF. This modules gives us the effect of
  15481. + * zero cost encryption, of course you will need to run it at both ends
  15482. + * since it does no crypto at all.
  15483. + *
  15484. + * Written by David McCullough <david_mccullough@securecomputing.com>
  15485. + * Copyright (C) 2006-2007 David McCullough
  15486. + *
  15487. + * LICENSE TERMS
  15488. + *
  15489. + * The free distribution and use of this software in both source and binary
  15490. + * form is allowed (with or without changes) provided that:
  15491. + *
  15492. + * 1. distributions of this source code include the above copyright
  15493. + * notice, this list of conditions and the following disclaimer;
  15494. + *
  15495. + * 2. distributions in binary form include the above copyright
  15496. + * notice, this list of conditions and the following disclaimer
  15497. + * in the documentation and/or other associated materials;
  15498. + *
  15499. + * 3. the copyright holder's name is not used to endorse products
  15500. + * built using this software without specific written permission.
  15501. + *
  15502. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  15503. + * may be distributed under the terms of the GNU General Public License (GPL),
  15504. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  15505. + *
  15506. + * DISCLAIMER
  15507. + *
  15508. + * This software is provided 'as is' with no explicit or implied warranties
  15509. + * in respect of its properties, including, but not limited to, correctness
  15510. + * and/or fitness for purpose.
  15511. + */
  15512. +
  15513. +#ifndef AUTOCONF_INCLUDED
  15514. +#include <linux/config.h>
  15515. +#endif
  15516. +#include <linux/module.h>
  15517. +#include <linux/init.h>
  15518. +#include <linux/list.h>
  15519. +#include <linux/slab.h>
  15520. +#include <linux/sched.h>
  15521. +#include <linux/wait.h>
  15522. +#include <linux/crypto.h>
  15523. +#include <linux/interrupt.h>
  15524. +
  15525. +#include <cryptodev.h>
  15526. +#include <uio.h>
  15527. +
  15528. +static int32_t null_id = -1;
  15529. +static u_int32_t null_sesnum = 0;
  15530. +
  15531. +static int null_process(device_t, struct cryptop *, int);
  15532. +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
  15533. +static int null_freesession(device_t, u_int64_t);
  15534. +
  15535. +#define debug ocfnull_debug
  15536. +int ocfnull_debug = 0;
  15537. +module_param(ocfnull_debug, int, 0644);
  15538. +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
  15539. +
  15540. +/*
  15541. + * dummy device structure
  15542. + */
  15543. +
  15544. +static struct {
  15545. + softc_device_decl sc_dev;
  15546. +} nulldev;
  15547. +
  15548. +static device_method_t null_methods = {
  15549. + /* crypto device methods */
  15550. + DEVMETHOD(cryptodev_newsession, null_newsession),
  15551. + DEVMETHOD(cryptodev_freesession,null_freesession),
  15552. + DEVMETHOD(cryptodev_process, null_process),
  15553. +};
  15554. +
  15555. +/*
  15556. + * Generate a new software session.
  15557. + */
  15558. +static int
  15559. +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
  15560. +{
  15561. + dprintk("%s()\n", __FUNCTION__);
  15562. + if (sid == NULL || cri == NULL) {
  15563. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  15564. + return EINVAL;
  15565. + }
  15566. +
  15567. + if (null_sesnum == 0)
  15568. + null_sesnum++;
  15569. + *sid = null_sesnum++;
  15570. + return 0;
  15571. +}
  15572. +
  15573. +
  15574. +/*
  15575. + * Free a session.
  15576. + */
  15577. +static int
  15578. +null_freesession(device_t arg, u_int64_t tid)
  15579. +{
  15580. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  15581. +
  15582. + dprintk("%s()\n", __FUNCTION__);
  15583. + if (sid > null_sesnum) {
  15584. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  15585. + return EINVAL;
  15586. + }
  15587. +
  15588. + /* Silently accept and return */
  15589. + if (sid == 0)
  15590. + return 0;
  15591. + return 0;
  15592. +}
  15593. +
  15594. +
  15595. +/*
  15596. + * Process a request.
  15597. + */
  15598. +static int
  15599. +null_process(device_t arg, struct cryptop *crp, int hint)
  15600. +{
  15601. + unsigned int lid;
  15602. +
  15603. + dprintk("%s()\n", __FUNCTION__);
  15604. +
  15605. + /* Sanity check */
  15606. + if (crp == NULL) {
  15607. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  15608. + return EINVAL;
  15609. + }
  15610. +
  15611. + crp->crp_etype = 0;
  15612. +
  15613. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  15614. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  15615. + crp->crp_etype = EINVAL;
  15616. + goto done;
  15617. + }
  15618. +
  15619. + /*
  15620. + * find the session we are using
  15621. + */
  15622. +
  15623. + lid = crp->crp_sid & 0xffffffff;
  15624. + if (lid >= null_sesnum || lid == 0) {
  15625. + crp->crp_etype = ENOENT;
  15626. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  15627. + goto done;
  15628. + }
  15629. +
  15630. +done:
  15631. + crypto_done(crp);
  15632. + return 0;
  15633. +}
  15634. +
  15635. +
  15636. +/*
  15637. + * our driver startup and shutdown routines
  15638. + */
  15639. +
  15640. +static int
  15641. +null_init(void)
  15642. +{
  15643. + dprintk("%s(%p)\n", __FUNCTION__, null_init);
  15644. +
  15645. + memset(&nulldev, 0, sizeof(nulldev));
  15646. + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
  15647. +
  15648. + null_id = crypto_get_driverid(softc_get_device(&nulldev),
  15649. + CRYPTOCAP_F_HARDWARE);
  15650. + if (null_id < 0)
  15651. + panic("ocfnull: crypto device cannot initialize!");
  15652. +
  15653. +#define REGISTER(alg) \
  15654. + crypto_register(null_id,alg,0,0)
  15655. + REGISTER(CRYPTO_DES_CBC);
  15656. + REGISTER(CRYPTO_3DES_CBC);
  15657. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  15658. + REGISTER(CRYPTO_MD5);
  15659. + REGISTER(CRYPTO_SHA1);
  15660. + REGISTER(CRYPTO_MD5_HMAC);
  15661. + REGISTER(CRYPTO_SHA1_HMAC);
  15662. +#undef REGISTER
  15663. +
  15664. + return 0;
  15665. +}
  15666. +
  15667. +static void
  15668. +null_exit(void)
  15669. +{
  15670. + dprintk("%s()\n", __FUNCTION__);
  15671. + crypto_unregister_all(null_id);
  15672. + null_id = -1;
  15673. +}
  15674. +
  15675. +module_init(null_init);
  15676. +module_exit(null_exit);
  15677. +
  15678. +MODULE_LICENSE("Dual BSD/GPL");
  15679. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  15680. +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
  15681. diff -Nur linux-2.6.27.10.orig/crypto/ocf/pasemi/Makefile linux-2.6.27.10/crypto/ocf/pasemi/Makefile
  15682. --- linux-2.6.27.10.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
  15683. +++ linux-2.6.27.10/crypto/ocf/pasemi/Makefile 2008-12-23 19:31:44.000000000 +0100
  15684. @@ -0,0 +1,12 @@
  15685. +# for SGlinux builds
  15686. +-include $(ROOTDIR)/modules/.config
  15687. +
  15688. +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
  15689. +
  15690. +obj ?= .
  15691. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  15692. +
  15693. +ifdef TOPDIR
  15694. +-include $(TOPDIR)/Rules.make
  15695. +endif
  15696. +
  15697. diff -Nur linux-2.6.27.10.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.27.10/crypto/ocf/pasemi/pasemi.c
  15698. --- linux-2.6.27.10.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
  15699. +++ linux-2.6.27.10/crypto/ocf/pasemi/pasemi.c 2008-12-23 19:31:44.000000000 +0100
  15700. @@ -0,0 +1,1009 @@
  15701. +/*
  15702. + * Copyright (C) 2007 PA Semi, Inc
  15703. + *
  15704. + * Driver for the PA Semi PWRficient DMA Crypto Engine
  15705. + *
  15706. + * This program is free software; you can redistribute it and/or modify
  15707. + * it under the terms of the GNU General Public License version 2 as
  15708. + * published by the Free Software Foundation.
  15709. + *
  15710. + * This program is distributed in the hope that it will be useful,
  15711. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15712. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15713. + * GNU General Public License for more details.
  15714. + *
  15715. + * You should have received a copy of the GNU General Public License
  15716. + * along with this program; if not, write to the Free Software
  15717. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15718. + */
  15719. +
  15720. +#ifndef AUTOCONF_INCLUDED
  15721. +#include <linux/config.h>
  15722. +#endif
  15723. +#include <linux/module.h>
  15724. +#include <linux/init.h>
  15725. +#include <linux/interrupt.h>
  15726. +#include <linux/timer.h>
  15727. +#include <linux/random.h>
  15728. +#include <linux/skbuff.h>
  15729. +#include <asm/scatterlist.h>
  15730. +#include <linux/moduleparam.h>
  15731. +#include <linux/pci.h>
  15732. +#include <cryptodev.h>
  15733. +#include <uio.h>
  15734. +#include "pasemi_fnu.h"
  15735. +
  15736. +#define DRV_NAME "pasemi"
  15737. +
  15738. +#define TIMER_INTERVAL 1000
  15739. +
  15740. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
  15741. +static struct pasdma_status volatile * dma_status;
  15742. +
  15743. +static int debug;
  15744. +module_param(debug, int, 0644);
  15745. +MODULE_PARM_DESC(debug, "Enable debug");
  15746. +
  15747. +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
  15748. +{
  15749. + desc->postop = 0;
  15750. + desc->quad[0] = hdr;
  15751. + desc->quad_cnt = 1;
  15752. + desc->size = 1;
  15753. +}
  15754. +
  15755. +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
  15756. +{
  15757. + desc->quad[desc->quad_cnt++] = val;
  15758. + desc->size = (desc->quad_cnt + 1) / 2;
  15759. +}
  15760. +
  15761. +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
  15762. +{
  15763. + desc->quad[0] |= hdr;
  15764. +}
  15765. +
  15766. +static int pasemi_desc_size(struct pasemi_desc *desc)
  15767. +{
  15768. + return desc->size;
  15769. +}
  15770. +
  15771. +static void pasemi_ring_add_desc(
  15772. + struct pasemi_fnu_txring *ring,
  15773. + struct pasemi_desc *desc,
  15774. + struct cryptop *crp) {
  15775. + int i;
  15776. + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  15777. +
  15778. + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
  15779. + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
  15780. + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
  15781. +
  15782. + for (i = 0; i < desc->quad_cnt; i += 2) {
  15783. + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  15784. + ring->desc[ring_index] = desc->quad[i];
  15785. + ring->desc[ring_index + 1] = desc->quad[i + 1];
  15786. + ring->next_to_fill++;
  15787. + }
  15788. +
  15789. + if (desc->quad_cnt & 1)
  15790. + ring->desc[ring_index + 1] = 0;
  15791. +}
  15792. +
  15793. +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
  15794. +{
  15795. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
  15796. + incr);
  15797. +}
  15798. +
  15799. +/*
  15800. + * Generate a new software session.
  15801. + */
  15802. +static int
  15803. +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  15804. +{
  15805. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  15806. + struct pasemi_softc *sc = device_get_softc(dev);
  15807. + struct pasemi_session *ses = NULL, **sespp;
  15808. + int sesn, blksz = 0;
  15809. + u64 ccmd = 0;
  15810. + unsigned long flags;
  15811. + struct pasemi_desc init_desc;
  15812. + struct pasemi_fnu_txring *txring;
  15813. +
  15814. + DPRINTF("%s()\n", __FUNCTION__);
  15815. + if (sidp == NULL || cri == NULL || sc == NULL) {
  15816. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  15817. + return -EINVAL;
  15818. + }
  15819. + for (c = cri; c != NULL; c = c->cri_next) {
  15820. + if (ALG_IS_SIG(c->cri_alg)) {
  15821. + if (macini)
  15822. + return -EINVAL;
  15823. + macini = c;
  15824. + } else if (ALG_IS_CIPHER(c->cri_alg)) {
  15825. + if (encini)
  15826. + return -EINVAL;
  15827. + encini = c;
  15828. + } else {
  15829. + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
  15830. + return -EINVAL;
  15831. + }
  15832. + }
  15833. + if (encini == NULL && macini == NULL)
  15834. + return -EINVAL;
  15835. + if (encini) {
  15836. + /* validate key length */
  15837. + switch (encini->cri_alg) {
  15838. + case CRYPTO_DES_CBC:
  15839. + if (encini->cri_klen != 64)
  15840. + return -EINVAL;
  15841. + ccmd = DMA_CALGO_DES;
  15842. + break;
  15843. + case CRYPTO_3DES_CBC:
  15844. + if (encini->cri_klen != 192)
  15845. + return -EINVAL;
  15846. + ccmd = DMA_CALGO_3DES;
  15847. + break;
  15848. + case CRYPTO_AES_CBC:
  15849. + if (encini->cri_klen != 128 &&
  15850. + encini->cri_klen != 192 &&
  15851. + encini->cri_klen != 256)
  15852. + return -EINVAL;
  15853. + ccmd = DMA_CALGO_AES;
  15854. + break;
  15855. + case CRYPTO_ARC4:
  15856. + if (encini->cri_klen != 128)
  15857. + return -EINVAL;
  15858. + ccmd = DMA_CALGO_ARC;
  15859. + break;
  15860. + default:
  15861. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  15862. + encini->cri_alg);
  15863. + return -EINVAL;
  15864. + }
  15865. + }
  15866. +
  15867. + if (macini) {
  15868. + switch (macini->cri_alg) {
  15869. + case CRYPTO_MD5:
  15870. + case CRYPTO_MD5_HMAC:
  15871. + blksz = 16;
  15872. + break;
  15873. + case CRYPTO_SHA1:
  15874. + case CRYPTO_SHA1_HMAC:
  15875. + blksz = 20;
  15876. + break;
  15877. + default:
  15878. + DPRINTF("UNKNOWN macini->cri_alg %d\n",
  15879. + macini->cri_alg);
  15880. + return -EINVAL;
  15881. + }
  15882. + if (((macini->cri_klen + 7) / 8) > blksz) {
  15883. + DPRINTF("key length %d bigger than blksize %d not supported\n",
  15884. + ((macini->cri_klen + 7) / 8), blksz);
  15885. + return -EINVAL;
  15886. + }
  15887. + }
  15888. +
  15889. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  15890. + if (sc->sc_sessions[sesn] == NULL) {
  15891. + sc->sc_sessions[sesn] = (struct pasemi_session *)
  15892. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  15893. + ses = sc->sc_sessions[sesn];
  15894. + break;
  15895. + } else if (sc->sc_sessions[sesn]->used == 0) {
  15896. + ses = sc->sc_sessions[sesn];
  15897. + break;
  15898. + }
  15899. + }
  15900. +
  15901. + if (ses == NULL) {
  15902. + sespp = (struct pasemi_session **)
  15903. + kzalloc(sc->sc_nsessions * 2 *
  15904. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  15905. + if (sespp == NULL)
  15906. + return -ENOMEM;
  15907. + memcpy(sespp, sc->sc_sessions,
  15908. + sc->sc_nsessions * sizeof(struct pasemi_session *));
  15909. + kfree(sc->sc_sessions);
  15910. + sc->sc_sessions = sespp;
  15911. + sesn = sc->sc_nsessions;
  15912. + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
  15913. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  15914. + if (ses == NULL)
  15915. + return -ENOMEM;
  15916. + sc->sc_nsessions *= 2;
  15917. + }
  15918. +
  15919. + ses->used = 1;
  15920. +
  15921. + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
  15922. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  15923. +
  15924. + /* enter the channel scheduler */
  15925. + spin_lock_irqsave(&sc->sc_chnlock, flags);
  15926. +
  15927. + /* ARC4 has to be processed by the even channel */
  15928. + if (encini && (encini->cri_alg == CRYPTO_ARC4))
  15929. + ses->chan = sc->sc_lastchn & ~1;
  15930. + else
  15931. + ses->chan = sc->sc_lastchn;
  15932. + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
  15933. +
  15934. + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
  15935. +
  15936. + txring = &sc->tx[ses->chan];
  15937. +
  15938. + if (encini) {
  15939. + ses->ccmd = ccmd;
  15940. +
  15941. + /* get an IV */
  15942. + /* XXX may read fewer than requested */
  15943. + get_random_bytes(ses->civ, sizeof(ses->civ));
  15944. +
  15945. + ses->keysz = (encini->cri_klen - 63) / 64;
  15946. + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
  15947. +
  15948. + pasemi_desc_start(&init_desc,
  15949. + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
  15950. + pasemi_desc_build(&init_desc,
  15951. + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
  15952. + }
  15953. + if (macini) {
  15954. + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
  15955. + macini->cri_alg == CRYPTO_SHA1_HMAC)
  15956. + memcpy(ses->hkey, macini->cri_key, blksz);
  15957. + else {
  15958. + /* Load initialization constants(RFC 1321, 3174) */
  15959. + ses->hiv[0] = 0x67452301efcdab89ULL;
  15960. + ses->hiv[1] = 0x98badcfe10325476ULL;
  15961. + ses->hiv[2] = 0xc3d2e1f000000000ULL;
  15962. + }
  15963. + ses->hseq = 0ULL;
  15964. + }
  15965. +
  15966. + spin_lock_irqsave(&txring->fill_lock, flags);
  15967. +
  15968. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
  15969. + txring->next_to_clean) > TX_RING_SIZE) {
  15970. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  15971. + return ERESTART;
  15972. + }
  15973. +
  15974. + if (encini) {
  15975. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  15976. + pasemi_ring_incr(sc, ses->chan,
  15977. + pasemi_desc_size(&init_desc));
  15978. + }
  15979. +
  15980. + txring->sesn = sesn;
  15981. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  15982. +
  15983. + *sidp = PASEMI_SID(sesn);
  15984. + return 0;
  15985. +}
  15986. +
  15987. +/*
  15988. + * Deallocate a session.
  15989. + */
  15990. +static int
  15991. +pasemi_freesession(device_t dev, u_int64_t tid)
  15992. +{
  15993. + struct pasemi_softc *sc = device_get_softc(dev);
  15994. + int session;
  15995. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  15996. +
  15997. + DPRINTF("%s()\n", __FUNCTION__);
  15998. +
  15999. + if (sc == NULL)
  16000. + return -EINVAL;
  16001. + session = PASEMI_SESSION(sid);
  16002. + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
  16003. + return -EINVAL;
  16004. +
  16005. + pci_unmap_single(sc->dma_pdev,
  16006. + sc->sc_sessions[session]->dma_addr,
  16007. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  16008. + memset(sc->sc_sessions[session], 0,
  16009. + sizeof(struct pasemi_session));
  16010. +
  16011. + return 0;
  16012. +}
  16013. +
  16014. +static int
  16015. +pasemi_process(device_t dev, struct cryptop *crp, int hint)
  16016. +{
  16017. +
  16018. + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
  16019. + struct pasemi_softc *sc = device_get_softc(dev);
  16020. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  16021. + caddr_t ivp;
  16022. + struct pasemi_desc init_desc, work_desc;
  16023. + struct pasemi_session *ses;
  16024. + struct sk_buff *skb;
  16025. + struct uio *uiop;
  16026. + unsigned long flags;
  16027. + struct pasemi_fnu_txring *txring;
  16028. +
  16029. + DPRINTF("%s()\n", __FUNCTION__);
  16030. +
  16031. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
  16032. + return -EINVAL;
  16033. +
  16034. + crp->crp_etype = 0;
  16035. + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
  16036. + return -EINVAL;
  16037. +
  16038. + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
  16039. +
  16040. + crd1 = crp->crp_desc;
  16041. + if (crd1 == NULL) {
  16042. + err = -EINVAL;
  16043. + goto errout;
  16044. + }
  16045. + crd2 = crd1->crd_next;
  16046. +
  16047. + if (ALG_IS_SIG(crd1->crd_alg)) {
  16048. + maccrd = crd1;
  16049. + if (crd2 == NULL)
  16050. + enccrd = NULL;
  16051. + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
  16052. + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
  16053. + enccrd = crd2;
  16054. + else
  16055. + goto erralg;
  16056. + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
  16057. + enccrd = crd1;
  16058. + if (crd2 == NULL)
  16059. + maccrd = NULL;
  16060. + else if (ALG_IS_SIG(crd2->crd_alg) &&
  16061. + (crd1->crd_flags & CRD_F_ENCRYPT))
  16062. + maccrd = crd2;
  16063. + else
  16064. + goto erralg;
  16065. + } else
  16066. + goto erralg;
  16067. +
  16068. + chsel = ses->chan;
  16069. +
  16070. + txring = &sc->tx[chsel];
  16071. +
  16072. + if (enccrd && !maccrd) {
  16073. + if (enccrd->crd_alg == CRYPTO_ARC4)
  16074. + reinit = 1;
  16075. + reinit_size = 0x40;
  16076. + srclen = crp->crp_ilen;
  16077. +
  16078. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
  16079. + | XCT_FUN_FUN(chsel));
  16080. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  16081. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
  16082. + else
  16083. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
  16084. + } else if (enccrd && maccrd) {
  16085. + if (enccrd->crd_alg == CRYPTO_ARC4)
  16086. + reinit = 1;
  16087. + reinit_size = 0x68;
  16088. +
  16089. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  16090. + /* Encrypt -> Authenticate */
  16091. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
  16092. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  16093. + srclen = maccrd->crd_skip + maccrd->crd_len;
  16094. + } else {
  16095. + /* Authenticate -> Decrypt */
  16096. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
  16097. + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
  16098. + pasemi_desc_build(&work_desc, 0);
  16099. + pasemi_desc_build(&work_desc, 0);
  16100. + pasemi_desc_build(&work_desc, 0);
  16101. + work_desc.postop = PASEMI_CHECK_SIG;
  16102. + srclen = crp->crp_ilen;
  16103. + }
  16104. +
  16105. + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
  16106. + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
  16107. + } else if (!enccrd && maccrd) {
  16108. + srclen = maccrd->crd_len;
  16109. +
  16110. + pasemi_desc_start(&init_desc,
  16111. + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
  16112. + pasemi_desc_build(&init_desc,
  16113. + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
  16114. +
  16115. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
  16116. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  16117. + }
  16118. +
  16119. + if (enccrd) {
  16120. + switch (enccrd->crd_alg) {
  16121. + case CRYPTO_3DES_CBC:
  16122. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
  16123. + XCT_FUN_BCM_CBC);
  16124. + ivsize = sizeof(u64);
  16125. + break;
  16126. + case CRYPTO_DES_CBC:
  16127. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
  16128. + XCT_FUN_BCM_CBC);
  16129. + ivsize = sizeof(u64);
  16130. + break;
  16131. + case CRYPTO_AES_CBC:
  16132. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
  16133. + XCT_FUN_BCM_CBC);
  16134. + ivsize = 2 * sizeof(u64);
  16135. + break;
  16136. + case CRYPTO_ARC4:
  16137. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
  16138. + ivsize = 0;
  16139. + break;
  16140. + default:
  16141. + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
  16142. + enccrd->crd_alg);
  16143. + err = -EINVAL;
  16144. + goto errout;
  16145. + }
  16146. +
  16147. + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
  16148. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  16149. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16150. + memcpy(ivp, enccrd->crd_iv, ivsize);
  16151. + /* If IV is not present in the buffer already, it has to be copied there */
  16152. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
  16153. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  16154. + enccrd->crd_inject, ivsize, ivp);
  16155. + } else {
  16156. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16157. + /* IV is provided expicitly in descriptor */
  16158. + memcpy(ivp, enccrd->crd_iv, ivsize);
  16159. + else
  16160. + /* IV is provided in the packet */
  16161. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  16162. + enccrd->crd_inject, ivsize,
  16163. + ivp);
  16164. + }
  16165. + }
  16166. +
  16167. + if (maccrd) {
  16168. + switch (maccrd->crd_alg) {
  16169. + case CRYPTO_MD5:
  16170. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
  16171. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16172. + break;
  16173. + case CRYPTO_SHA1:
  16174. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
  16175. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16176. + break;
  16177. + case CRYPTO_MD5_HMAC:
  16178. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
  16179. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16180. + break;
  16181. + case CRYPTO_SHA1_HMAC:
  16182. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
  16183. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16184. + break;
  16185. + default:
  16186. + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
  16187. + maccrd->crd_alg);
  16188. + err = -EINVAL;
  16189. + goto errout;
  16190. + }
  16191. + }
  16192. +
  16193. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  16194. + /* using SKB buffers */
  16195. + skb = (struct sk_buff *)crp->crp_buf;
  16196. + if (skb_shinfo(skb)->nr_frags) {
  16197. + printk(DRV_NAME ": skb frags unimplemented\n");
  16198. + err = -EINVAL;
  16199. + goto errout;
  16200. + }
  16201. + pasemi_desc_build(
  16202. + &work_desc,
  16203. + XCT_FUN_DST_PTR(skb->len, pci_map_single(
  16204. + sc->dma_pdev, skb->data,
  16205. + skb->len, DMA_TO_DEVICE)));
  16206. + pasemi_desc_build(
  16207. + &work_desc,
  16208. + XCT_FUN_SRC_PTR(
  16209. + srclen, pci_map_single(
  16210. + sc->dma_pdev, skb->data,
  16211. + srclen, DMA_TO_DEVICE)));
  16212. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  16213. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  16214. + /* using IOV buffers */
  16215. + uiop = (struct uio *)crp->crp_buf;
  16216. + if (uiop->uio_iovcnt > 1) {
  16217. + printk(DRV_NAME ": iov frags unimplemented\n");
  16218. + err = -EINVAL;
  16219. + goto errout;
  16220. + }
  16221. +
  16222. + /* crp_olen is never set; always use crp_ilen */
  16223. + pasemi_desc_build(
  16224. + &work_desc,
  16225. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  16226. + sc->dma_pdev,
  16227. + uiop->uio_iov->iov_base,
  16228. + crp->crp_ilen, DMA_TO_DEVICE)));
  16229. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  16230. +
  16231. + pasemi_desc_build(
  16232. + &work_desc,
  16233. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  16234. + sc->dma_pdev,
  16235. + uiop->uio_iov->iov_base,
  16236. + srclen, DMA_TO_DEVICE)));
  16237. + } else {
  16238. + /* using contig buffers */
  16239. + pasemi_desc_build(
  16240. + &work_desc,
  16241. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  16242. + sc->dma_pdev,
  16243. + crp->crp_buf,
  16244. + crp->crp_ilen, DMA_TO_DEVICE)));
  16245. + pasemi_desc_build(
  16246. + &work_desc,
  16247. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  16248. + sc->dma_pdev,
  16249. + crp->crp_buf, srclen,
  16250. + DMA_TO_DEVICE)));
  16251. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  16252. + }
  16253. +
  16254. + spin_lock_irqsave(&txring->fill_lock, flags);
  16255. +
  16256. + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
  16257. + txring->sesn = PASEMI_SESSION(crp->crp_sid);
  16258. + reinit = 1;
  16259. + }
  16260. +
  16261. + if (enccrd) {
  16262. + pasemi_desc_start(&init_desc,
  16263. + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
  16264. + pasemi_desc_build(&init_desc,
  16265. + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
  16266. + }
  16267. +
  16268. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
  16269. + pasemi_desc_size(&work_desc)) -
  16270. + txring->next_to_clean) > TX_RING_SIZE) {
  16271. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  16272. + err = ERESTART;
  16273. + goto errout;
  16274. + }
  16275. +
  16276. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  16277. + pasemi_ring_add_desc(txring, &work_desc, crp);
  16278. +
  16279. + pasemi_ring_incr(sc, chsel,
  16280. + pasemi_desc_size(&init_desc) +
  16281. + pasemi_desc_size(&work_desc));
  16282. +
  16283. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  16284. +
  16285. + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
  16286. +
  16287. + return 0;
  16288. +
  16289. +erralg:
  16290. + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
  16291. + crd1->crd_alg, crd2->crd_alg);
  16292. + err = -EINVAL;
  16293. +
  16294. +errout:
  16295. + if (err != ERESTART) {
  16296. + crp->crp_etype = err;
  16297. + crypto_done(crp);
  16298. + }
  16299. + return err;
  16300. +}
  16301. +
  16302. +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
  16303. +{
  16304. + int i, j, ring_idx;
  16305. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  16306. + u16 delta_cnt;
  16307. + int flags, loops = 10;
  16308. + int desc_size;
  16309. + struct cryptop *crp;
  16310. +
  16311. + spin_lock_irqsave(&ring->clean_lock, flags);
  16312. +
  16313. + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
  16314. + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
  16315. + && loops--) {
  16316. +
  16317. + for (i = 0; i < delta_cnt; i++) {
  16318. + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
  16319. + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
  16320. + if (crp) {
  16321. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  16322. + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
  16323. + /* Need to make sure signature matched,
  16324. + * if not - return error */
  16325. + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
  16326. + crp->crp_etype = -EINVAL;
  16327. + }
  16328. + crypto_done(TX_DESC_INFO(ring,
  16329. + ring->next_to_clean).cf_crp);
  16330. + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
  16331. + pci_unmap_single(
  16332. + sc->dma_pdev,
  16333. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
  16334. + PCI_DMA_TODEVICE);
  16335. +
  16336. + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
  16337. +
  16338. + ring->next_to_clean++;
  16339. + for (j = 1; j < desc_size; j++) {
  16340. + ring_idx = 2 *
  16341. + (ring->next_to_clean &
  16342. + (TX_RING_SIZE-1));
  16343. + pci_unmap_single(
  16344. + sc->dma_pdev,
  16345. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
  16346. + PCI_DMA_TODEVICE);
  16347. + if (ring->desc[ring_idx + 1])
  16348. + pci_unmap_single(
  16349. + sc->dma_pdev,
  16350. + XCT_PTR_ADDR_LEN(
  16351. + ring->desc[
  16352. + ring_idx + 1]),
  16353. + PCI_DMA_TODEVICE);
  16354. + ring->desc[ring_idx] =
  16355. + ring->desc[ring_idx + 1] = 0;
  16356. + ring->next_to_clean++;
  16357. + }
  16358. + } else {
  16359. + for (j = 0; j < desc_size; j++) {
  16360. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  16361. + ring->desc[ring_idx] =
  16362. + ring->desc[ring_idx + 1] = 0;
  16363. + ring->next_to_clean++;
  16364. + }
  16365. + }
  16366. + }
  16367. +
  16368. + ring->total_pktcnt += delta_cnt;
  16369. + }
  16370. + spin_unlock_irqrestore(&ring->clean_lock, flags);
  16371. +
  16372. + return 0;
  16373. +}
  16374. +
  16375. +static void sweepup_tx(struct pasemi_softc *sc)
  16376. +{
  16377. + int i;
  16378. +
  16379. + for (i = 0; i < sc->sc_num_channels; i++)
  16380. + pasemi_clean_tx(sc, i);
  16381. +}
  16382. +
  16383. +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
  16384. +{
  16385. + struct pasemi_softc *sc = arg;
  16386. + unsigned int reg;
  16387. + int chan = irq - sc->base_irq;
  16388. + int chan_index = sc->base_chan + chan;
  16389. + u64 stat = dma_status->tx_sta[chan_index];
  16390. +
  16391. + DPRINTF("%s()\n", __FUNCTION__);
  16392. +
  16393. + if (!(stat & PAS_STATUS_CAUSE_M))
  16394. + return IRQ_NONE;
  16395. +
  16396. + pasemi_clean_tx(sc, chan);
  16397. +
  16398. + stat = dma_status->tx_sta[chan_index];
  16399. +
  16400. + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
  16401. + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
  16402. +
  16403. + if (stat & PAS_STATUS_SOFT)
  16404. + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
  16405. +
  16406. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
  16407. +
  16408. +
  16409. + return IRQ_HANDLED;
  16410. +}
  16411. +
  16412. +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
  16413. +{
  16414. + u32 val;
  16415. + int chan_index = chan + sc->base_chan;
  16416. + int ret;
  16417. + struct pasemi_fnu_txring *ring;
  16418. +
  16419. + ring = &sc->tx[chan];
  16420. +
  16421. + spin_lock_init(&ring->fill_lock);
  16422. + spin_lock_init(&ring->clean_lock);
  16423. +
  16424. + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
  16425. + TX_RING_SIZE, GFP_KERNEL);
  16426. + if (!ring->desc_info)
  16427. + return -ENOMEM;
  16428. +
  16429. + /* Allocate descriptors */
  16430. + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
  16431. + TX_RING_SIZE *
  16432. + 2 * sizeof(u64),
  16433. + &ring->dma, GFP_KERNEL);
  16434. + if (!ring->desc)
  16435. + return -ENOMEM;
  16436. +
  16437. + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
  16438. +
  16439. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
  16440. +
  16441. + ring->total_pktcnt = 0;
  16442. +
  16443. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
  16444. + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
  16445. +
  16446. + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
  16447. + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
  16448. +
  16449. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
  16450. +
  16451. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
  16452. + PAS_DMA_TXCHAN_CFG_TY_FUNC |
  16453. + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
  16454. + PAS_DMA_TXCHAN_CFG_WT(2));
  16455. +
  16456. + /* enable tx channel */
  16457. + out_le32(sc->dma_regs +
  16458. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  16459. + PAS_DMA_TXCHAN_TCMDSTA_EN);
  16460. +
  16461. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
  16462. + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
  16463. +
  16464. + ring->next_to_fill = 0;
  16465. + ring->next_to_clean = 0;
  16466. +
  16467. + snprintf(ring->irq_name, sizeof(ring->irq_name),
  16468. + "%s%d", "crypto", chan);
  16469. +
  16470. + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
  16471. + ret = request_irq(ring->irq, (irq_handler_t)
  16472. + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
  16473. + if (ret) {
  16474. + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
  16475. + ring->irq, ret);
  16476. + ring->irq = -1;
  16477. + return ret;
  16478. + }
  16479. +
  16480. + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
  16481. +
  16482. + return 0;
  16483. +}
  16484. +
  16485. +static device_method_t pasemi_methods = {
  16486. + /* crypto device methods */
  16487. + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
  16488. + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
  16489. + DEVMETHOD(cryptodev_process, pasemi_process),
  16490. +};
  16491. +
  16492. +/* Set up the crypto device structure, private data,
  16493. + * and anything else we need before we start */
  16494. +
  16495. +static int __devinit
  16496. +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  16497. +{
  16498. + struct pasemi_softc *sc;
  16499. + int ret, i;
  16500. +
  16501. + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
  16502. +
  16503. + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
  16504. + if (!sc)
  16505. + return -ENOMEM;
  16506. +
  16507. + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
  16508. +
  16509. + pci_set_drvdata(pdev, sc);
  16510. +
  16511. + spin_lock_init(&sc->sc_chnlock);
  16512. +
  16513. + sc->sc_sessions = (struct pasemi_session **)
  16514. + kzalloc(PASEMI_INITIAL_SESSIONS *
  16515. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  16516. + if (sc->sc_sessions == NULL) {
  16517. + ret = -ENOMEM;
  16518. + goto out;
  16519. + }
  16520. +
  16521. + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
  16522. + sc->sc_lastchn = 0;
  16523. + sc->base_irq = pdev->irq + 6;
  16524. + sc->base_chan = 6;
  16525. + sc->sc_cid = -1;
  16526. + sc->dma_pdev = pdev;
  16527. +
  16528. + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
  16529. + if (!sc->iob_pdev) {
  16530. + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
  16531. + ret = -ENODEV;
  16532. + goto out;
  16533. + }
  16534. +
  16535. + /* This is hardcoded and ugly, but we have some firmware versions
  16536. + * who don't provide the register space in the device tree. Luckily
  16537. + * they are at well-known locations so we can just do the math here.
  16538. + */
  16539. + sc->dma_regs =
  16540. + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
  16541. + sc->iob_regs =
  16542. + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
  16543. + if (!sc->dma_regs || !sc->iob_regs) {
  16544. + dev_err(&pdev->dev, "Can't map registers\n");
  16545. + ret = -ENODEV;
  16546. + goto out;
  16547. + }
  16548. +
  16549. + dma_status = __ioremap(0xfd800000, 0x1000, 0);
  16550. + if (!dma_status) {
  16551. + ret = -ENODEV;
  16552. + dev_err(&pdev->dev, "Can't map dmastatus space\n");
  16553. + goto out;
  16554. + }
  16555. +
  16556. + sc->tx = (struct pasemi_fnu_txring *)
  16557. + kzalloc(sizeof(struct pasemi_fnu_txring)
  16558. + * 8, GFP_KERNEL);
  16559. + if (!sc->tx) {
  16560. + ret = -ENOMEM;
  16561. + goto out;
  16562. + }
  16563. +
  16564. + /* Initialize the h/w */
  16565. + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
  16566. + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
  16567. + PAS_DMA_COM_CFG_FWF));
  16568. + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
  16569. +
  16570. + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
  16571. + sc->sc_num_channels++;
  16572. + ret = pasemi_dma_setup_tx_resources(sc, i);
  16573. + if (ret)
  16574. + goto out;
  16575. + }
  16576. +
  16577. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
  16578. + CRYPTOCAP_F_HARDWARE);
  16579. + if (sc->sc_cid < 0) {
  16580. + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
  16581. + ret = -ENXIO;
  16582. + goto out;
  16583. + }
  16584. +
  16585. + /* register algorithms with the framework */
  16586. + printk(DRV_NAME ":");
  16587. +
  16588. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  16589. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  16590. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  16591. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  16592. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  16593. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  16594. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  16595. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  16596. +
  16597. + return 0;
  16598. +
  16599. +out:
  16600. + pasemi_dma_remove(pdev);
  16601. + return ret;
  16602. +}
  16603. +
  16604. +#define MAX_RETRIES 5000
  16605. +
  16606. +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
  16607. +{
  16608. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  16609. + int chan_index = chan + sc->base_chan;
  16610. + int retries;
  16611. + u32 stat;
  16612. +
  16613. + /* Stop the channel */
  16614. + out_le32(sc->dma_regs +
  16615. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  16616. + PAS_DMA_TXCHAN_TCMDSTA_ST);
  16617. +
  16618. + for (retries = 0; retries < MAX_RETRIES; retries++) {
  16619. + stat = in_le32(sc->dma_regs +
  16620. + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
  16621. + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
  16622. + break;
  16623. + cond_resched();
  16624. + }
  16625. +
  16626. + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
  16627. + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
  16628. + chan_index);
  16629. +
  16630. + /* Disable the channel */
  16631. + out_le32(sc->dma_regs +
  16632. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  16633. + 0);
  16634. +
  16635. + if (ring->desc_info)
  16636. + kfree((void *) ring->desc_info);
  16637. + if (ring->desc)
  16638. + dma_free_coherent(&sc->dma_pdev->dev,
  16639. + TX_RING_SIZE *
  16640. + 2 * sizeof(u64),
  16641. + (void *) ring->desc, ring->dma);
  16642. + if (ring->irq != -1)
  16643. + free_irq(ring->irq, sc);
  16644. +
  16645. + del_timer(&ring->crypto_timer);
  16646. +}
  16647. +
  16648. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
  16649. +{
  16650. + struct pasemi_softc *sc = pci_get_drvdata(pdev);
  16651. + int i;
  16652. +
  16653. + DPRINTF("%s()\n", __FUNCTION__);
  16654. +
  16655. + if (sc->sc_cid >= 0) {
  16656. + crypto_unregister_all(sc->sc_cid);
  16657. + }
  16658. +
  16659. + if (sc->tx) {
  16660. + for (i = 0; i < sc->sc_num_channels; i++)
  16661. + pasemi_free_tx_resources(sc, i);
  16662. +
  16663. + kfree(sc->tx);
  16664. + }
  16665. + if (sc->sc_sessions) {
  16666. + for (i = 0; i < sc->sc_nsessions; i++)
  16667. + kfree(sc->sc_sessions[i]);
  16668. + kfree(sc->sc_sessions);
  16669. + }
  16670. + if (sc->iob_pdev)
  16671. + pci_dev_put(sc->iob_pdev);
  16672. + if (sc->dma_regs)
  16673. + iounmap(sc->dma_regs);
  16674. + if (sc->iob_regs)
  16675. + iounmap(sc->iob_regs);
  16676. + kfree(sc);
  16677. +}
  16678. +
  16679. +static struct pci_device_id pasemi_dma_pci_tbl[] = {
  16680. + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
  16681. +};
  16682. +
  16683. +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
  16684. +
  16685. +static struct pci_driver pasemi_dma_driver = {
  16686. + .name = "pasemi_dma",
  16687. + .id_table = pasemi_dma_pci_tbl,
  16688. + .probe = pasemi_dma_probe,
  16689. + .remove = __devexit_p(pasemi_dma_remove),
  16690. +};
  16691. +
  16692. +static void __exit pasemi_dma_cleanup_module(void)
  16693. +{
  16694. + pci_unregister_driver(&pasemi_dma_driver);
  16695. + __iounmap(dma_status);
  16696. + dma_status = NULL;
  16697. +}
  16698. +
  16699. +int pasemi_dma_init_module(void)
  16700. +{
  16701. + return pci_register_driver(&pasemi_dma_driver);
  16702. +}
  16703. +
  16704. +module_init(pasemi_dma_init_module);
  16705. +module_exit(pasemi_dma_cleanup_module);
  16706. +
  16707. +MODULE_LICENSE("Dual BSD/GPL");
  16708. +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
  16709. +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
  16710. diff -Nur linux-2.6.27.10.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.27.10/crypto/ocf/pasemi/pasemi_fnu.h
  16711. --- linux-2.6.27.10.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
  16712. +++ linux-2.6.27.10/crypto/ocf/pasemi/pasemi_fnu.h 2008-12-23 19:31:44.000000000 +0100
  16713. @@ -0,0 +1,410 @@
  16714. +/*
  16715. + * Copyright (C) 2007 PA Semi, Inc
  16716. + *
  16717. + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
  16718. + * hardware register layouts.
  16719. + *
  16720. + * This program is free software; you can redistribute it and/or modify
  16721. + * it under the terms of the GNU General Public License version 2 as
  16722. + * published by the Free Software Foundation.
  16723. + *
  16724. + * This program is distributed in the hope that it will be useful,
  16725. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16726. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16727. + * GNU General Public License for more details.
  16728. + *
  16729. + * You should have received a copy of the GNU General Public License
  16730. + * along with this program; if not, write to the Free Software
  16731. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16732. + */
  16733. +
  16734. +#ifndef PASEMI_FNU_H
  16735. +#define PASEMI_FNU_H
  16736. +
  16737. +#include <linux/spinlock.h>
  16738. +
  16739. +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
  16740. +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
  16741. +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
  16742. +
  16743. +/* Must be a power of two */
  16744. +#define RX_RING_SIZE 512
  16745. +#define TX_RING_SIZE 512
  16746. +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
  16747. +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
  16748. +#define MAX_DESC_SIZE 8
  16749. +#define PASEMI_INITIAL_SESSIONS 10
  16750. +#define PASEMI_FNU_CHANNELS 8
  16751. +
  16752. +/* DMA descriptor */
  16753. +struct pasemi_desc {
  16754. + u64 quad[2*MAX_DESC_SIZE];
  16755. + int quad_cnt;
  16756. + int size;
  16757. + int postop;
  16758. +};
  16759. +
  16760. +/*
  16761. + * Holds per descriptor data
  16762. + */
  16763. +struct pasemi_desc_info {
  16764. + int desc_size;
  16765. + int desc_postop;
  16766. +#define PASEMI_CHECK_SIG 0x1
  16767. +
  16768. + struct cryptop *cf_crp;
  16769. +};
  16770. +
  16771. +/*
  16772. + * Holds per channel data
  16773. + */
  16774. +struct pasemi_fnu_txring {
  16775. + volatile u64 *desc;
  16776. + volatile struct
  16777. + pasemi_desc_info *desc_info;
  16778. + dma_addr_t dma;
  16779. + struct timer_list crypto_timer;
  16780. + spinlock_t fill_lock;
  16781. + spinlock_t clean_lock;
  16782. + unsigned int next_to_fill;
  16783. + unsigned int next_to_clean;
  16784. + u16 total_pktcnt;
  16785. + int irq;
  16786. + int sesn;
  16787. + char irq_name[10];
  16788. +};
  16789. +
  16790. +/*
  16791. + * Holds data specific to a single pasemi device.
  16792. + */
  16793. +struct pasemi_softc {
  16794. + softc_device_decl sc_cdev;
  16795. + struct pci_dev *dma_pdev; /* device backpointer */
  16796. + struct pci_dev *iob_pdev; /* device backpointer */
  16797. + void __iomem *dma_regs;
  16798. + void __iomem *iob_regs;
  16799. + int base_irq;
  16800. + int base_chan;
  16801. + int32_t sc_cid; /* crypto tag */
  16802. + int sc_nsessions;
  16803. + struct pasemi_session **sc_sessions;
  16804. + int sc_num_channels;/* number of crypto channels */
  16805. +
  16806. + /* pointer to the array of txring datastructures, one txring per channel */
  16807. + struct pasemi_fnu_txring *tx;
  16808. +
  16809. + /*
  16810. + * mutual exclusion for the channel scheduler
  16811. + */
  16812. + spinlock_t sc_chnlock;
  16813. + /* last channel used, for now use round-robin to allocate channels */
  16814. + int sc_lastchn;
  16815. +};
  16816. +
  16817. +struct pasemi_session {
  16818. + u64 civ[2];
  16819. + u64 keysz;
  16820. + u64 key[4];
  16821. + u64 ccmd;
  16822. + u64 hkey[4];
  16823. + u64 hseq;
  16824. + u64 giv[2];
  16825. + u64 hiv[4];
  16826. +
  16827. + int used;
  16828. + dma_addr_t dma_addr;
  16829. + int chan;
  16830. +};
  16831. +
  16832. +/* status register layout in IOB region, at 0xfd800000 */
  16833. +struct pasdma_status {
  16834. + u64 rx_sta[64];
  16835. + u64 tx_sta[20];
  16836. +};
  16837. +
  16838. +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
  16839. + (alg == CRYPTO_3DES_CBC) || \
  16840. + (alg == CRYPTO_AES_CBC) || \
  16841. + (alg == CRYPTO_ARC4) || \
  16842. + (alg == CRYPTO_NULL_CBC))
  16843. +
  16844. +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
  16845. + (alg == CRYPTO_MD5_HMAC) || \
  16846. + (alg == CRYPTO_SHA1) || \
  16847. + (alg == CRYPTO_SHA1_HMAC) || \
  16848. + (alg == CRYPTO_NULL_HMAC))
  16849. +
  16850. +enum {
  16851. + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
  16852. + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
  16853. + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
  16854. + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
  16855. + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
  16856. +};
  16857. +
  16858. +/* All these registers live in the PCI configuration space for the DMA PCI
  16859. + * device. Use the normal PCI config access functions for them.
  16860. + */
  16861. +
  16862. +#define PAS_DMA_COM_CFG_FWF 0x18000000
  16863. +
  16864. +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
  16865. +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
  16866. +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
  16867. +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
  16868. +
  16869. +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
  16870. +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
  16871. +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
  16872. +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
  16873. +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
  16874. +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
  16875. +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
  16876. +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
  16877. +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
  16878. +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
  16879. +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
  16880. +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
  16881. +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
  16882. +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
  16883. +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
  16884. +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
  16885. +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
  16886. +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
  16887. + PAS_DMA_TXCHAN_CFG_TATTR_M)
  16888. +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
  16889. +#define PAS_DMA_TXCHAN_CFG_WT_S 6
  16890. +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
  16891. + PAS_DMA_TXCHAN_CFG_WT_M)
  16892. +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
  16893. +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
  16894. +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
  16895. +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
  16896. +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
  16897. +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
  16898. +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
  16899. +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
  16900. +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
  16901. +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
  16902. + PAS_DMA_TXCHAN_BASEL_BRBL_M)
  16903. +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
  16904. +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
  16905. +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
  16906. +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
  16907. + PAS_DMA_TXCHAN_BASEU_BRBH_M)
  16908. +/* # of cache lines worth of buffer ring */
  16909. +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
  16910. +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
  16911. +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
  16912. + PAS_DMA_TXCHAN_BASEU_SIZ_M)
  16913. +
  16914. +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
  16915. +#define PAS_STATUS_PCNT_S 0
  16916. +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
  16917. +#define PAS_STATUS_DCNT_S 16
  16918. +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
  16919. +#define PAS_STATUS_BPCNT_S 32
  16920. +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
  16921. +#define PAS_STATUS_TIMER 0x1000000000000000ull
  16922. +#define PAS_STATUS_ERROR 0x2000000000000000ull
  16923. +#define PAS_STATUS_SOFT 0x4000000000000000ull
  16924. +#define PAS_STATUS_INT 0x8000000000000000ull
  16925. +
  16926. +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
  16927. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
  16928. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
  16929. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
  16930. + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
  16931. +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
  16932. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
  16933. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
  16934. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
  16935. + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
  16936. +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
  16937. +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
  16938. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
  16939. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
  16940. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
  16941. + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
  16942. +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
  16943. +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
  16944. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
  16945. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
  16946. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
  16947. + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
  16948. +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
  16949. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
  16950. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
  16951. +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
  16952. + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
  16953. +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
  16954. +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
  16955. +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
  16956. +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
  16957. +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
  16958. +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
  16959. +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
  16960. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
  16961. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
  16962. +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
  16963. + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
  16964. +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
  16965. +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
  16966. +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
  16967. +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
  16968. +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
  16969. +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
  16970. +
  16971. +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
  16972. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
  16973. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
  16974. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
  16975. + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
  16976. +
  16977. +/* Transmit descriptor fields */
  16978. +#define XCT_MACTX_T 0x8000000000000000ull
  16979. +#define XCT_MACTX_ST 0x4000000000000000ull
  16980. +#define XCT_MACTX_NORES 0x0000000000000000ull
  16981. +#define XCT_MACTX_8BRES 0x1000000000000000ull
  16982. +#define XCT_MACTX_24BRES 0x2000000000000000ull
  16983. +#define XCT_MACTX_40BRES 0x3000000000000000ull
  16984. +#define XCT_MACTX_I 0x0800000000000000ull
  16985. +#define XCT_MACTX_O 0x0400000000000000ull
  16986. +#define XCT_MACTX_E 0x0200000000000000ull
  16987. +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
  16988. +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
  16989. +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
  16990. +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
  16991. +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
  16992. +#define XCT_MACTX_CRC_M 0x0060000000000000ull
  16993. +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
  16994. +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
  16995. +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
  16996. +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
  16997. +#define XCT_MACTX_SS 0x0010000000000000ull
  16998. +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
  16999. +#define XCT_MACTX_LLEN_S 32ull
  17000. +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
  17001. + XCT_MACTX_LLEN_M)
  17002. +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
  17003. +#define XCT_MACTX_IPH_S 27ull
  17004. +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
  17005. + XCT_MACTX_IPH_M)
  17006. +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
  17007. +#define XCT_MACTX_IPO_S 22ull
  17008. +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
  17009. + XCT_MACTX_IPO_M)
  17010. +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
  17011. +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
  17012. +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
  17013. +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
  17014. +#define XCT_MACTX_V6 0x0000000000000010ull
  17015. +#define XCT_MACTX_C 0x0000000000000004ull
  17016. +#define XCT_MACTX_AL2 0x0000000000000002ull
  17017. +
  17018. +#define XCT_PTR_T 0x8000000000000000ull
  17019. +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
  17020. +#define XCT_PTR_LEN_S 44
  17021. +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
  17022. + XCT_PTR_LEN_M)
  17023. +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
  17024. +#define XCT_PTR_ADDR_S 0
  17025. +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
  17026. + XCT_PTR_ADDR_M)
  17027. +
  17028. +/* Function descriptor fields */
  17029. +#define XCT_FUN_T 0x8000000000000000ull
  17030. +#define XCT_FUN_ST 0x4000000000000000ull
  17031. +#define XCT_FUN_NORES 0x0000000000000000ull
  17032. +#define XCT_FUN_8BRES 0x1000000000000000ull
  17033. +#define XCT_FUN_24BRES 0x2000000000000000ull
  17034. +#define XCT_FUN_40BRES 0x3000000000000000ull
  17035. +#define XCT_FUN_I 0x0800000000000000ull
  17036. +#define XCT_FUN_O 0x0400000000000000ull
  17037. +#define XCT_FUN_E 0x0200000000000000ull
  17038. +#define XCT_FUN_FUN_S 54
  17039. +#define XCT_FUN_FUN_M 0x01c0000000000000ull
  17040. +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
  17041. + XCT_FUN_FUN_M)
  17042. +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
  17043. +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
  17044. +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
  17045. +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
  17046. +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
  17047. +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
  17048. +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
  17049. +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
  17050. +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
  17051. +#define XCT_FUN_LLEN_S 32ULL
  17052. +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
  17053. + XCT_FUN_LLEN_M)
  17054. +#define XCT_FUN_SHL_M 0x00000000f8000000ull
  17055. +#define XCT_FUN_SHL_S 27ull
  17056. +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
  17057. + XCT_FUN_SHL_M)
  17058. +#define XCT_FUN_CHL_M 0x0000000007c00000ull
  17059. +#define XCT_FUN_CHL_S 22ull
  17060. +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
  17061. + XCT_FUN_CHL_M)
  17062. +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
  17063. +#define XCT_FUN_HSZ_S 18ull
  17064. +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
  17065. + XCT_FUN_HSZ_M)
  17066. +#define XCT_FUN_ALG_DES 0x0000000000000000ull
  17067. +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
  17068. +#define XCT_FUN_ALG_AES 0x0000000000010000ull
  17069. +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
  17070. +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
  17071. +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
  17072. +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
  17073. +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
  17074. +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
  17075. +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
  17076. +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
  17077. +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
  17078. +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
  17079. +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
  17080. +#define XCT_FUN_BCP_PL 0x0000000000000400ull
  17081. +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
  17082. +#define XCT_FUN_SIG_MD5 (0ull << 4)
  17083. +#define XCT_FUN_SIG_SHA1 (2ull << 4)
  17084. +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
  17085. +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
  17086. +#define XCT_FUN_A 0x0000000000000008ull
  17087. +#define XCT_FUN_C 0x0000000000000004ull
  17088. +#define XCT_FUN_AL2 0x0000000000000002ull
  17089. +#define XCT_FUN_SE 0x0000000000000001ull
  17090. +
  17091. +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
  17092. +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
  17093. + 0x8000000000000000ull)
  17094. +
  17095. +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
  17096. +#define XCT_CTRL_HDR_FUN_NUM_S 54
  17097. +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
  17098. +#define XCT_CTRL_HDR_LEN_S 32
  17099. +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
  17100. +#define XCT_CTRL_HDR_REG_S 0
  17101. +
  17102. +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
  17103. + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
  17104. + & XCT_CTRL_HDR_FUN_NUM_M) | \
  17105. + ((((long)(len)) << \
  17106. + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
  17107. + ((((long)(reg)) << \
  17108. + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
  17109. +
  17110. +/* Function config command options */
  17111. +#define DMA_CALGO_DES 0x00
  17112. +#define DMA_CALGO_3DES 0x01
  17113. +#define DMA_CALGO_AES 0x02
  17114. +#define DMA_CALGO_ARC 0x03
  17115. +
  17116. +#define DMA_FN_CIV0 0x02
  17117. +#define DMA_FN_CIV1 0x03
  17118. +#define DMA_FN_HKEY0 0x0a
  17119. +
  17120. +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
  17121. + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
  17122. +
  17123. +#endif /* PASEMI_FNU_H */
  17124. diff -Nur linux-2.6.27.10.orig/crypto/ocf/random.c linux-2.6.27.10/crypto/ocf/random.c
  17125. --- linux-2.6.27.10.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
  17126. +++ linux-2.6.27.10/crypto/ocf/random.c 2008-12-23 19:31:44.000000000 +0100
  17127. @@ -0,0 +1,317 @@
  17128. +/*
  17129. + * A system independant way of adding entropy to the kernels pool
  17130. + * this way the drivers can focus on the real work and we can take
  17131. + * care of pushing it to the appropriate place in the kernel.
  17132. + *
  17133. + * This should be fast and callable from timers/interrupts
  17134. + *
  17135. + * Written by David McCullough <david_mccullough@securecomputing.com>
  17136. + * Copyright (C) 2006-2007 David McCullough
  17137. + * Copyright (C) 2004-2005 Intel Corporation.
  17138. + *
  17139. + * LICENSE TERMS
  17140. + *
  17141. + * The free distribution and use of this software in both source and binary
  17142. + * form is allowed (with or without changes) provided that:
  17143. + *
  17144. + * 1. distributions of this source code include the above copyright
  17145. + * notice, this list of conditions and the following disclaimer;
  17146. + *
  17147. + * 2. distributions in binary form include the above copyright
  17148. + * notice, this list of conditions and the following disclaimer
  17149. + * in the documentation and/or other associated materials;
  17150. + *
  17151. + * 3. the copyright holder's name is not used to endorse products
  17152. + * built using this software without specific written permission.
  17153. + *
  17154. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  17155. + * may be distributed under the terms of the GNU General Public License (GPL),
  17156. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  17157. + *
  17158. + * DISCLAIMER
  17159. + *
  17160. + * This software is provided 'as is' with no explicit or implied warranties
  17161. + * in respect of its properties, including, but not limited to, correctness
  17162. + * and/or fitness for purpose.
  17163. + */
  17164. +
  17165. +#ifndef AUTOCONF_INCLUDED
  17166. +#include <linux/config.h>
  17167. +#endif
  17168. +#include <linux/module.h>
  17169. +#include <linux/init.h>
  17170. +#include <linux/list.h>
  17171. +#include <linux/slab.h>
  17172. +#include <linux/wait.h>
  17173. +#include <linux/sched.h>
  17174. +#include <linux/spinlock.h>
  17175. +#include <linux/version.h>
  17176. +#include <linux/unistd.h>
  17177. +#include <linux/poll.h>
  17178. +#include <linux/random.h>
  17179. +#include <cryptodev.h>
  17180. +
  17181. +#ifdef CONFIG_OCF_FIPS
  17182. +#include "rndtest.h"
  17183. +#endif
  17184. +
  17185. +#ifndef HAS_RANDOM_INPUT_WAIT
  17186. +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
  17187. +#endif
  17188. +
  17189. +/*
  17190. + * a hack to access the debug levels from the crypto driver
  17191. + */
  17192. +extern int crypto_debug;
  17193. +#define debug crypto_debug
  17194. +
  17195. +/*
  17196. + * a list of all registered random providers
  17197. + */
  17198. +static LIST_HEAD(random_ops);
  17199. +static int started = 0;
  17200. +static int initted = 0;
  17201. +
  17202. +struct random_op {
  17203. + struct list_head random_list;
  17204. + u_int32_t driverid;
  17205. + int (*read_random)(void *arg, u_int32_t *buf, int len);
  17206. + void *arg;
  17207. +};
  17208. +
  17209. +static int random_proc(void *arg);
  17210. +
  17211. +static pid_t randomproc = (pid_t) -1;
  17212. +static spinlock_t random_lock;
  17213. +
  17214. +/*
  17215. + * just init the spin locks
  17216. + */
  17217. +static int
  17218. +crypto_random_init(void)
  17219. +{
  17220. + spin_lock_init(&random_lock);
  17221. + initted = 1;
  17222. + return(0);
  17223. +}
  17224. +
  17225. +/*
  17226. + * Add the given random reader to our list (if not present)
  17227. + * and start the thread (if not already started)
  17228. + *
  17229. + * we have to assume that driver id is ok for now
  17230. + */
  17231. +int
  17232. +crypto_rregister(
  17233. + u_int32_t driverid,
  17234. + int (*read_random)(void *arg, u_int32_t *buf, int len),
  17235. + void *arg)
  17236. +{
  17237. + unsigned long flags;
  17238. + int ret = 0;
  17239. + struct random_op *rops, *tmp;
  17240. +
  17241. + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
  17242. + __FUNCTION__, driverid, read_random, arg);
  17243. +
  17244. + if (!initted)
  17245. + crypto_random_init();
  17246. +
  17247. +#if 0
  17248. + struct cryptocap *cap;
  17249. +
  17250. + cap = crypto_checkdriver(driverid);
  17251. + if (!cap)
  17252. + return EINVAL;
  17253. +#endif
  17254. +
  17255. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  17256. + if (rops->driverid == driverid && rops->read_random == read_random)
  17257. + return EEXIST;
  17258. + }
  17259. +
  17260. + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
  17261. + if (!rops)
  17262. + return ENOMEM;
  17263. +
  17264. + rops->driverid = driverid;
  17265. + rops->read_random = read_random;
  17266. + rops->arg = arg;
  17267. +
  17268. + spin_lock_irqsave(&random_lock, flags);
  17269. + list_add_tail(&rops->random_list, &random_ops);
  17270. + if (!started) {
  17271. + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
  17272. + if (randomproc < 0) {
  17273. + ret = randomproc;
  17274. + printk("crypto: crypto_rregister cannot start random thread; "
  17275. + "error %d", ret);
  17276. + } else
  17277. + started = 1;
  17278. + }
  17279. + spin_unlock_irqrestore(&random_lock, flags);
  17280. +
  17281. + return ret;
  17282. +}
  17283. +EXPORT_SYMBOL(crypto_rregister);
  17284. +
  17285. +int
  17286. +crypto_runregister_all(u_int32_t driverid)
  17287. +{
  17288. + struct random_op *rops, *tmp;
  17289. + unsigned long flags;
  17290. +
  17291. + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
  17292. +
  17293. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  17294. + if (rops->driverid == driverid) {
  17295. + list_del(&rops->random_list);
  17296. + kfree(rops);
  17297. + }
  17298. + }
  17299. +
  17300. + spin_lock_irqsave(&random_lock, flags);
  17301. + if (list_empty(&random_ops) && started)
  17302. + kill_pid(randomproc, SIGKILL, 1);
  17303. + spin_unlock_irqrestore(&random_lock, flags);
  17304. + return(0);
  17305. +}
  17306. +EXPORT_SYMBOL(crypto_runregister_all);
  17307. +
  17308. +/*
  17309. + * while we can add entropy to random.c continue to read random data from
  17310. + * the drivers and push it to random.
  17311. + */
  17312. +static int
  17313. +random_proc(void *arg)
  17314. +{
  17315. + int n;
  17316. + int wantcnt;
  17317. + int bufcnt = 0;
  17318. + int retval = 0;
  17319. + int *buf = NULL;
  17320. +
  17321. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  17322. + daemonize();
  17323. + spin_lock_irq(&current->sigmask_lock);
  17324. + sigemptyset(&current->blocked);
  17325. + recalc_sigpending(current);
  17326. + spin_unlock_irq(&current->sigmask_lock);
  17327. + sprintf(current->comm, "ocf-random");
  17328. +#else
  17329. + daemonize("ocf-random");
  17330. + allow_signal(SIGKILL);
  17331. +#endif
  17332. +
  17333. + (void) get_fs();
  17334. + set_fs(get_ds());
  17335. +
  17336. +#ifdef CONFIG_OCF_FIPS
  17337. +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
  17338. +#else
  17339. +#define NUM_INT 32
  17340. +#endif
  17341. +
  17342. + /*
  17343. + * some devices can transferr their RNG data direct into memory,
  17344. + * so make sure it is device friendly
  17345. + */
  17346. + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
  17347. + if (NULL == buf) {
  17348. + printk("crypto: RNG could not allocate memory\n");
  17349. + retval = -ENOMEM;
  17350. + goto bad_alloc;
  17351. + }
  17352. +
  17353. + wantcnt = NUM_INT; /* start by adding some entropy */
  17354. +
  17355. + /*
  17356. + * its possible due to errors or driver removal that we no longer
  17357. + * have anything to do, if so exit or we will consume all the CPU
  17358. + * doing nothing
  17359. + */
  17360. + while (!list_empty(&random_ops)) {
  17361. + struct random_op *rops, *tmp;
  17362. +
  17363. +#ifdef CONFIG_OCF_FIPS
  17364. + if (wantcnt)
  17365. + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
  17366. +#endif
  17367. +
  17368. + /* see if we can get enough entropy to make the world
  17369. + * a better place.
  17370. + */
  17371. + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
  17372. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  17373. +
  17374. + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
  17375. + NUM_INT - bufcnt);
  17376. +
  17377. + /* on failure remove the random number generator */
  17378. + if (n == -1) {
  17379. + list_del(&rops->random_list);
  17380. + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
  17381. + rops->driverid);
  17382. + kfree(rops);
  17383. + } else if (n > 0)
  17384. + bufcnt += n;
  17385. + }
  17386. + /* give up CPU for a bit, just in case as this is a loop */
  17387. + schedule();
  17388. + }
  17389. +
  17390. +
  17391. +#ifdef CONFIG_OCF_FIPS
  17392. + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
  17393. + dprintk("crypto: buffer had fips errors, discarding\n");
  17394. + bufcnt = 0;
  17395. + }
  17396. +#endif
  17397. +
  17398. + /*
  17399. + * if we have a certified buffer, we can send some data
  17400. + * to /dev/random and move along
  17401. + */
  17402. + if (bufcnt > 0) {
  17403. + /* add what we have */
  17404. + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
  17405. + bufcnt = 0;
  17406. + }
  17407. +
  17408. + /* give up CPU for a bit so we don't hog while filling */
  17409. + schedule();
  17410. +
  17411. + /* wait for needing more */
  17412. + wantcnt = random_input_wait();
  17413. +
  17414. + if (wantcnt <= 0)
  17415. + wantcnt = 0; /* try to get some info again */
  17416. + else
  17417. + /* round up to one word or we can loop forever */
  17418. + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
  17419. + if (wantcnt > NUM_INT) {
  17420. + wantcnt = NUM_INT;
  17421. + }
  17422. +
  17423. + if (signal_pending(current)) {
  17424. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  17425. + spin_lock_irq(&current->sigmask_lock);
  17426. +#endif
  17427. + flush_signals(current);
  17428. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  17429. + spin_unlock_irq(&current->sigmask_lock);
  17430. +#endif
  17431. + }
  17432. + }
  17433. +
  17434. + kfree(buf);
  17435. +
  17436. +bad_alloc:
  17437. + spin_lock_irq(&random_lock);
  17438. + randomproc = (pid_t) -1;
  17439. + started = 0;
  17440. + spin_unlock_irq(&random_lock);
  17441. +
  17442. + return retval;
  17443. +}
  17444. +
  17445. diff -Nur linux-2.6.27.10.orig/crypto/ocf/README linux-2.6.27.10/crypto/ocf/README
  17446. --- linux-2.6.27.10.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
  17447. +++ linux-2.6.27.10/crypto/ocf/README 2008-12-23 19:31:44.000000000 +0100
  17448. @@ -0,0 +1,167 @@
  17449. +README - ocf-linux-20071215
  17450. +---------------------------
  17451. +
  17452. +This README provides instructions for getting ocf-linux compiled and
  17453. +operating in a generic linux environment. For other information you
  17454. +might like to visit the home page for this project:
  17455. +
  17456. + http://ocf-linux.sourceforge.net/
  17457. +
  17458. +Adding OCF to linux
  17459. +-------------------
  17460. +
  17461. + Not much in this file for now, just some notes. I usually build
  17462. + the ocf support as modules but it can be built into the kernel as
  17463. + well. To use it:
  17464. +
  17465. + * mknod /dev/crypto c 10 70
  17466. +
  17467. + * to add OCF to your kernel source, you have two options. Apply
  17468. + the kernel specific patch:
  17469. +
  17470. + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
  17471. + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
  17472. +
  17473. + if you do one of the above, then you can proceed to the next step,
  17474. + or you can do the above process by hand with using the patches against
  17475. + linux-2.4.35 and 2.6.23 to include the ocf code under crypto/ocf.
  17476. + Here's how to add it:
  17477. +
  17478. + for 2.4.35 (and later)
  17479. +
  17480. + cd linux-2.4.35/crypto
  17481. + tar xvzf ocf-linux.tar.gz
  17482. + cd ..
  17483. + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
  17484. +
  17485. + for 2.6.23 (and later), find the kernel patch specific (or nearest)
  17486. + to your kernel versions and then:
  17487. +
  17488. + cd linux-2.6.NN/crypto
  17489. + tar xvzf ocf-linux.tar.gz
  17490. + cd ..
  17491. + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
  17492. +
  17493. + It should be easy to take this patch and apply it to other more
  17494. + recent versions of the kernels. The same patches should also work
  17495. + relatively easily on kernels as old as 2.6.11 and 2.4.18.
  17496. +
  17497. + * under 2.4 if you are on a non-x86 platform, you may need to:
  17498. +
  17499. + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
  17500. +
  17501. + so that you can build the kernel crypto support needed for the cryptosoft
  17502. + driver.
  17503. +
  17504. + * For simplicity you should enable all the crypto support in your kernel
  17505. + except for the test driver. Likewise for the OCF options. Do not
  17506. + enable OCF crypto drivers for HW that you do not have (for example
  17507. + ixp4xx will not compile on non-Xscale systems).
  17508. +
  17509. + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
  17510. + crypto/cryptodev.h in an include directory that is used for building
  17511. + applications for your platform. For example on a host system that
  17512. + might be:
  17513. +
  17514. + /usr/include/crypto/cryptodev.h
  17515. +
  17516. + * patch your openssl-0.9.8i code with the openssl-0.9.8i.patch.
  17517. + (NOTE: there is no longer a need to patch ssh). The patch is against:
  17518. + openssl-0_9_8e
  17519. +
  17520. + If you need a patch for an older version of openssl, you should look
  17521. + to older OCF releases. This patch is unlikely to work on older
  17522. + openssl versions.
  17523. +
  17524. + openssl-0.9.8i.patch
  17525. + - enables --with-cryptodev for non BSD systems
  17526. + - adds -cpu option to openssl speed for calculating CPU load
  17527. + under linux
  17528. + - fixes null pointer in openssl speed multi thread output.
  17529. + - fixes test keys to work with linux crypto's more stringent
  17530. + key checking.
  17531. + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
  17532. + with the --with-cryptodev-digests option
  17533. + - fixes bug in engine code caching.
  17534. +
  17535. + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
  17536. + tools for testing OCF (ie., cryptotest).
  17537. +
  17538. +How to load the OCF drivers
  17539. +---------------------------
  17540. +
  17541. + First insert the base modules:
  17542. +
  17543. + insmod ocf
  17544. + insmod cryptodev
  17545. +
  17546. + You can then install the software OCF driver with:
  17547. +
  17548. + insmod cryptosoft
  17549. +
  17550. + and one or more of the OCF HW drivers with:
  17551. +
  17552. + insmod safe
  17553. + insmod hifn7751
  17554. + insmod ixp4xx
  17555. + ...
  17556. +
  17557. + all the drivers take a debug option to enable verbose debug so that
  17558. + you can see what is going on. For debug you load them as:
  17559. +
  17560. + insmod ocf crypto_debug=1
  17561. + insmod cryptodev cryptodev_debug=1
  17562. + insmod cryptosoft swcr_debug=1
  17563. +
  17564. + You may load more than one OCF crypto driver but then there is no guarantee
  17565. + as to which will be used.
  17566. +
  17567. + You can also enable debug at run time on 2.6 systems with the following:
  17568. +
  17569. + echo 1 > /sys/module/ocf/parameters/crypto_debug
  17570. + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
  17571. + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
  17572. + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
  17573. + echo 1 > /sys/module/safe/parameters/safe_debug
  17574. + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
  17575. + ...
  17576. +
  17577. +Testing the OCF support
  17578. +-----------------------
  17579. +
  17580. + run "cryptotest", it should do a short test for a couple of
  17581. + des packets. If it does everything is working.
  17582. +
  17583. + If this works, then ssh will use the driver when invoked as:
  17584. +
  17585. + ssh -c 3des username@host
  17586. +
  17587. + to see for sure that it is operating, enable debug as defined above.
  17588. +
  17589. + To get a better idea of performance run:
  17590. +
  17591. + cryptotest 100 4096
  17592. +
  17593. + There are more options to cryptotest, see the help.
  17594. +
  17595. + It is also possible to use openssl to test the speed of the crypto
  17596. + drivers.
  17597. +
  17598. + openssl speed -evp des -engine cryptodev -elapsed
  17599. + openssl speed -evp des3 -engine cryptodev -elapsed
  17600. + openssl speed -evp aes128 -engine cryptodev -elapsed
  17601. +
  17602. + and multiple threads (10) with:
  17603. +
  17604. + openssl speed -evp des -engine cryptodev -elapsed -multi 10
  17605. + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
  17606. + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
  17607. +
  17608. + for public key testing you can try:
  17609. +
  17610. + cryptokeytest
  17611. + openssl speed -engine cryptodev rsa -elapsed
  17612. + openssl speed -engine cryptodev dsa -elapsed
  17613. +
  17614. +David McCullough
  17615. +david_mccullough@securecomputing.com
  17616. diff -Nur linux-2.6.27.10.orig/crypto/ocf/rndtest.c linux-2.6.27.10/crypto/ocf/rndtest.c
  17617. --- linux-2.6.27.10.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
  17618. +++ linux-2.6.27.10/crypto/ocf/rndtest.c 2008-12-23 19:31:44.000000000 +0100
  17619. @@ -0,0 +1,300 @@
  17620. +/* $OpenBSD$ */
  17621. +
  17622. +/*
  17623. + * OCF/Linux port done by David McCullough <david_mccullough@securecomputing.com>
  17624. + * Copyright (C) 2006-2007 David McCullough
  17625. + * Copyright (C) 2004-2005 Intel Corporation.
  17626. + * The license and original author are listed below.
  17627. + *
  17628. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  17629. + * All rights reserved.
  17630. + *
  17631. + * Redistribution and use in source and binary forms, with or without
  17632. + * modification, are permitted provided that the following conditions
  17633. + * are met:
  17634. + * 1. Redistributions of source code must retain the above copyright
  17635. + * notice, this list of conditions and the following disclaimer.
  17636. + * 2. Redistributions in binary form must reproduce the above copyright
  17637. + * notice, this list of conditions and the following disclaimer in the
  17638. + * documentation and/or other materials provided with the distribution.
  17639. + * 3. All advertising materials mentioning features or use of this software
  17640. + * must display the following acknowledgement:
  17641. + * This product includes software developed by Jason L. Wright
  17642. + * 4. The name of the author may not be used to endorse or promote products
  17643. + * derived from this software without specific prior written permission.
  17644. + *
  17645. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17646. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17647. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17648. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  17649. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17650. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  17651. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  17652. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  17653. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17654. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17655. + * POSSIBILITY OF SUCH DAMAGE.
  17656. + */
  17657. +
  17658. +#ifndef AUTOCONF_INCLUDED
  17659. +#include <linux/config.h>
  17660. +#endif
  17661. +#include <linux/module.h>
  17662. +#include <linux/list.h>
  17663. +#include <linux/wait.h>
  17664. +#include <linux/time.h>
  17665. +#include <linux/version.h>
  17666. +#include <linux/unistd.h>
  17667. +#include <linux/kernel.h>
  17668. +#include <linux/string.h>
  17669. +#include <linux/time.h>
  17670. +#include <cryptodev.h>
  17671. +#include "rndtest.h"
  17672. +
  17673. +static struct rndtest_stats rndstats;
  17674. +
  17675. +static void rndtest_test(struct rndtest_state *);
  17676. +
  17677. +/* The tests themselves */
  17678. +static int rndtest_monobit(struct rndtest_state *);
  17679. +static int rndtest_runs(struct rndtest_state *);
  17680. +static int rndtest_longruns(struct rndtest_state *);
  17681. +static int rndtest_chi_4(struct rndtest_state *);
  17682. +
  17683. +static int rndtest_runs_check(struct rndtest_state *, int, int *);
  17684. +static void rndtest_runs_record(struct rndtest_state *, int, int *);
  17685. +
  17686. +static const struct rndtest_testfunc {
  17687. + int (*test)(struct rndtest_state *);
  17688. +} rndtest_funcs[] = {
  17689. + { rndtest_monobit },
  17690. + { rndtest_runs },
  17691. + { rndtest_chi_4 },
  17692. + { rndtest_longruns },
  17693. +};
  17694. +
  17695. +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
  17696. +
  17697. +static void
  17698. +rndtest_test(struct rndtest_state *rsp)
  17699. +{
  17700. + int i, rv = 0;
  17701. +
  17702. + rndstats.rst_tests++;
  17703. + for (i = 0; i < RNDTEST_NTESTS; i++)
  17704. + rv |= (*rndtest_funcs[i].test)(rsp);
  17705. + rsp->rs_discard = (rv != 0);
  17706. +}
  17707. +
  17708. +
  17709. +extern int crypto_debug;
  17710. +#define rndtest_verbose 2
  17711. +#define rndtest_report(rsp, failure, fmt, a...) \
  17712. + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
  17713. +
  17714. +#define RNDTEST_MONOBIT_MINONES 9725
  17715. +#define RNDTEST_MONOBIT_MAXONES 10275
  17716. +
  17717. +static int
  17718. +rndtest_monobit(struct rndtest_state *rsp)
  17719. +{
  17720. + int i, ones = 0, j;
  17721. + u_int8_t r;
  17722. +
  17723. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17724. + r = rsp->rs_buf[i];
  17725. + for (j = 0; j < 8; j++, r <<= 1)
  17726. + if (r & 0x80)
  17727. + ones++;
  17728. + }
  17729. + if (ones > RNDTEST_MONOBIT_MINONES &&
  17730. + ones < RNDTEST_MONOBIT_MAXONES) {
  17731. + if (rndtest_verbose > 1)
  17732. + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
  17733. + RNDTEST_MONOBIT_MINONES, ones,
  17734. + RNDTEST_MONOBIT_MAXONES);
  17735. + return (0);
  17736. + } else {
  17737. + if (rndtest_verbose)
  17738. + rndtest_report(rsp, 1,
  17739. + "monobit failed (%d ones)", ones);
  17740. + rndstats.rst_monobit++;
  17741. + return (-1);
  17742. + }
  17743. +}
  17744. +
  17745. +#define RNDTEST_RUNS_NINTERVAL 6
  17746. +
  17747. +static const struct rndtest_runs_tabs {
  17748. + u_int16_t min, max;
  17749. +} rndtest_runs_tab[] = {
  17750. + { 2343, 2657 },
  17751. + { 1135, 1365 },
  17752. + { 542, 708 },
  17753. + { 251, 373 },
  17754. + { 111, 201 },
  17755. + { 111, 201 },
  17756. +};
  17757. +
  17758. +static int
  17759. +rndtest_runs(struct rndtest_state *rsp)
  17760. +{
  17761. + int i, j, ones, zeros, rv = 0;
  17762. + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
  17763. + u_int8_t c;
  17764. +
  17765. + bzero(onei, sizeof(onei));
  17766. + bzero(zeroi, sizeof(zeroi));
  17767. + ones = zeros = 0;
  17768. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17769. + c = rsp->rs_buf[i];
  17770. + for (j = 0; j < 8; j++, c <<= 1) {
  17771. + if (c & 0x80) {
  17772. + ones++;
  17773. + rndtest_runs_record(rsp, zeros, zeroi);
  17774. + zeros = 0;
  17775. + } else {
  17776. + zeros++;
  17777. + rndtest_runs_record(rsp, ones, onei);
  17778. + ones = 0;
  17779. + }
  17780. + }
  17781. + }
  17782. + rndtest_runs_record(rsp, ones, onei);
  17783. + rndtest_runs_record(rsp, zeros, zeroi);
  17784. +
  17785. + rv |= rndtest_runs_check(rsp, 0, zeroi);
  17786. + rv |= rndtest_runs_check(rsp, 1, onei);
  17787. +
  17788. + if (rv)
  17789. + rndstats.rst_runs++;
  17790. +
  17791. + return (rv);
  17792. +}
  17793. +
  17794. +static void
  17795. +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
  17796. +{
  17797. + if (len == 0)
  17798. + return;
  17799. + if (len > RNDTEST_RUNS_NINTERVAL)
  17800. + len = RNDTEST_RUNS_NINTERVAL;
  17801. + len -= 1;
  17802. + intrv[len]++;
  17803. +}
  17804. +
  17805. +static int
  17806. +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
  17807. +{
  17808. + int i, rv = 0;
  17809. +
  17810. + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
  17811. + if (src[i] < rndtest_runs_tab[i].min ||
  17812. + src[i] > rndtest_runs_tab[i].max) {
  17813. + rndtest_report(rsp, 1,
  17814. + "%s interval %d failed (%d, %d-%d)",
  17815. + val ? "ones" : "zeros",
  17816. + i + 1, src[i], rndtest_runs_tab[i].min,
  17817. + rndtest_runs_tab[i].max);
  17818. + rv = -1;
  17819. + } else {
  17820. + rndtest_report(rsp, 0,
  17821. + "runs pass %s interval %d (%d < %d < %d)",
  17822. + val ? "ones" : "zeros",
  17823. + i + 1, rndtest_runs_tab[i].min, src[i],
  17824. + rndtest_runs_tab[i].max);
  17825. + }
  17826. + }
  17827. + return (rv);
  17828. +}
  17829. +
  17830. +static int
  17831. +rndtest_longruns(struct rndtest_state *rsp)
  17832. +{
  17833. + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
  17834. + u_int8_t c;
  17835. +
  17836. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17837. + c = rsp->rs_buf[i];
  17838. + for (j = 0; j < 8; j++, c <<= 1) {
  17839. + if (c & 0x80) {
  17840. + zeros = 0;
  17841. + ones++;
  17842. + if (ones > maxones)
  17843. + maxones = ones;
  17844. + } else {
  17845. + ones = 0;
  17846. + zeros++;
  17847. + if (zeros > maxzeros)
  17848. + maxzeros = zeros;
  17849. + }
  17850. + }
  17851. + }
  17852. +
  17853. + if (maxones < 26 && maxzeros < 26) {
  17854. + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
  17855. + maxones, maxzeros);
  17856. + return (0);
  17857. + } else {
  17858. + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
  17859. + maxones, maxzeros);
  17860. + rndstats.rst_longruns++;
  17861. + return (-1);
  17862. + }
  17863. +}
  17864. +
  17865. +/*
  17866. + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
  17867. + * but it is really the chi^2 test over 4 bits (the poker test as described
  17868. + * by Knuth vol 2 is something different, and I take him as authoritative
  17869. + * on nomenclature over NIST).
  17870. + */
  17871. +#define RNDTEST_CHI4_K 16
  17872. +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
  17873. +
  17874. +/*
  17875. + * The unnormalized values are used so that we don't have to worry about
  17876. + * fractional precision. The "real" value is found by:
  17877. + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
  17878. + */
  17879. +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
  17880. +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
  17881. +
  17882. +static int
  17883. +rndtest_chi_4(struct rndtest_state *rsp)
  17884. +{
  17885. + unsigned int freq[RNDTEST_CHI4_K], i, sum;
  17886. +
  17887. + for (i = 0; i < RNDTEST_CHI4_K; i++)
  17888. + freq[i] = 0;
  17889. +
  17890. + /* Get number of occurances of each 4 bit pattern */
  17891. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17892. + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
  17893. + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
  17894. + }
  17895. +
  17896. + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
  17897. + sum += freq[i] * freq[i];
  17898. +
  17899. + if (sum >= 1563181 && sum <= 1576929) {
  17900. + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
  17901. + return (0);
  17902. + } else {
  17903. + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
  17904. + rndstats.rst_chi++;
  17905. + return (-1);
  17906. + }
  17907. +}
  17908. +
  17909. +int
  17910. +rndtest_buf(unsigned char *buf)
  17911. +{
  17912. + struct rndtest_state rsp;
  17913. +
  17914. + memset(&rsp, 0, sizeof(rsp));
  17915. + rsp.rs_buf = buf;
  17916. + rndtest_test(&rsp);
  17917. + return(rsp.rs_discard);
  17918. +}
  17919. +
  17920. diff -Nur linux-2.6.27.10.orig/crypto/ocf/rndtest.h linux-2.6.27.10/crypto/ocf/rndtest.h
  17921. --- linux-2.6.27.10.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
  17922. +++ linux-2.6.27.10/crypto/ocf/rndtest.h 2008-12-23 19:31:44.000000000 +0100
  17923. @@ -0,0 +1,54 @@
  17924. +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
  17925. +/* $OpenBSD$ */
  17926. +
  17927. +/*
  17928. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  17929. + * All rights reserved.
  17930. + *
  17931. + * Redistribution and use in source and binary forms, with or without
  17932. + * modification, are permitted provided that the following conditions
  17933. + * are met:
  17934. + * 1. Redistributions of source code must retain the above copyright
  17935. + * notice, this list of conditions and the following disclaimer.
  17936. + * 2. Redistributions in binary form must reproduce the above copyright
  17937. + * notice, this list of conditions and the following disclaimer in the
  17938. + * documentation and/or other materials provided with the distribution.
  17939. + * 3. All advertising materials mentioning features or use of this software
  17940. + * must display the following acknowledgement:
  17941. + * This product includes software developed by Jason L. Wright
  17942. + * 4. The name of the author may not be used to endorse or promote products
  17943. + * derived from this software without specific prior written permission.
  17944. + *
  17945. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17946. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17947. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17948. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  17949. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17950. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  17951. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  17952. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  17953. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17954. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17955. + * POSSIBILITY OF SUCH DAMAGE.
  17956. + */
  17957. +
  17958. +
  17959. +/* Some of the tests depend on these values */
  17960. +#define RNDTEST_NBYTES 2500
  17961. +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
  17962. +
  17963. +struct rndtest_state {
  17964. + int rs_discard; /* discard/accept random data */
  17965. + u_int8_t *rs_buf;
  17966. +};
  17967. +
  17968. +struct rndtest_stats {
  17969. + u_int32_t rst_discard; /* number of bytes discarded */
  17970. + u_int32_t rst_tests; /* number of test runs */
  17971. + u_int32_t rst_monobit; /* monobit test failures */
  17972. + u_int32_t rst_runs; /* 0/1 runs failures */
  17973. + u_int32_t rst_longruns; /* longruns failures */
  17974. + u_int32_t rst_chi; /* chi^2 failures */
  17975. +};
  17976. +
  17977. +extern int rndtest_buf(unsigned char *buf);
  17978. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/Makefile linux-2.6.27.10/crypto/ocf/safe/Makefile
  17979. --- linux-2.6.27.10.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
  17980. +++ linux-2.6.27.10/crypto/ocf/safe/Makefile 2008-12-23 19:31:44.000000000 +0100
  17981. @@ -0,0 +1,12 @@
  17982. +# for SGlinux builds
  17983. +-include $(ROOTDIR)/modules/.config
  17984. +
  17985. +obj-$(CONFIG_OCF_SAFE) += safe.o
  17986. +
  17987. +obj ?= .
  17988. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  17989. +
  17990. +ifdef TOPDIR
  17991. +-include $(TOPDIR)/Rules.make
  17992. +endif
  17993. +
  17994. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/md5.c linux-2.6.27.10/crypto/ocf/safe/md5.c
  17995. --- linux-2.6.27.10.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
  17996. +++ linux-2.6.27.10/crypto/ocf/safe/md5.c 2008-12-23 19:31:44.000000000 +0100
  17997. @@ -0,0 +1,308 @@
  17998. +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  17999. +/*
  18000. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  18001. + * All rights reserved.
  18002. + *
  18003. + * Redistribution and use in source and binary forms, with or without
  18004. + * modification, are permitted provided that the following conditions
  18005. + * are met:
  18006. + * 1. Redistributions of source code must retain the above copyright
  18007. + * notice, this list of conditions and the following disclaimer.
  18008. + * 2. Redistributions in binary form must reproduce the above copyright
  18009. + * notice, this list of conditions and the following disclaimer in the
  18010. + * documentation and/or other materials provided with the distribution.
  18011. + * 3. Neither the name of the project nor the names of its contributors
  18012. + * may be used to endorse or promote products derived from this software
  18013. + * without specific prior written permission.
  18014. + *
  18015. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  18016. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18017. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18018. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  18019. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18020. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  18021. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  18022. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18023. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  18024. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  18025. + * SUCH DAMAGE.
  18026. + */
  18027. +
  18028. +#if 0
  18029. +#include <sys/cdefs.h>
  18030. +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
  18031. +
  18032. +#include <sys/types.h>
  18033. +#include <sys/cdefs.h>
  18034. +#include <sys/time.h>
  18035. +#include <sys/systm.h>
  18036. +#include <crypto/md5.h>
  18037. +#endif
  18038. +
  18039. +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
  18040. +
  18041. +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
  18042. +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
  18043. +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
  18044. +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
  18045. +
  18046. +#define ROUND1(a, b, c, d, k, s, i) { \
  18047. + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
  18048. + (a) = SHIFT((a), (s)); \
  18049. + (a) = (b) + (a); \
  18050. +}
  18051. +
  18052. +#define ROUND2(a, b, c, d, k, s, i) { \
  18053. + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
  18054. + (a) = SHIFT((a), (s)); \
  18055. + (a) = (b) + (a); \
  18056. +}
  18057. +
  18058. +#define ROUND3(a, b, c, d, k, s, i) { \
  18059. + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
  18060. + (a) = SHIFT((a), (s)); \
  18061. + (a) = (b) + (a); \
  18062. +}
  18063. +
  18064. +#define ROUND4(a, b, c, d, k, s, i) { \
  18065. + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
  18066. + (a) = SHIFT((a), (s)); \
  18067. + (a) = (b) + (a); \
  18068. +}
  18069. +
  18070. +#define Sa 7
  18071. +#define Sb 12
  18072. +#define Sc 17
  18073. +#define Sd 22
  18074. +
  18075. +#define Se 5
  18076. +#define Sf 9
  18077. +#define Sg 14
  18078. +#define Sh 20
  18079. +
  18080. +#define Si 4
  18081. +#define Sj 11
  18082. +#define Sk 16
  18083. +#define Sl 23
  18084. +
  18085. +#define Sm 6
  18086. +#define Sn 10
  18087. +#define So 15
  18088. +#define Sp 21
  18089. +
  18090. +#define MD5_A0 0x67452301
  18091. +#define MD5_B0 0xefcdab89
  18092. +#define MD5_C0 0x98badcfe
  18093. +#define MD5_D0 0x10325476
  18094. +
  18095. +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
  18096. +static const u_int32_t T[65] = {
  18097. + 0,
  18098. + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  18099. + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  18100. + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  18101. + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  18102. +
  18103. + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  18104. + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
  18105. + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  18106. + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  18107. +
  18108. + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  18109. + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  18110. + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
  18111. + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  18112. +
  18113. + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  18114. + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  18115. + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  18116. + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  18117. +};
  18118. +
  18119. +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  18120. + 0x80, 0, 0, 0, 0, 0, 0, 0,
  18121. + 0, 0, 0, 0, 0, 0, 0, 0,
  18122. + 0, 0, 0, 0, 0, 0, 0, 0,
  18123. + 0, 0, 0, 0, 0, 0, 0, 0,
  18124. + 0, 0, 0, 0, 0, 0, 0, 0,
  18125. + 0, 0, 0, 0, 0, 0, 0, 0,
  18126. + 0, 0, 0, 0, 0, 0, 0, 0,
  18127. + 0, 0, 0, 0, 0, 0, 0, 0,
  18128. +};
  18129. +
  18130. +static void md5_calc(u_int8_t *, md5_ctxt *);
  18131. +
  18132. +void md5_init(ctxt)
  18133. + md5_ctxt *ctxt;
  18134. +{
  18135. + ctxt->md5_n = 0;
  18136. + ctxt->md5_i = 0;
  18137. + ctxt->md5_sta = MD5_A0;
  18138. + ctxt->md5_stb = MD5_B0;
  18139. + ctxt->md5_stc = MD5_C0;
  18140. + ctxt->md5_std = MD5_D0;
  18141. + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  18142. +}
  18143. +
  18144. +void md5_loop(ctxt, input, len)
  18145. + md5_ctxt *ctxt;
  18146. + u_int8_t *input;
  18147. + u_int len; /* number of bytes */
  18148. +{
  18149. + u_int gap, i;
  18150. +
  18151. + ctxt->md5_n += len * 8; /* byte to bit */
  18152. + gap = MD5_BUFLEN - ctxt->md5_i;
  18153. +
  18154. + if (len >= gap) {
  18155. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  18156. + gap);
  18157. + md5_calc(ctxt->md5_buf, ctxt);
  18158. +
  18159. + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  18160. + md5_calc((u_int8_t *)(input + i), ctxt);
  18161. + }
  18162. +
  18163. + ctxt->md5_i = len - i;
  18164. + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  18165. + } else {
  18166. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  18167. + len);
  18168. + ctxt->md5_i += len;
  18169. + }
  18170. +}
  18171. +
  18172. +void md5_pad(ctxt)
  18173. + md5_ctxt *ctxt;
  18174. +{
  18175. + u_int gap;
  18176. +
  18177. + /* Don't count up padding. Keep md5_n. */
  18178. + gap = MD5_BUFLEN - ctxt->md5_i;
  18179. + if (gap > 8) {
  18180. + bcopy(md5_paddat,
  18181. + (void *)(ctxt->md5_buf + ctxt->md5_i),
  18182. + gap - sizeof(ctxt->md5_n));
  18183. + } else {
  18184. + /* including gap == 8 */
  18185. + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  18186. + gap);
  18187. + md5_calc(ctxt->md5_buf, ctxt);
  18188. + bcopy((md5_paddat + gap),
  18189. + (void *)ctxt->md5_buf,
  18190. + MD5_BUFLEN - sizeof(ctxt->md5_n));
  18191. + }
  18192. +
  18193. + /* 8 byte word */
  18194. +#if BYTE_ORDER == LITTLE_ENDIAN
  18195. + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  18196. +#endif
  18197. +#if BYTE_ORDER == BIG_ENDIAN
  18198. + ctxt->md5_buf[56] = ctxt->md5_n8[7];
  18199. + ctxt->md5_buf[57] = ctxt->md5_n8[6];
  18200. + ctxt->md5_buf[58] = ctxt->md5_n8[5];
  18201. + ctxt->md5_buf[59] = ctxt->md5_n8[4];
  18202. + ctxt->md5_buf[60] = ctxt->md5_n8[3];
  18203. + ctxt->md5_buf[61] = ctxt->md5_n8[2];
  18204. + ctxt->md5_buf[62] = ctxt->md5_n8[1];
  18205. + ctxt->md5_buf[63] = ctxt->md5_n8[0];
  18206. +#endif
  18207. +
  18208. + md5_calc(ctxt->md5_buf, ctxt);
  18209. +}
  18210. +
  18211. +void md5_result(digest, ctxt)
  18212. + u_int8_t *digest;
  18213. + md5_ctxt *ctxt;
  18214. +{
  18215. + /* 4 byte words */
  18216. +#if BYTE_ORDER == LITTLE_ENDIAN
  18217. + bcopy(&ctxt->md5_st8[0], digest, 16);
  18218. +#endif
  18219. +#if BYTE_ORDER == BIG_ENDIAN
  18220. + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  18221. + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  18222. + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  18223. + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  18224. + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  18225. + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  18226. + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  18227. + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  18228. +#endif
  18229. +}
  18230. +
  18231. +static void md5_calc(b64, ctxt)
  18232. + u_int8_t *b64;
  18233. + md5_ctxt *ctxt;
  18234. +{
  18235. + u_int32_t A = ctxt->md5_sta;
  18236. + u_int32_t B = ctxt->md5_stb;
  18237. + u_int32_t C = ctxt->md5_stc;
  18238. + u_int32_t D = ctxt->md5_std;
  18239. +#if BYTE_ORDER == LITTLE_ENDIAN
  18240. + u_int32_t *X = (u_int32_t *)b64;
  18241. +#endif
  18242. +#if BYTE_ORDER == BIG_ENDIAN
  18243. + /* 4 byte words */
  18244. + /* what a brute force but fast! */
  18245. + u_int32_t X[16];
  18246. + u_int8_t *y = (u_int8_t *)X;
  18247. + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  18248. + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  18249. + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  18250. + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  18251. + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  18252. + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  18253. + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  18254. + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  18255. + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  18256. + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  18257. + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  18258. + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  18259. + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  18260. + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  18261. + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  18262. + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  18263. +#endif
  18264. +
  18265. + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
  18266. + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
  18267. + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
  18268. + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
  18269. + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
  18270. + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  18271. + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  18272. + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  18273. +
  18274. + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
  18275. + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
  18276. + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  18277. + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
  18278. + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  18279. + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
  18280. + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
  18281. + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  18282. +
  18283. + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
  18284. + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  18285. + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
  18286. + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  18287. + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
  18288. + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
  18289. + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  18290. + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
  18291. +
  18292. + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
  18293. + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
  18294. + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
  18295. + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
  18296. + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
  18297. + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
  18298. + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
  18299. + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
  18300. +
  18301. + ctxt->md5_sta += A;
  18302. + ctxt->md5_stb += B;
  18303. + ctxt->md5_stc += C;
  18304. + ctxt->md5_std += D;
  18305. +}
  18306. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/md5.h linux-2.6.27.10/crypto/ocf/safe/md5.h
  18307. --- linux-2.6.27.10.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
  18308. +++ linux-2.6.27.10/crypto/ocf/safe/md5.h 2008-12-23 19:31:44.000000000 +0100
  18309. @@ -0,0 +1,76 @@
  18310. +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
  18311. +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
  18312. +
  18313. +/*
  18314. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  18315. + * All rights reserved.
  18316. + *
  18317. + * Redistribution and use in source and binary forms, with or without
  18318. + * modification, are permitted provided that the following conditions
  18319. + * are met:
  18320. + * 1. Redistributions of source code must retain the above copyright
  18321. + * notice, this list of conditions and the following disclaimer.
  18322. + * 2. Redistributions in binary form must reproduce the above copyright
  18323. + * notice, this list of conditions and the following disclaimer in the
  18324. + * documentation and/or other materials provided with the distribution.
  18325. + * 3. Neither the name of the project nor the names of its contributors
  18326. + * may be used to endorse or promote products derived from this software
  18327. + * without specific prior written permission.
  18328. + *
  18329. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  18330. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18331. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18332. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  18333. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18334. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  18335. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  18336. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18337. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  18338. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  18339. + * SUCH DAMAGE.
  18340. + */
  18341. +
  18342. +#ifndef _NETINET6_MD5_H_
  18343. +#define _NETINET6_MD5_H_
  18344. +
  18345. +#define MD5_BUFLEN 64
  18346. +
  18347. +typedef struct {
  18348. + union {
  18349. + u_int32_t md5_state32[4];
  18350. + u_int8_t md5_state8[16];
  18351. + } md5_st;
  18352. +
  18353. +#define md5_sta md5_st.md5_state32[0]
  18354. +#define md5_stb md5_st.md5_state32[1]
  18355. +#define md5_stc md5_st.md5_state32[2]
  18356. +#define md5_std md5_st.md5_state32[3]
  18357. +#define md5_st8 md5_st.md5_state8
  18358. +
  18359. + union {
  18360. + u_int64_t md5_count64;
  18361. + u_int8_t md5_count8[8];
  18362. + } md5_count;
  18363. +#define md5_n md5_count.md5_count64
  18364. +#define md5_n8 md5_count.md5_count8
  18365. +
  18366. + u_int md5_i;
  18367. + u_int8_t md5_buf[MD5_BUFLEN];
  18368. +} md5_ctxt;
  18369. +
  18370. +extern void md5_init(md5_ctxt *);
  18371. +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
  18372. +extern void md5_pad(md5_ctxt *);
  18373. +extern void md5_result(u_int8_t *, md5_ctxt *);
  18374. +
  18375. +/* compatibility */
  18376. +#define MD5_CTX md5_ctxt
  18377. +#define MD5Init(x) md5_init((x))
  18378. +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
  18379. +#define MD5Final(x, y) \
  18380. +do { \
  18381. + md5_pad((y)); \
  18382. + md5_result((x), (y)); \
  18383. +} while (0)
  18384. +
  18385. +#endif /* ! _NETINET6_MD5_H_*/
  18386. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/safe.c linux-2.6.27.10/crypto/ocf/safe/safe.c
  18387. --- linux-2.6.27.10.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
  18388. +++ linux-2.6.27.10/crypto/ocf/safe/safe.c 2008-12-23 19:31:44.000000000 +0100
  18389. @@ -0,0 +1,2288 @@
  18390. +/*-
  18391. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  18392. + * Copyright (C) 2004-2007 David McCullough
  18393. + * The license and original author are listed below.
  18394. + *
  18395. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  18396. + * Copyright (c) 2003 Global Technology Associates, Inc.
  18397. + * All rights reserved.
  18398. + *
  18399. + * Redistribution and use in source and binary forms, with or without
  18400. + * modification, are permitted provided that the following conditions
  18401. + * are met:
  18402. + * 1. Redistributions of source code must retain the above copyright
  18403. + * notice, this list of conditions and the following disclaimer.
  18404. + * 2. Redistributions in binary form must reproduce the above copyright
  18405. + * notice, this list of conditions and the following disclaimer in the
  18406. + * documentation and/or other materials provided with the distribution.
  18407. + *
  18408. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18409. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18410. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18411. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18412. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18413. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  18414. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  18415. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18416. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  18417. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  18418. + * SUCH DAMAGE.
  18419. + *
  18420. +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
  18421. + */
  18422. +
  18423. +#ifndef AUTOCONF_INCLUDED
  18424. +#include <linux/config.h>
  18425. +#endif
  18426. +#include <linux/module.h>
  18427. +#include <linux/kernel.h>
  18428. +#include <linux/init.h>
  18429. +#include <linux/list.h>
  18430. +#include <linux/slab.h>
  18431. +#include <linux/wait.h>
  18432. +#include <linux/sched.h>
  18433. +#include <linux/pci.h>
  18434. +#include <linux/delay.h>
  18435. +#include <linux/interrupt.h>
  18436. +#include <linux/spinlock.h>
  18437. +#include <linux/random.h>
  18438. +#include <linux/version.h>
  18439. +#include <linux/skbuff.h>
  18440. +#include <asm/io.h>
  18441. +
  18442. +/*
  18443. + * SafeNet SafeXcel-1141 hardware crypto accelerator
  18444. + */
  18445. +
  18446. +#include <cryptodev.h>
  18447. +#include <uio.h>
  18448. +#include <safe/safereg.h>
  18449. +#include <safe/safevar.h>
  18450. +
  18451. +#if 1
  18452. +#define DPRINTF(a) do { \
  18453. + if (debug) { \
  18454. + printk("%s: ", sc ? \
  18455. + device_get_nameunit(sc->sc_dev) : "safe"); \
  18456. + printk a; \
  18457. + } \
  18458. + } while (0)
  18459. +#else
  18460. +#define DPRINTF(a)
  18461. +#endif
  18462. +
  18463. +/*
  18464. + * until we find a cleaner way, include the BSD md5/sha1 code
  18465. + * here
  18466. + */
  18467. +#define HMAC_HACK 1
  18468. +#ifdef HMAC_HACK
  18469. +#define LITTLE_ENDIAN 1234
  18470. +#define BIG_ENDIAN 4321
  18471. +#ifdef __LITTLE_ENDIAN
  18472. +#define BYTE_ORDER LITTLE_ENDIAN
  18473. +#endif
  18474. +#ifdef __BIG_ENDIAN
  18475. +#define BYTE_ORDER BIG_ENDIAN
  18476. +#endif
  18477. +#include <safe/md5.h>
  18478. +#include <safe/md5.c>
  18479. +#include <safe/sha1.h>
  18480. +#include <safe/sha1.c>
  18481. +
  18482. +u_int8_t hmac_ipad_buffer[64] = {
  18483. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18484. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18485. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18486. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18487. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18488. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18489. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18490. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
  18491. +};
  18492. +
  18493. +u_int8_t hmac_opad_buffer[64] = {
  18494. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18495. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18496. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18497. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18498. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18499. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18500. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18501. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
  18502. +};
  18503. +#endif /* HMAC_HACK */
  18504. +
  18505. +/* add proc entry for this */
  18506. +struct safe_stats safestats;
  18507. +
  18508. +#define debug safe_debug
  18509. +int safe_debug = 0;
  18510. +module_param(safe_debug, int, 0644);
  18511. +MODULE_PARM_DESC(safe_debug, "Enable debug");
  18512. +
  18513. +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
  18514. +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
  18515. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  18516. +static void safe_rng_init(struct safe_softc *);
  18517. +int safe_rngbufsize = 8; /* 32 bytes each read */
  18518. +module_param(safe_rngbufsize, int, 0644);
  18519. +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
  18520. +int safe_rngmaxalarm = 8; /* max alarms before reset */
  18521. +module_param(safe_rngmaxalarm, int, 0644);
  18522. +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
  18523. +#endif /* SAFE_NO_RNG */
  18524. +
  18525. +static void safe_totalreset(struct safe_softc *sc);
  18526. +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
  18527. +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
  18528. +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
  18529. +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
  18530. +static int safe_kstart(struct safe_softc *sc);
  18531. +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
  18532. +static void safe_kfeed(struct safe_softc *sc);
  18533. +static void safe_kpoll(unsigned long arg);
  18534. +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
  18535. + u_int32_t len, struct crparam *n);
  18536. +
  18537. +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
  18538. +static int safe_freesession(device_t, u_int64_t);
  18539. +static int safe_process(device_t, struct cryptop *, int);
  18540. +
  18541. +static device_method_t safe_methods = {
  18542. + /* crypto device methods */
  18543. + DEVMETHOD(cryptodev_newsession, safe_newsession),
  18544. + DEVMETHOD(cryptodev_freesession,safe_freesession),
  18545. + DEVMETHOD(cryptodev_process, safe_process),
  18546. + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
  18547. +};
  18548. +
  18549. +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
  18550. +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
  18551. +
  18552. +#define SAFE_MAX_CHIPS 8
  18553. +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
  18554. +
  18555. +/*
  18556. + * split our buffers up into safe DMAable byte fragments to avoid lockup
  18557. + * bug in 1141 HW on rev 1.0.
  18558. + */
  18559. +
  18560. +static int
  18561. +pci_map_linear(
  18562. + struct safe_softc *sc,
  18563. + struct safe_operand *buf,
  18564. + void *addr,
  18565. + int len)
  18566. +{
  18567. + dma_addr_t tmp;
  18568. + int chunk, tlen = len;
  18569. +
  18570. + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
  18571. +
  18572. + buf->mapsize += len;
  18573. + while (len > 0) {
  18574. + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
  18575. + buf->segs[buf->nsegs].ds_addr = tmp;
  18576. + buf->segs[buf->nsegs].ds_len = chunk;
  18577. + buf->segs[buf->nsegs].ds_tlen = tlen;
  18578. + buf->nsegs++;
  18579. + tmp += chunk;
  18580. + len -= chunk;
  18581. + tlen = 0;
  18582. + }
  18583. + return 0;
  18584. +}
  18585. +
  18586. +/*
  18587. + * map in a given uio buffer (great on some arches :-)
  18588. + */
  18589. +
  18590. +static int
  18591. +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
  18592. +{
  18593. + struct iovec *iov = uio->uio_iov;
  18594. + int n;
  18595. +
  18596. + DPRINTF(("%s()\n", __FUNCTION__));
  18597. +
  18598. + buf->mapsize = 0;
  18599. + buf->nsegs = 0;
  18600. +
  18601. + for (n = 0; n < uio->uio_iovcnt; n++) {
  18602. + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
  18603. + iov++;
  18604. + }
  18605. +
  18606. + /* identify this buffer by the first segment */
  18607. + buf->map = (void *) buf->segs[0].ds_addr;
  18608. + return(0);
  18609. +}
  18610. +
  18611. +/*
  18612. + * map in a given sk_buff
  18613. + */
  18614. +
  18615. +static int
  18616. +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
  18617. +{
  18618. + int i;
  18619. +
  18620. + DPRINTF(("%s()\n", __FUNCTION__));
  18621. +
  18622. + buf->mapsize = 0;
  18623. + buf->nsegs = 0;
  18624. +
  18625. + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
  18626. +
  18627. + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
  18628. + pci_map_linear(sc, buf,
  18629. + page_address(skb_shinfo(skb)->frags[i].page) +
  18630. + skb_shinfo(skb)->frags[i].page_offset,
  18631. + skb_shinfo(skb)->frags[i].size);
  18632. + }
  18633. +
  18634. + /* identify this buffer by the first segment */
  18635. + buf->map = (void *) buf->segs[0].ds_addr;
  18636. + return(0);
  18637. +}
  18638. +
  18639. +
  18640. +#if 0 /* not needed at this time */
  18641. +static void
  18642. +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
  18643. +{
  18644. + int i;
  18645. +
  18646. + DPRINTF(("%s()\n", __FUNCTION__));
  18647. + for (i = 0; i < buf->nsegs; i++)
  18648. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  18649. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  18650. +}
  18651. +#endif
  18652. +
  18653. +static void
  18654. +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
  18655. +{
  18656. + int i;
  18657. + DPRINTF(("%s()\n", __FUNCTION__));
  18658. + for (i = 0; i < buf->nsegs; i++) {
  18659. + if (buf->segs[i].ds_tlen) {
  18660. + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  18661. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  18662. + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
  18663. + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  18664. + }
  18665. + buf->segs[i].ds_addr = 0;
  18666. + buf->segs[i].ds_len = 0;
  18667. + buf->segs[i].ds_tlen = 0;
  18668. + }
  18669. + buf->nsegs = 0;
  18670. + buf->mapsize = 0;
  18671. + buf->map = 0;
  18672. +}
  18673. +
  18674. +
  18675. +/*
  18676. + * SafeXcel Interrupt routine
  18677. + */
  18678. +static irqreturn_t
  18679. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  18680. +safe_intr(int irq, void *arg)
  18681. +#else
  18682. +safe_intr(int irq, void *arg, struct pt_regs *regs)
  18683. +#endif
  18684. +{
  18685. + struct safe_softc *sc = arg;
  18686. + int stat;
  18687. + unsigned long flags;
  18688. +
  18689. + stat = READ_REG(sc, SAFE_HM_STAT);
  18690. +
  18691. + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
  18692. +
  18693. + if (stat == 0) /* shared irq, not for us */
  18694. + return IRQ_NONE;
  18695. +
  18696. + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
  18697. +
  18698. + if ((stat & SAFE_INT_PE_DDONE)) {
  18699. + /*
  18700. + * Descriptor(s) done; scan the ring and
  18701. + * process completed operations.
  18702. + */
  18703. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  18704. + while (sc->sc_back != sc->sc_front) {
  18705. + struct safe_ringentry *re = sc->sc_back;
  18706. +
  18707. +#ifdef SAFE_DEBUG
  18708. + if (debug) {
  18709. + safe_dump_ringstate(sc, __func__);
  18710. + safe_dump_request(sc, __func__, re);
  18711. + }
  18712. +#endif
  18713. + /*
  18714. + * safe_process marks ring entries that were allocated
  18715. + * but not used with a csr of zero. This insures the
  18716. + * ring front pointer never needs to be set backwards
  18717. + * in the event that an entry is allocated but not used
  18718. + * because of a setup error.
  18719. + */
  18720. + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
  18721. + if (re->re_desc.d_csr != 0) {
  18722. + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
  18723. + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
  18724. + break;
  18725. + }
  18726. + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
  18727. + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
  18728. + break;
  18729. + }
  18730. + sc->sc_nqchip--;
  18731. + safe_callback(sc, re);
  18732. + }
  18733. + if (++(sc->sc_back) == sc->sc_ringtop)
  18734. + sc->sc_back = sc->sc_ring;
  18735. + }
  18736. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  18737. + }
  18738. +
  18739. + /*
  18740. + * Check to see if we got any DMA Error
  18741. + */
  18742. + if (stat & SAFE_INT_PE_ERROR) {
  18743. + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
  18744. + (int)READ_REG(sc, SAFE_PE_DMASTAT));
  18745. + safestats.st_dmaerr++;
  18746. + safe_totalreset(sc);
  18747. +#if 0
  18748. + safe_feed(sc);
  18749. +#endif
  18750. + }
  18751. +
  18752. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  18753. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  18754. + DPRINTF(("%s: wakeup crypto %x\n", __func__,
  18755. + sc->sc_needwakeup));
  18756. + sc->sc_needwakeup &= ~wakeup;
  18757. + crypto_unblock(sc->sc_cid, wakeup);
  18758. + }
  18759. +
  18760. + return IRQ_HANDLED;
  18761. +}
  18762. +
  18763. +/*
  18764. + * safe_feed() - post a request to chip
  18765. + */
  18766. +static void
  18767. +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
  18768. +{
  18769. + DPRINTF(("%s()\n", __FUNCTION__));
  18770. +#ifdef SAFE_DEBUG
  18771. + if (debug) {
  18772. + safe_dump_ringstate(sc, __func__);
  18773. + safe_dump_request(sc, __func__, re);
  18774. + }
  18775. +#endif
  18776. + sc->sc_nqchip++;
  18777. + if (sc->sc_nqchip > safestats.st_maxqchip)
  18778. + safestats.st_maxqchip = sc->sc_nqchip;
  18779. + /* poke h/w to check descriptor ring, any value can be written */
  18780. + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
  18781. +}
  18782. +
  18783. +#define N(a) (sizeof(a) / sizeof (a[0]))
  18784. +static void
  18785. +safe_setup_enckey(struct safe_session *ses, caddr_t key)
  18786. +{
  18787. + int i;
  18788. +
  18789. + bcopy(key, ses->ses_key, ses->ses_klen / 8);
  18790. +
  18791. + /* PE is little-endian, insure proper byte order */
  18792. + for (i = 0; i < N(ses->ses_key); i++)
  18793. + ses->ses_key[i] = htole32(ses->ses_key[i]);
  18794. +}
  18795. +
  18796. +static void
  18797. +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
  18798. +{
  18799. +#ifdef HMAC_HACK
  18800. + MD5_CTX md5ctx;
  18801. + SHA1_CTX sha1ctx;
  18802. + int i;
  18803. +
  18804. +
  18805. + for (i = 0; i < klen; i++)
  18806. + key[i] ^= HMAC_IPAD_VAL;
  18807. +
  18808. + if (algo == CRYPTO_MD5_HMAC) {
  18809. + MD5Init(&md5ctx);
  18810. + MD5Update(&md5ctx, key, klen);
  18811. + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  18812. + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
  18813. + } else {
  18814. + SHA1Init(&sha1ctx);
  18815. + SHA1Update(&sha1ctx, key, klen);
  18816. + SHA1Update(&sha1ctx, hmac_ipad_buffer,
  18817. + SHA1_HMAC_BLOCK_LEN - klen);
  18818. + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
  18819. + }
  18820. +
  18821. + for (i = 0; i < klen; i++)
  18822. + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  18823. +
  18824. + if (algo == CRYPTO_MD5_HMAC) {
  18825. + MD5Init(&md5ctx);
  18826. + MD5Update(&md5ctx, key, klen);
  18827. + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  18828. + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
  18829. + } else {
  18830. + SHA1Init(&sha1ctx);
  18831. + SHA1Update(&sha1ctx, key, klen);
  18832. + SHA1Update(&sha1ctx, hmac_opad_buffer,
  18833. + SHA1_HMAC_BLOCK_LEN - klen);
  18834. + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
  18835. + }
  18836. +
  18837. + for (i = 0; i < klen; i++)
  18838. + key[i] ^= HMAC_OPAD_VAL;
  18839. +
  18840. +#if 0
  18841. + /*
  18842. + * this code prevents SHA working on a BE host,
  18843. + * so it is obviously wrong. I think the byte
  18844. + * swap setup we do with the chip fixes this for us
  18845. + */
  18846. +
  18847. + /* PE is little-endian, insure proper byte order */
  18848. + for (i = 0; i < N(ses->ses_hminner); i++) {
  18849. + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
  18850. + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
  18851. + }
  18852. +#endif
  18853. +#else /* HMAC_HACK */
  18854. + printk("safe: md5/sha not implemented\n");
  18855. +#endif /* HMAC_HACK */
  18856. +}
  18857. +#undef N
  18858. +
  18859. +/*
  18860. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  18861. + * contains our registration id, and should contain an encoded session
  18862. + * id on successful allocation.
  18863. + */
  18864. +static int
  18865. +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  18866. +{
  18867. + struct safe_softc *sc = device_get_softc(dev);
  18868. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  18869. + struct safe_session *ses = NULL;
  18870. + int sesn;
  18871. +
  18872. + DPRINTF(("%s()\n", __FUNCTION__));
  18873. +
  18874. + if (sidp == NULL || cri == NULL || sc == NULL)
  18875. + return (EINVAL);
  18876. +
  18877. + for (c = cri; c != NULL; c = c->cri_next) {
  18878. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  18879. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  18880. + c->cri_alg == CRYPTO_NULL_HMAC) {
  18881. + if (macini)
  18882. + return (EINVAL);
  18883. + macini = c;
  18884. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  18885. + c->cri_alg == CRYPTO_3DES_CBC ||
  18886. + c->cri_alg == CRYPTO_AES_CBC ||
  18887. + c->cri_alg == CRYPTO_NULL_CBC) {
  18888. + if (encini)
  18889. + return (EINVAL);
  18890. + encini = c;
  18891. + } else
  18892. + return (EINVAL);
  18893. + }
  18894. + if (encini == NULL && macini == NULL)
  18895. + return (EINVAL);
  18896. + if (encini) { /* validate key length */
  18897. + switch (encini->cri_alg) {
  18898. + case CRYPTO_DES_CBC:
  18899. + if (encini->cri_klen != 64)
  18900. + return (EINVAL);
  18901. + break;
  18902. + case CRYPTO_3DES_CBC:
  18903. + if (encini->cri_klen != 192)
  18904. + return (EINVAL);
  18905. + break;
  18906. + case CRYPTO_AES_CBC:
  18907. + if (encini->cri_klen != 128 &&
  18908. + encini->cri_klen != 192 &&
  18909. + encini->cri_klen != 256)
  18910. + return (EINVAL);
  18911. + break;
  18912. + }
  18913. + }
  18914. +
  18915. + if (sc->sc_sessions == NULL) {
  18916. + ses = sc->sc_sessions = (struct safe_session *)
  18917. + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
  18918. + if (ses == NULL)
  18919. + return (ENOMEM);
  18920. + memset(ses, 0, sizeof(struct safe_session));
  18921. + sesn = 0;
  18922. + sc->sc_nsessions = 1;
  18923. + } else {
  18924. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  18925. + if (sc->sc_sessions[sesn].ses_used == 0) {
  18926. + ses = &sc->sc_sessions[sesn];
  18927. + break;
  18928. + }
  18929. + }
  18930. +
  18931. + if (ses == NULL) {
  18932. + sesn = sc->sc_nsessions;
  18933. + ses = (struct safe_session *)
  18934. + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
  18935. + if (ses == NULL)
  18936. + return (ENOMEM);
  18937. + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
  18938. + bcopy(sc->sc_sessions, ses, sesn *
  18939. + sizeof(struct safe_session));
  18940. + bzero(sc->sc_sessions, sesn *
  18941. + sizeof(struct safe_session));
  18942. + kfree(sc->sc_sessions);
  18943. + sc->sc_sessions = ses;
  18944. + ses = &sc->sc_sessions[sesn];
  18945. + sc->sc_nsessions++;
  18946. + }
  18947. + }
  18948. +
  18949. + bzero(ses, sizeof(struct safe_session));
  18950. + ses->ses_used = 1;
  18951. +
  18952. + if (encini) {
  18953. + /* get an IV */
  18954. + /* XXX may read fewer than requested */
  18955. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  18956. +
  18957. + ses->ses_klen = encini->cri_klen;
  18958. + if (encini->cri_key != NULL)
  18959. + safe_setup_enckey(ses, encini->cri_key);
  18960. + }
  18961. +
  18962. + if (macini) {
  18963. + ses->ses_mlen = macini->cri_mlen;
  18964. + if (ses->ses_mlen == 0) {
  18965. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  18966. + ses->ses_mlen = MD5_HASH_LEN;
  18967. + else
  18968. + ses->ses_mlen = SHA1_HASH_LEN;
  18969. + }
  18970. +
  18971. + if (macini->cri_key != NULL) {
  18972. + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
  18973. + macini->cri_klen / 8);
  18974. + }
  18975. + }
  18976. +
  18977. + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
  18978. + return (0);
  18979. +}
  18980. +
  18981. +/*
  18982. + * Deallocate a session.
  18983. + */
  18984. +static int
  18985. +safe_freesession(device_t dev, u_int64_t tid)
  18986. +{
  18987. + struct safe_softc *sc = device_get_softc(dev);
  18988. + int session, ret;
  18989. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  18990. +
  18991. + DPRINTF(("%s()\n", __FUNCTION__));
  18992. +
  18993. + if (sc == NULL)
  18994. + return (EINVAL);
  18995. +
  18996. + session = SAFE_SESSION(sid);
  18997. + if (session < sc->sc_nsessions) {
  18998. + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
  18999. + ret = 0;
  19000. + } else
  19001. + ret = EINVAL;
  19002. + return (ret);
  19003. +}
  19004. +
  19005. +
  19006. +static int
  19007. +safe_process(device_t dev, struct cryptop *crp, int hint)
  19008. +{
  19009. + struct safe_softc *sc = device_get_softc(dev);
  19010. + int err = 0, i, nicealign, uniform;
  19011. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  19012. + int bypass, oplen, ivsize;
  19013. + caddr_t iv;
  19014. + int16_t coffset;
  19015. + struct safe_session *ses;
  19016. + struct safe_ringentry *re;
  19017. + struct safe_sarec *sa;
  19018. + struct safe_pdesc *pd;
  19019. + u_int32_t cmd0, cmd1, staterec;
  19020. + unsigned long flags;
  19021. +
  19022. + DPRINTF(("%s()\n", __FUNCTION__));
  19023. +
  19024. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  19025. + safestats.st_invalid++;
  19026. + return (EINVAL);
  19027. + }
  19028. + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  19029. + safestats.st_badsession++;
  19030. + return (EINVAL);
  19031. + }
  19032. +
  19033. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  19034. + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
  19035. + safestats.st_ringfull++;
  19036. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  19037. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  19038. + return (ERESTART);
  19039. + }
  19040. + re = sc->sc_front;
  19041. +
  19042. + staterec = re->re_sa.sa_staterec; /* save */
  19043. + /* NB: zero everything but the PE descriptor */
  19044. + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
  19045. + re->re_sa.sa_staterec = staterec; /* restore */
  19046. +
  19047. + re->re_crp = crp;
  19048. + re->re_sesn = SAFE_SESSION(crp->crp_sid);
  19049. +
  19050. + re->re_src.nsegs = 0;
  19051. + re->re_dst.nsegs = 0;
  19052. +
  19053. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  19054. + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
  19055. + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
  19056. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  19057. + re->re_src_io = (struct uio *)crp->crp_buf;
  19058. + re->re_dst_io = (struct uio *)crp->crp_buf;
  19059. + } else {
  19060. + safestats.st_badflags++;
  19061. + err = EINVAL;
  19062. + goto errout; /* XXX we don't handle contiguous blocks! */
  19063. + }
  19064. +
  19065. + sa = &re->re_sa;
  19066. + ses = &sc->sc_sessions[re->re_sesn];
  19067. +
  19068. + crd1 = crp->crp_desc;
  19069. + if (crd1 == NULL) {
  19070. + safestats.st_nodesc++;
  19071. + err = EINVAL;
  19072. + goto errout;
  19073. + }
  19074. + crd2 = crd1->crd_next;
  19075. +
  19076. + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
  19077. + cmd1 = 0;
  19078. + if (crd2 == NULL) {
  19079. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  19080. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  19081. + crd1->crd_alg == CRYPTO_NULL_HMAC) {
  19082. + maccrd = crd1;
  19083. + enccrd = NULL;
  19084. + cmd0 |= SAFE_SA_CMD0_OP_HASH;
  19085. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  19086. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  19087. + crd1->crd_alg == CRYPTO_AES_CBC ||
  19088. + crd1->crd_alg == CRYPTO_NULL_CBC) {
  19089. + maccrd = NULL;
  19090. + enccrd = crd1;
  19091. + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
  19092. + } else {
  19093. + safestats.st_badalg++;
  19094. + err = EINVAL;
  19095. + goto errout;
  19096. + }
  19097. + } else {
  19098. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  19099. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  19100. + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
  19101. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  19102. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  19103. + crd2->crd_alg == CRYPTO_AES_CBC ||
  19104. + crd2->crd_alg == CRYPTO_NULL_CBC) &&
  19105. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  19106. + maccrd = crd1;
  19107. + enccrd = crd2;
  19108. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  19109. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  19110. + crd1->crd_alg == CRYPTO_AES_CBC ||
  19111. + crd1->crd_alg == CRYPTO_NULL_CBC) &&
  19112. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  19113. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  19114. + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
  19115. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  19116. + enccrd = crd1;
  19117. + maccrd = crd2;
  19118. + } else {
  19119. + safestats.st_badalg++;
  19120. + err = EINVAL;
  19121. + goto errout;
  19122. + }
  19123. + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
  19124. + }
  19125. +
  19126. + if (enccrd) {
  19127. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  19128. + safe_setup_enckey(ses, enccrd->crd_key);
  19129. +
  19130. + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
  19131. + cmd0 |= SAFE_SA_CMD0_DES;
  19132. + cmd1 |= SAFE_SA_CMD1_CBC;
  19133. + ivsize = 2*sizeof(u_int32_t);
  19134. + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
  19135. + cmd0 |= SAFE_SA_CMD0_3DES;
  19136. + cmd1 |= SAFE_SA_CMD1_CBC;
  19137. + ivsize = 2*sizeof(u_int32_t);
  19138. + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
  19139. + cmd0 |= SAFE_SA_CMD0_AES;
  19140. + cmd1 |= SAFE_SA_CMD1_CBC;
  19141. + if (ses->ses_klen == 128)
  19142. + cmd1 |= SAFE_SA_CMD1_AES128;
  19143. + else if (ses->ses_klen == 192)
  19144. + cmd1 |= SAFE_SA_CMD1_AES192;
  19145. + else
  19146. + cmd1 |= SAFE_SA_CMD1_AES256;
  19147. + ivsize = 4*sizeof(u_int32_t);
  19148. + } else {
  19149. + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
  19150. + ivsize = 0;
  19151. + }
  19152. +
  19153. + /*
  19154. + * Setup encrypt/decrypt state. When using basic ops
  19155. + * we can't use an inline IV because hash/crypt offset
  19156. + * must be from the end of the IV to the start of the
  19157. + * crypt data and this leaves out the preceding header
  19158. + * from the hash calculation. Instead we place the IV
  19159. + * in the state record and set the hash/crypt offset to
  19160. + * copy both the header+IV.
  19161. + */
  19162. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  19163. + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
  19164. +
  19165. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  19166. + iv = enccrd->crd_iv;
  19167. + else
  19168. + iv = (caddr_t) ses->ses_iv;
  19169. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  19170. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  19171. + enccrd->crd_inject, ivsize, iv);
  19172. + }
  19173. + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
  19174. + /* make iv LE */
  19175. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  19176. + re->re_sastate.sa_saved_iv[i] =
  19177. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  19178. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
  19179. + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
  19180. + } else {
  19181. + cmd0 |= SAFE_SA_CMD0_INBOUND;
  19182. +
  19183. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  19184. + bcopy(enccrd->crd_iv,
  19185. + re->re_sastate.sa_saved_iv, ivsize);
  19186. + } else {
  19187. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  19188. + enccrd->crd_inject, ivsize,
  19189. + (caddr_t)re->re_sastate.sa_saved_iv);
  19190. + }
  19191. + /* make iv LE */
  19192. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  19193. + re->re_sastate.sa_saved_iv[i] =
  19194. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  19195. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
  19196. + }
  19197. + /*
  19198. + * For basic encryption use the zero pad algorithm.
  19199. + * This pads results to an 8-byte boundary and
  19200. + * suppresses padding verification for inbound (i.e.
  19201. + * decrypt) operations.
  19202. + *
  19203. + * NB: Not sure if the 8-byte pad boundary is a problem.
  19204. + */
  19205. + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
  19206. +
  19207. + /* XXX assert key bufs have the same size */
  19208. + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
  19209. + }
  19210. +
  19211. + if (maccrd) {
  19212. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  19213. + safe_setup_mackey(ses, maccrd->crd_alg,
  19214. + maccrd->crd_key, maccrd->crd_klen / 8);
  19215. + }
  19216. +
  19217. + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  19218. + cmd0 |= SAFE_SA_CMD0_MD5;
  19219. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  19220. + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
  19221. + cmd0 |= SAFE_SA_CMD0_SHA1;
  19222. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  19223. + } else {
  19224. + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
  19225. + }
  19226. + /*
  19227. + * Digest data is loaded from the SA and the hash
  19228. + * result is saved to the state block where we
  19229. + * retrieve it for return to the caller.
  19230. + */
  19231. + /* XXX assert digest bufs have the same size */
  19232. + bcopy(ses->ses_hminner, sa->sa_indigest,
  19233. + sizeof(sa->sa_indigest));
  19234. + bcopy(ses->ses_hmouter, sa->sa_outdigest,
  19235. + sizeof(sa->sa_outdigest));
  19236. +
  19237. + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
  19238. + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
  19239. + }
  19240. +
  19241. + if (enccrd && maccrd) {
  19242. + /*
  19243. + * The offset from hash data to the start of
  19244. + * crypt data is the difference in the skips.
  19245. + */
  19246. + bypass = maccrd->crd_skip;
  19247. + coffset = enccrd->crd_skip - maccrd->crd_skip;
  19248. + if (coffset < 0) {
  19249. + DPRINTF(("%s: hash does not precede crypt; "
  19250. + "mac skip %u enc skip %u\n",
  19251. + __func__, maccrd->crd_skip, enccrd->crd_skip));
  19252. + safestats.st_skipmismatch++;
  19253. + err = EINVAL;
  19254. + goto errout;
  19255. + }
  19256. + oplen = enccrd->crd_skip + enccrd->crd_len;
  19257. + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
  19258. + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
  19259. + __func__, maccrd->crd_skip + maccrd->crd_len,
  19260. + oplen));
  19261. + safestats.st_lenmismatch++;
  19262. + err = EINVAL;
  19263. + goto errout;
  19264. + }
  19265. +#ifdef SAFE_DEBUG
  19266. + if (debug) {
  19267. + printf("mac: skip %d, len %d, inject %d\n",
  19268. + maccrd->crd_skip, maccrd->crd_len,
  19269. + maccrd->crd_inject);
  19270. + printf("enc: skip %d, len %d, inject %d\n",
  19271. + enccrd->crd_skip, enccrd->crd_len,
  19272. + enccrd->crd_inject);
  19273. + printf("bypass %d coffset %d oplen %d\n",
  19274. + bypass, coffset, oplen);
  19275. + }
  19276. +#endif
  19277. + if (coffset & 3) { /* offset must be 32-bit aligned */
  19278. + DPRINTF(("%s: coffset %u misaligned\n",
  19279. + __func__, coffset));
  19280. + safestats.st_coffmisaligned++;
  19281. + err = EINVAL;
  19282. + goto errout;
  19283. + }
  19284. + coffset >>= 2;
  19285. + if (coffset > 255) { /* offset must be <256 dwords */
  19286. + DPRINTF(("%s: coffset %u too big\n",
  19287. + __func__, coffset));
  19288. + safestats.st_cofftoobig++;
  19289. + err = EINVAL;
  19290. + goto errout;
  19291. + }
  19292. + /*
  19293. + * Tell the hardware to copy the header to the output.
  19294. + * The header is defined as the data from the end of
  19295. + * the bypass to the start of data to be encrypted.
  19296. + * Typically this is the inline IV. Note that you need
  19297. + * to do this even if src+dst are the same; it appears
  19298. + * that w/o this bit the crypted data is written
  19299. + * immediately after the bypass data.
  19300. + */
  19301. + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
  19302. + /*
  19303. + * Disable IP header mutable bit handling. This is
  19304. + * needed to get correct HMAC calculations.
  19305. + */
  19306. + cmd1 |= SAFE_SA_CMD1_MUTABLE;
  19307. + } else {
  19308. + if (enccrd) {
  19309. + bypass = enccrd->crd_skip;
  19310. + oplen = bypass + enccrd->crd_len;
  19311. + } else {
  19312. + bypass = maccrd->crd_skip;
  19313. + oplen = bypass + maccrd->crd_len;
  19314. + }
  19315. + coffset = 0;
  19316. + }
  19317. + /* XXX verify multiple of 4 when using s/g */
  19318. + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
  19319. + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
  19320. + safestats.st_bypasstoobig++;
  19321. + err = EINVAL;
  19322. + goto errout;
  19323. + }
  19324. +
  19325. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  19326. + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
  19327. + safestats.st_noload++;
  19328. + err = ENOMEM;
  19329. + goto errout;
  19330. + }
  19331. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  19332. + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
  19333. + safestats.st_noload++;
  19334. + err = ENOMEM;
  19335. + goto errout;
  19336. + }
  19337. + }
  19338. + nicealign = safe_dmamap_aligned(sc, &re->re_src);
  19339. + uniform = safe_dmamap_uniform(sc, &re->re_src);
  19340. +
  19341. + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
  19342. + nicealign, uniform, re->re_src.nsegs));
  19343. + if (re->re_src.nsegs > 1) {
  19344. + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
  19345. + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
  19346. + for (i = 0; i < re->re_src_nsegs; i++) {
  19347. + /* NB: no need to check if there's space */
  19348. + pd = sc->sc_spfree;
  19349. + if (++(sc->sc_spfree) == sc->sc_springtop)
  19350. + sc->sc_spfree = sc->sc_spring;
  19351. +
  19352. + KASSERT((pd->pd_flags&3) == 0 ||
  19353. + (pd->pd_flags&3) == SAFE_PD_DONE,
  19354. + ("bogus source particle descriptor; flags %x",
  19355. + pd->pd_flags));
  19356. + pd->pd_addr = re->re_src_segs[i].ds_addr;
  19357. + pd->pd_size = re->re_src_segs[i].ds_len;
  19358. + pd->pd_flags = SAFE_PD_READY;
  19359. + }
  19360. + cmd0 |= SAFE_SA_CMD0_IGATHER;
  19361. + } else {
  19362. + /*
  19363. + * No need for gather, reference the operand directly.
  19364. + */
  19365. + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
  19366. + }
  19367. +
  19368. + if (enccrd == NULL && maccrd != NULL) {
  19369. + /*
  19370. + * Hash op; no destination needed.
  19371. + */
  19372. + } else {
  19373. + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
  19374. + if (!nicealign) {
  19375. + safestats.st_iovmisaligned++;
  19376. + err = EINVAL;
  19377. + goto errout;
  19378. + }
  19379. + if (uniform != 1) {
  19380. + device_printf(sc->sc_dev, "!uniform source\n");
  19381. + if (!uniform) {
  19382. + /*
  19383. + * There's no way to handle the DMA
  19384. + * requirements with this uio. We
  19385. + * could create a separate DMA area for
  19386. + * the result and then copy it back,
  19387. + * but for now we just bail and return
  19388. + * an error. Note that uio requests
  19389. + * > SAFE_MAX_DSIZE are handled because
  19390. + * the DMA map and segment list for the
  19391. + * destination wil result in a
  19392. + * destination particle list that does
  19393. + * the necessary scatter DMA.
  19394. + */
  19395. + safestats.st_iovnotuniform++;
  19396. + err = EINVAL;
  19397. + goto errout;
  19398. + }
  19399. + } else
  19400. + re->re_dst = re->re_src;
  19401. + } else {
  19402. + safestats.st_badflags++;
  19403. + err = EINVAL;
  19404. + goto errout;
  19405. + }
  19406. +
  19407. + if (re->re_dst.nsegs > 1) {
  19408. + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
  19409. + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
  19410. + for (i = 0; i < re->re_dst_nsegs; i++) {
  19411. + pd = sc->sc_dpfree;
  19412. + KASSERT((pd->pd_flags&3) == 0 ||
  19413. + (pd->pd_flags&3) == SAFE_PD_DONE,
  19414. + ("bogus dest particle descriptor; flags %x",
  19415. + pd->pd_flags));
  19416. + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
  19417. + sc->sc_dpfree = sc->sc_dpring;
  19418. + pd->pd_addr = re->re_dst_segs[i].ds_addr;
  19419. + pd->pd_flags = SAFE_PD_READY;
  19420. + }
  19421. + cmd0 |= SAFE_SA_CMD0_OSCATTER;
  19422. + } else {
  19423. + /*
  19424. + * No need for scatter, reference the operand directly.
  19425. + */
  19426. + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
  19427. + }
  19428. + }
  19429. +
  19430. + /*
  19431. + * All done with setup; fillin the SA command words
  19432. + * and the packet engine descriptor. The operation
  19433. + * is now ready for submission to the hardware.
  19434. + */
  19435. + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
  19436. + sa->sa_cmd1 = cmd1
  19437. + | (coffset << SAFE_SA_CMD1_OFFSET_S)
  19438. + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
  19439. + | SAFE_SA_CMD1_SRPCI
  19440. + ;
  19441. + /*
  19442. + * NB: the order of writes is important here. In case the
  19443. + * chip is scanning the ring because of an outstanding request
  19444. + * it might nab this one too. In that case we need to make
  19445. + * sure the setup is complete before we write the length
  19446. + * field of the descriptor as it signals the descriptor is
  19447. + * ready for processing.
  19448. + */
  19449. + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
  19450. + if (maccrd)
  19451. + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
  19452. + wmb();
  19453. + re->re_desc.d_len = oplen
  19454. + | SAFE_PE_LEN_READY
  19455. + | (bypass << SAFE_PE_LEN_BYPASS_S)
  19456. + ;
  19457. +
  19458. + safestats.st_ipackets++;
  19459. + safestats.st_ibytes += oplen;
  19460. +
  19461. + if (++(sc->sc_front) == sc->sc_ringtop)
  19462. + sc->sc_front = sc->sc_ring;
  19463. +
  19464. + /* XXX honor batching */
  19465. + safe_feed(sc, re);
  19466. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  19467. + return (0);
  19468. +
  19469. +errout:
  19470. + if (re->re_src.map != re->re_dst.map)
  19471. + pci_unmap_operand(sc, &re->re_dst);
  19472. + if (re->re_src.map)
  19473. + pci_unmap_operand(sc, &re->re_src);
  19474. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  19475. + if (err != ERESTART) {
  19476. + crp->crp_etype = err;
  19477. + crypto_done(crp);
  19478. + } else {
  19479. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  19480. + }
  19481. + return (err);
  19482. +}
  19483. +
  19484. +static void
  19485. +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
  19486. +{
  19487. + struct cryptop *crp = (struct cryptop *)re->re_crp;
  19488. + struct cryptodesc *crd;
  19489. +
  19490. + DPRINTF(("%s()\n", __FUNCTION__));
  19491. +
  19492. + safestats.st_opackets++;
  19493. + safestats.st_obytes += re->re_dst.mapsize;
  19494. +
  19495. + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
  19496. + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
  19497. + re->re_desc.d_csr,
  19498. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
  19499. + safestats.st_peoperr++;
  19500. + crp->crp_etype = EIO; /* something more meaningful? */
  19501. + }
  19502. +
  19503. + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
  19504. + pci_unmap_operand(sc, &re->re_dst);
  19505. + pci_unmap_operand(sc, &re->re_src);
  19506. +
  19507. + /*
  19508. + * If result was written to a differet mbuf chain, swap
  19509. + * it in as the return value and reclaim the original.
  19510. + */
  19511. + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
  19512. + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
  19513. + /* kfree_skb(skb) */
  19514. + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
  19515. + return;
  19516. + }
  19517. +
  19518. + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
  19519. + /* copy out IV for future use */
  19520. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  19521. + int i;
  19522. + int ivsize;
  19523. +
  19524. + if (crd->crd_alg == CRYPTO_DES_CBC ||
  19525. + crd->crd_alg == CRYPTO_3DES_CBC) {
  19526. + ivsize = 2*sizeof(u_int32_t);
  19527. + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
  19528. + ivsize = 4*sizeof(u_int32_t);
  19529. + } else
  19530. + continue;
  19531. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  19532. + crd->crd_skip + crd->crd_len - ivsize, ivsize,
  19533. + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
  19534. + for (i = 0;
  19535. + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
  19536. + i++)
  19537. + sc->sc_sessions[re->re_sesn].ses_iv[i] =
  19538. + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
  19539. + break;
  19540. + }
  19541. + }
  19542. +
  19543. + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
  19544. + /* copy out ICV result */
  19545. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  19546. + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
  19547. + crd->crd_alg == CRYPTO_SHA1_HMAC ||
  19548. + crd->crd_alg == CRYPTO_NULL_HMAC))
  19549. + continue;
  19550. + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
  19551. + /*
  19552. + * SHA-1 ICV's are byte-swapped; fix 'em up
  19553. + * before copy them to their destination.
  19554. + */
  19555. + re->re_sastate.sa_saved_indigest[0] =
  19556. + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
  19557. + re->re_sastate.sa_saved_indigest[1] =
  19558. + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
  19559. + re->re_sastate.sa_saved_indigest[2] =
  19560. + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
  19561. + } else {
  19562. + re->re_sastate.sa_saved_indigest[0] =
  19563. + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
  19564. + re->re_sastate.sa_saved_indigest[1] =
  19565. + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
  19566. + re->re_sastate.sa_saved_indigest[2] =
  19567. + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
  19568. + }
  19569. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  19570. + crd->crd_inject,
  19571. + sc->sc_sessions[re->re_sesn].ses_mlen,
  19572. + (caddr_t)re->re_sastate.sa_saved_indigest);
  19573. + break;
  19574. + }
  19575. + }
  19576. + crypto_done(crp);
  19577. +}
  19578. +
  19579. +
  19580. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  19581. +#define SAFE_RNG_MAXWAIT 1000
  19582. +
  19583. +static void
  19584. +safe_rng_init(struct safe_softc *sc)
  19585. +{
  19586. + u_int32_t w, v;
  19587. + int i;
  19588. +
  19589. + DPRINTF(("%s()\n", __FUNCTION__));
  19590. +
  19591. + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
  19592. + /* use default value according to the manual */
  19593. + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
  19594. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  19595. +
  19596. + /*
  19597. + * There is a bug in rev 1.0 of the 1140 that when the RNG
  19598. + * is brought out of reset the ready status flag does not
  19599. + * work until the RNG has finished its internal initialization.
  19600. + *
  19601. + * So in order to determine the device is through its
  19602. + * initialization we must read the data register, using the
  19603. + * status reg in the read in case it is initialized. Then read
  19604. + * the data register until it changes from the first read.
  19605. + * Once it changes read the data register until it changes
  19606. + * again. At this time the RNG is considered initialized.
  19607. + * This could take between 750ms - 1000ms in time.
  19608. + */
  19609. + i = 0;
  19610. + w = READ_REG(sc, SAFE_RNG_OUT);
  19611. + do {
  19612. + v = READ_REG(sc, SAFE_RNG_OUT);
  19613. + if (v != w) {
  19614. + w = v;
  19615. + break;
  19616. + }
  19617. + DELAY(10);
  19618. + } while (++i < SAFE_RNG_MAXWAIT);
  19619. +
  19620. + /* Wait Until data changes again */
  19621. + i = 0;
  19622. + do {
  19623. + v = READ_REG(sc, SAFE_RNG_OUT);
  19624. + if (v != w)
  19625. + break;
  19626. + DELAY(10);
  19627. + } while (++i < SAFE_RNG_MAXWAIT);
  19628. +}
  19629. +
  19630. +static __inline void
  19631. +safe_rng_disable_short_cycle(struct safe_softc *sc)
  19632. +{
  19633. + DPRINTF(("%s()\n", __FUNCTION__));
  19634. +
  19635. + WRITE_REG(sc, SAFE_RNG_CTRL,
  19636. + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
  19637. +}
  19638. +
  19639. +static __inline void
  19640. +safe_rng_enable_short_cycle(struct safe_softc *sc)
  19641. +{
  19642. + DPRINTF(("%s()\n", __FUNCTION__));
  19643. +
  19644. + WRITE_REG(sc, SAFE_RNG_CTRL,
  19645. + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
  19646. +}
  19647. +
  19648. +static __inline u_int32_t
  19649. +safe_rng_read(struct safe_softc *sc)
  19650. +{
  19651. + int i;
  19652. +
  19653. + i = 0;
  19654. + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
  19655. + ;
  19656. + return READ_REG(sc, SAFE_RNG_OUT);
  19657. +}
  19658. +
  19659. +static int
  19660. +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
  19661. +{
  19662. + struct safe_softc *sc = (struct safe_softc *) arg;
  19663. + int i, rc;
  19664. +
  19665. + DPRINTF(("%s()\n", __FUNCTION__));
  19666. +
  19667. + safestats.st_rng++;
  19668. + /*
  19669. + * Fetch the next block of data.
  19670. + */
  19671. + if (maxwords > safe_rngbufsize)
  19672. + maxwords = safe_rngbufsize;
  19673. + if (maxwords > SAFE_RNG_MAXBUFSIZ)
  19674. + maxwords = SAFE_RNG_MAXBUFSIZ;
  19675. +retry:
  19676. + /* read as much as we can */
  19677. + for (rc = 0; rc < maxwords; rc++) {
  19678. + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
  19679. + break;
  19680. + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
  19681. + }
  19682. + if (rc == 0)
  19683. + return 0;
  19684. + /*
  19685. + * Check the comparator alarm count and reset the h/w if
  19686. + * it exceeds our threshold. This guards against the
  19687. + * hardware oscillators resonating with external signals.
  19688. + */
  19689. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
  19690. + u_int32_t freq_inc, w;
  19691. +
  19692. + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
  19693. + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
  19694. + safestats.st_rngalarm++;
  19695. + safe_rng_enable_short_cycle(sc);
  19696. + freq_inc = 18;
  19697. + for (i = 0; i < 64; i++) {
  19698. + w = READ_REG(sc, SAFE_RNG_CNFG);
  19699. + freq_inc = ((w + freq_inc) & 0x3fL);
  19700. + w = ((w & ~0x3fL) | freq_inc);
  19701. + WRITE_REG(sc, SAFE_RNG_CNFG, w);
  19702. +
  19703. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  19704. +
  19705. + (void) safe_rng_read(sc);
  19706. + DELAY(25);
  19707. +
  19708. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
  19709. + safe_rng_disable_short_cycle(sc);
  19710. + goto retry;
  19711. + }
  19712. + freq_inc = 1;
  19713. + }
  19714. + safe_rng_disable_short_cycle(sc);
  19715. + } else
  19716. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  19717. +
  19718. + return(rc);
  19719. +}
  19720. +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
  19721. +
  19722. +
  19723. +/*
  19724. + * Resets the board. Values in the regesters are left as is
  19725. + * from the reset (i.e. initial values are assigned elsewhere).
  19726. + */
  19727. +static void
  19728. +safe_reset_board(struct safe_softc *sc)
  19729. +{
  19730. + u_int32_t v;
  19731. + /*
  19732. + * Reset the device. The manual says no delay
  19733. + * is needed between marking and clearing reset.
  19734. + */
  19735. + DPRINTF(("%s()\n", __FUNCTION__));
  19736. +
  19737. + v = READ_REG(sc, SAFE_PE_DMACFG) &~
  19738. + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
  19739. + SAFE_PE_DMACFG_SGRESET);
  19740. + WRITE_REG(sc, SAFE_PE_DMACFG, v
  19741. + | SAFE_PE_DMACFG_PERESET
  19742. + | SAFE_PE_DMACFG_PDRRESET
  19743. + | SAFE_PE_DMACFG_SGRESET);
  19744. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  19745. +}
  19746. +
  19747. +/*
  19748. + * Initialize registers we need to touch only once.
  19749. + */
  19750. +static void
  19751. +safe_init_board(struct safe_softc *sc)
  19752. +{
  19753. + u_int32_t v, dwords;
  19754. +
  19755. + DPRINTF(("%s()\n", __FUNCTION__));
  19756. +
  19757. + v = READ_REG(sc, SAFE_PE_DMACFG);
  19758. + v &=~ ( SAFE_PE_DMACFG_PEMODE
  19759. + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
  19760. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  19761. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  19762. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  19763. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  19764. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  19765. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  19766. + );
  19767. + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
  19768. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  19769. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  19770. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  19771. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  19772. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  19773. +#if 0
  19774. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  19775. +#endif
  19776. + ;
  19777. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  19778. +
  19779. +#ifdef __BIG_ENDIAN
  19780. + /* tell the safenet that we are 4321 and not 1234 */
  19781. + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
  19782. +#endif
  19783. +
  19784. + if (sc->sc_chiprev == SAFE_REV(1,0)) {
  19785. + /*
  19786. + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
  19787. + * "target mode transfers" done while the chip is DMA'ing
  19788. + * >1020 bytes cause the hardware to lockup. To avoid this
  19789. + * we reduce the max PCI transfer size and use small source
  19790. + * particle descriptors (<= 256 bytes).
  19791. + */
  19792. + WRITE_REG(sc, SAFE_DMA_CFG, 256);
  19793. + device_printf(sc->sc_dev,
  19794. + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
  19795. + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
  19796. + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
  19797. + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
  19798. + sc->sc_max_dsize = 256;
  19799. + } else {
  19800. + sc->sc_max_dsize = SAFE_MAX_DSIZE;
  19801. + }
  19802. +
  19803. + /* NB: operands+results are overlaid */
  19804. + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
  19805. + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
  19806. + /*
  19807. + * Configure ring entry size and number of items in the ring.
  19808. + */
  19809. + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
  19810. + ("PE ring entry not 32-bit aligned!"));
  19811. + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
  19812. + WRITE_REG(sc, SAFE_PE_RINGCFG,
  19813. + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
  19814. + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
  19815. +
  19816. + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
  19817. + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
  19818. + WRITE_REG(sc, SAFE_PE_PARTSIZE,
  19819. + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
  19820. + /*
  19821. + * NB: destination particles are fixed size. We use
  19822. + * an mbuf cluster and require all results go to
  19823. + * clusters or smaller.
  19824. + */
  19825. + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
  19826. +
  19827. + /* it's now safe to enable PE mode, do it */
  19828. + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
  19829. +
  19830. + /*
  19831. + * Configure hardware to use level-triggered interrupts and
  19832. + * to interrupt after each descriptor is processed.
  19833. + */
  19834. + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
  19835. + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
  19836. + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
  19837. + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
  19838. +}
  19839. +
  19840. +
  19841. +/*
  19842. + * Clean up after a chip crash.
  19843. + * It is assumed that the caller in splimp()
  19844. + */
  19845. +static void
  19846. +safe_cleanchip(struct safe_softc *sc)
  19847. +{
  19848. + DPRINTF(("%s()\n", __FUNCTION__));
  19849. +
  19850. + if (sc->sc_nqchip != 0) {
  19851. + struct safe_ringentry *re = sc->sc_back;
  19852. +
  19853. + while (re != sc->sc_front) {
  19854. + if (re->re_desc.d_csr != 0)
  19855. + safe_free_entry(sc, re);
  19856. + if (++re == sc->sc_ringtop)
  19857. + re = sc->sc_ring;
  19858. + }
  19859. + sc->sc_back = re;
  19860. + sc->sc_nqchip = 0;
  19861. + }
  19862. +}
  19863. +
  19864. +/*
  19865. + * free a safe_q
  19866. + * It is assumed that the caller is within splimp().
  19867. + */
  19868. +static int
  19869. +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
  19870. +{
  19871. + struct cryptop *crp;
  19872. +
  19873. + DPRINTF(("%s()\n", __FUNCTION__));
  19874. +
  19875. + /*
  19876. + * Free header MCR
  19877. + */
  19878. + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
  19879. +#ifdef NOTYET
  19880. + m_freem(re->re_dst_m);
  19881. +#else
  19882. + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
  19883. +#endif
  19884. +
  19885. + crp = (struct cryptop *)re->re_crp;
  19886. +
  19887. + re->re_desc.d_csr = 0;
  19888. +
  19889. + crp->crp_etype = EFAULT;
  19890. + crypto_done(crp);
  19891. + return(0);
  19892. +}
  19893. +
  19894. +/*
  19895. + * Routine to reset the chip and clean up.
  19896. + * It is assumed that the caller is in splimp()
  19897. + */
  19898. +static void
  19899. +safe_totalreset(struct safe_softc *sc)
  19900. +{
  19901. + DPRINTF(("%s()\n", __FUNCTION__));
  19902. +
  19903. + safe_reset_board(sc);
  19904. + safe_init_board(sc);
  19905. + safe_cleanchip(sc);
  19906. +}
  19907. +
  19908. +/*
  19909. + * Is the operand suitable aligned for direct DMA. Each
  19910. + * segment must be aligned on a 32-bit boundary and all
  19911. + * but the last segment must be a multiple of 4 bytes.
  19912. + */
  19913. +static int
  19914. +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
  19915. +{
  19916. + int i;
  19917. +
  19918. + DPRINTF(("%s()\n", __FUNCTION__));
  19919. +
  19920. + for (i = 0; i < op->nsegs; i++) {
  19921. + if (op->segs[i].ds_addr & 3)
  19922. + return (0);
  19923. + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
  19924. + return (0);
  19925. + }
  19926. + return (1);
  19927. +}
  19928. +
  19929. +/*
  19930. + * Is the operand suitable for direct DMA as the destination
  19931. + * of an operation. The hardware requires that each ``particle''
  19932. + * but the last in an operation result have the same size. We
  19933. + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
  19934. + * 0 if some segment is not a multiple of of this size, 1 if all
  19935. + * segments are exactly this size, or 2 if segments are at worst
  19936. + * a multple of this size.
  19937. + */
  19938. +static int
  19939. +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
  19940. +{
  19941. + int result = 1;
  19942. +
  19943. + DPRINTF(("%s()\n", __FUNCTION__));
  19944. +
  19945. + if (op->nsegs > 0) {
  19946. + int i;
  19947. +
  19948. + for (i = 0; i < op->nsegs-1; i++) {
  19949. + if (op->segs[i].ds_len % sc->sc_max_dsize)
  19950. + return (0);
  19951. + if (op->segs[i].ds_len != sc->sc_max_dsize)
  19952. + result = 2;
  19953. + }
  19954. + }
  19955. + return (result);
  19956. +}
  19957. +
  19958. +static int
  19959. +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
  19960. +{
  19961. + struct safe_softc *sc = device_get_softc(dev);
  19962. + struct safe_pkq *q;
  19963. + unsigned long flags;
  19964. +
  19965. + DPRINTF(("%s()\n", __FUNCTION__));
  19966. +
  19967. + if (sc == NULL) {
  19968. + krp->krp_status = EINVAL;
  19969. + goto err;
  19970. + }
  19971. +
  19972. + if (krp->krp_op != CRK_MOD_EXP) {
  19973. + krp->krp_status = EOPNOTSUPP;
  19974. + goto err;
  19975. + }
  19976. +
  19977. + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  19978. + if (q == NULL) {
  19979. + krp->krp_status = ENOMEM;
  19980. + goto err;
  19981. + }
  19982. + memset(q, 0, sizeof(*q));
  19983. + q->pkq_krp = krp;
  19984. + INIT_LIST_HEAD(&q->pkq_list);
  19985. +
  19986. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  19987. + list_add_tail(&q->pkq_list, &sc->sc_pkq);
  19988. + safe_kfeed(sc);
  19989. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  19990. + return (0);
  19991. +
  19992. +err:
  19993. + crypto_kdone(krp);
  19994. + return (0);
  19995. +}
  19996. +
  19997. +#define SAFE_CRK_PARAM_BASE 0
  19998. +#define SAFE_CRK_PARAM_EXP 1
  19999. +#define SAFE_CRK_PARAM_MOD 2
  20000. +
  20001. +static int
  20002. +safe_kstart(struct safe_softc *sc)
  20003. +{
  20004. + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
  20005. + int exp_bits, mod_bits, base_bits;
  20006. + u_int32_t op, a_off, b_off, c_off, d_off;
  20007. +
  20008. + DPRINTF(("%s()\n", __FUNCTION__));
  20009. +
  20010. + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
  20011. + krp->krp_status = EINVAL;
  20012. + return (1);
  20013. + }
  20014. +
  20015. + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  20016. + if (base_bits > 2048)
  20017. + goto too_big;
  20018. + if (base_bits <= 0) /* 5. base not zero */
  20019. + goto too_small;
  20020. +
  20021. + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  20022. + if (exp_bits > 2048)
  20023. + goto too_big;
  20024. + if (exp_bits <= 0) /* 1. exponent word length > 0 */
  20025. + goto too_small; /* 4. exponent not zero */
  20026. +
  20027. + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  20028. + if (mod_bits > 2048)
  20029. + goto too_big;
  20030. + if (mod_bits <= 32) /* 2. modulus word length > 1 */
  20031. + goto too_small; /* 8. MSW of modulus != zero */
  20032. + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
  20033. + goto too_small;
  20034. + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
  20035. + goto bad_domain; /* 6. modulus is odd */
  20036. + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
  20037. + goto too_small; /* make sure result will fit */
  20038. +
  20039. + /* 7. modulus > base */
  20040. + if (mod_bits < base_bits)
  20041. + goto too_small;
  20042. + if (mod_bits == base_bits) {
  20043. + u_int8_t *basep, *modp;
  20044. + int i;
  20045. +
  20046. + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
  20047. + ((base_bits + 7) / 8) - 1;
  20048. + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
  20049. + ((mod_bits + 7) / 8) - 1;
  20050. +
  20051. + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
  20052. + if (*modp < *basep)
  20053. + goto too_small;
  20054. + if (*modp > *basep)
  20055. + break;
  20056. + }
  20057. + }
  20058. +
  20059. + /* And on the 9th step, he rested. */
  20060. +
  20061. + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
  20062. + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
  20063. + if (mod_bits > 1024) {
  20064. + op = SAFE_PK_FUNC_EXP4;
  20065. + a_off = 0x000;
  20066. + b_off = 0x100;
  20067. + c_off = 0x200;
  20068. + d_off = 0x300;
  20069. + } else {
  20070. + op = SAFE_PK_FUNC_EXP16;
  20071. + a_off = 0x000;
  20072. + b_off = 0x080;
  20073. + c_off = 0x100;
  20074. + d_off = 0x180;
  20075. + }
  20076. + sc->sc_pk_reslen = b_off - a_off;
  20077. + sc->sc_pk_resoff = d_off;
  20078. +
  20079. + /* A is exponent, B is modulus, C is base, D is result */
  20080. + safe_kload_reg(sc, a_off, b_off - a_off,
  20081. + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  20082. + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
  20083. + safe_kload_reg(sc, b_off, b_off - a_off,
  20084. + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  20085. + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
  20086. + safe_kload_reg(sc, c_off, b_off - a_off,
  20087. + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  20088. + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
  20089. + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
  20090. +
  20091. + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
  20092. +
  20093. + return (0);
  20094. +
  20095. +too_big:
  20096. + krp->krp_status = E2BIG;
  20097. + return (1);
  20098. +too_small:
  20099. + krp->krp_status = ERANGE;
  20100. + return (1);
  20101. +bad_domain:
  20102. + krp->krp_status = EDOM;
  20103. + return (1);
  20104. +}
  20105. +
  20106. +static int
  20107. +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
  20108. +{
  20109. + u_int plen = (cr->crp_nbits + 7) / 8;
  20110. + int i, sig = plen * 8;
  20111. + u_int8_t c, *p = cr->crp_p;
  20112. +
  20113. + DPRINTF(("%s()\n", __FUNCTION__));
  20114. +
  20115. + for (i = plen - 1; i >= 0; i--) {
  20116. + c = p[i];
  20117. + if (c != 0) {
  20118. + while ((c & 0x80) == 0) {
  20119. + sig--;
  20120. + c <<= 1;
  20121. + }
  20122. + break;
  20123. + }
  20124. + sig -= 8;
  20125. + }
  20126. + return (sig);
  20127. +}
  20128. +
  20129. +static void
  20130. +safe_kfeed(struct safe_softc *sc)
  20131. +{
  20132. + struct safe_pkq *q, *tmp;
  20133. +
  20134. + DPRINTF(("%s()\n", __FUNCTION__));
  20135. +
  20136. + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
  20137. + return;
  20138. + if (sc->sc_pkq_cur != NULL)
  20139. + return;
  20140. + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
  20141. + sc->sc_pkq_cur = q;
  20142. + list_del(&q->pkq_list);
  20143. + if (safe_kstart(sc) != 0) {
  20144. + crypto_kdone(q->pkq_krp);
  20145. + kfree(q);
  20146. + sc->sc_pkq_cur = NULL;
  20147. + } else {
  20148. + /* op started, start polling */
  20149. + mod_timer(&sc->sc_pkto, jiffies + 1);
  20150. + break;
  20151. + }
  20152. + }
  20153. +}
  20154. +
  20155. +static void
  20156. +safe_kpoll(unsigned long arg)
  20157. +{
  20158. + struct safe_softc *sc = NULL;
  20159. + struct safe_pkq *q;
  20160. + struct crparam *res;
  20161. + int i;
  20162. + u_int32_t buf[64];
  20163. + unsigned long flags;
  20164. +
  20165. + DPRINTF(("%s()\n", __FUNCTION__));
  20166. +
  20167. + if (arg >= SAFE_MAX_CHIPS)
  20168. + return;
  20169. + sc = safe_chip_idx[arg];
  20170. + if (!sc) {
  20171. + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
  20172. + return;
  20173. + }
  20174. +
  20175. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  20176. + if (sc->sc_pkq_cur == NULL)
  20177. + goto out;
  20178. + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
  20179. + /* still running, check back later */
  20180. + mod_timer(&sc->sc_pkto, jiffies + 1);
  20181. + goto out;
  20182. + }
  20183. +
  20184. + q = sc->sc_pkq_cur;
  20185. + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
  20186. + bzero(buf, sizeof(buf));
  20187. + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
  20188. + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
  20189. + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
  20190. + sc->sc_pk_resoff + (i << 2)));
  20191. + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
  20192. + /*
  20193. + * reduce the bits that need copying if possible
  20194. + */
  20195. + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
  20196. + res->crp_nbits = safe_ksigbits(sc, res);
  20197. +
  20198. + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
  20199. + WRITE_REG(sc, i, 0);
  20200. +
  20201. + crypto_kdone(q->pkq_krp);
  20202. + kfree(q);
  20203. + sc->sc_pkq_cur = NULL;
  20204. +
  20205. + safe_kfeed(sc);
  20206. +out:
  20207. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  20208. +}
  20209. +
  20210. +static void
  20211. +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
  20212. + struct crparam *n)
  20213. +{
  20214. + u_int32_t buf[64], i;
  20215. +
  20216. + DPRINTF(("%s()\n", __FUNCTION__));
  20217. +
  20218. + bzero(buf, sizeof(buf));
  20219. + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
  20220. +
  20221. + for (i = 0; i < len >> 2; i++)
  20222. + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
  20223. + cpu_to_le32(buf[i]));
  20224. +}
  20225. +
  20226. +#ifdef SAFE_DEBUG
  20227. +static void
  20228. +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
  20229. +{
  20230. + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
  20231. + , tag
  20232. + , READ_REG(sc, SAFE_DMA_ENDIAN)
  20233. + , READ_REG(sc, SAFE_DMA_SRCADDR)
  20234. + , READ_REG(sc, SAFE_DMA_DSTADDR)
  20235. + , READ_REG(sc, SAFE_DMA_STAT)
  20236. + );
  20237. +}
  20238. +
  20239. +static void
  20240. +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
  20241. +{
  20242. + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
  20243. + , tag
  20244. + , READ_REG(sc, SAFE_HI_CFG)
  20245. + , READ_REG(sc, SAFE_HI_MASK)
  20246. + , READ_REG(sc, SAFE_HI_DESC_CNT)
  20247. + , READ_REG(sc, SAFE_HU_STAT)
  20248. + , READ_REG(sc, SAFE_HM_STAT)
  20249. + );
  20250. +}
  20251. +
  20252. +static void
  20253. +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
  20254. +{
  20255. + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
  20256. +
  20257. + /* NB: assume caller has lock on ring */
  20258. + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
  20259. + tag,
  20260. + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
  20261. + (unsigned long)(sc->sc_back - sc->sc_ring),
  20262. + (unsigned long)(sc->sc_front - sc->sc_ring));
  20263. +}
  20264. +
  20265. +static void
  20266. +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
  20267. +{
  20268. + int ix, nsegs;
  20269. +
  20270. + ix = re - sc->sc_ring;
  20271. + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
  20272. + , tag
  20273. + , re, ix
  20274. + , re->re_desc.d_csr
  20275. + , re->re_desc.d_src
  20276. + , re->re_desc.d_dst
  20277. + , re->re_desc.d_sa
  20278. + , re->re_desc.d_len
  20279. + );
  20280. + if (re->re_src.nsegs > 1) {
  20281. + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
  20282. + sizeof(struct safe_pdesc);
  20283. + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
  20284. + printf(" spd[%u] %p: %p size %u flags %x"
  20285. + , ix, &sc->sc_spring[ix]
  20286. + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
  20287. + , sc->sc_spring[ix].pd_size
  20288. + , sc->sc_spring[ix].pd_flags
  20289. + );
  20290. + if (sc->sc_spring[ix].pd_size == 0)
  20291. + printf(" (zero!)");
  20292. + printf("\n");
  20293. + if (++ix == SAFE_TOTAL_SPART)
  20294. + ix = 0;
  20295. + }
  20296. + }
  20297. + if (re->re_dst.nsegs > 1) {
  20298. + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
  20299. + sizeof(struct safe_pdesc);
  20300. + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
  20301. + printf(" dpd[%u] %p: %p flags %x\n"
  20302. + , ix, &sc->sc_dpring[ix]
  20303. + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
  20304. + , sc->sc_dpring[ix].pd_flags
  20305. + );
  20306. + if (++ix == SAFE_TOTAL_DPART)
  20307. + ix = 0;
  20308. + }
  20309. + }
  20310. + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
  20311. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
  20312. + printf("sa: key %x %x %x %x %x %x %x %x\n"
  20313. + , re->re_sa.sa_key[0]
  20314. + , re->re_sa.sa_key[1]
  20315. + , re->re_sa.sa_key[2]
  20316. + , re->re_sa.sa_key[3]
  20317. + , re->re_sa.sa_key[4]
  20318. + , re->re_sa.sa_key[5]
  20319. + , re->re_sa.sa_key[6]
  20320. + , re->re_sa.sa_key[7]
  20321. + );
  20322. + printf("sa: indigest %x %x %x %x %x\n"
  20323. + , re->re_sa.sa_indigest[0]
  20324. + , re->re_sa.sa_indigest[1]
  20325. + , re->re_sa.sa_indigest[2]
  20326. + , re->re_sa.sa_indigest[3]
  20327. + , re->re_sa.sa_indigest[4]
  20328. + );
  20329. + printf("sa: outdigest %x %x %x %x %x\n"
  20330. + , re->re_sa.sa_outdigest[0]
  20331. + , re->re_sa.sa_outdigest[1]
  20332. + , re->re_sa.sa_outdigest[2]
  20333. + , re->re_sa.sa_outdigest[3]
  20334. + , re->re_sa.sa_outdigest[4]
  20335. + );
  20336. + printf("sr: iv %x %x %x %x\n"
  20337. + , re->re_sastate.sa_saved_iv[0]
  20338. + , re->re_sastate.sa_saved_iv[1]
  20339. + , re->re_sastate.sa_saved_iv[2]
  20340. + , re->re_sastate.sa_saved_iv[3]
  20341. + );
  20342. + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
  20343. + , re->re_sastate.sa_saved_hashbc
  20344. + , re->re_sastate.sa_saved_indigest[0]
  20345. + , re->re_sastate.sa_saved_indigest[1]
  20346. + , re->re_sastate.sa_saved_indigest[2]
  20347. + , re->re_sastate.sa_saved_indigest[3]
  20348. + , re->re_sastate.sa_saved_indigest[4]
  20349. + );
  20350. +}
  20351. +
  20352. +static void
  20353. +safe_dump_ring(struct safe_softc *sc, const char *tag)
  20354. +{
  20355. + unsigned long flags;
  20356. +
  20357. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  20358. + printf("\nSafeNet Ring State:\n");
  20359. + safe_dump_intrstate(sc, tag);
  20360. + safe_dump_dmastatus(sc, tag);
  20361. + safe_dump_ringstate(sc, tag);
  20362. + if (sc->sc_nqchip) {
  20363. + struct safe_ringentry *re = sc->sc_back;
  20364. + do {
  20365. + safe_dump_request(sc, tag, re);
  20366. + if (++re == sc->sc_ringtop)
  20367. + re = sc->sc_ring;
  20368. + } while (re != sc->sc_front);
  20369. + }
  20370. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  20371. +}
  20372. +#endif /* SAFE_DEBUG */
  20373. +
  20374. +
  20375. +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  20376. +{
  20377. + struct safe_softc *sc = NULL;
  20378. + u32 mem_start, mem_len, cmd;
  20379. + int i, rc, devinfo;
  20380. + dma_addr_t raddr;
  20381. + static int num_chips = 0;
  20382. +
  20383. + DPRINTF(("%s()\n", __FUNCTION__));
  20384. +
  20385. + if (pci_enable_device(dev) < 0)
  20386. + return(-ENODEV);
  20387. +
  20388. + if (!dev->irq) {
  20389. + printk("safe: found device with no IRQ assigned. check BIOS settings!");
  20390. + pci_disable_device(dev);
  20391. + return(-ENODEV);
  20392. + }
  20393. +
  20394. + if (pci_set_mwi(dev)) {
  20395. + printk("safe: pci_set_mwi failed!");
  20396. + return(-ENODEV);
  20397. + }
  20398. +
  20399. + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  20400. + if (!sc)
  20401. + return(-ENOMEM);
  20402. + memset(sc, 0, sizeof(*sc));
  20403. +
  20404. + softc_device_init(sc, "safe", num_chips, safe_methods);
  20405. +
  20406. + sc->sc_irq = -1;
  20407. + sc->sc_cid = -1;
  20408. + sc->sc_pcidev = dev;
  20409. + if (num_chips < SAFE_MAX_CHIPS) {
  20410. + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
  20411. + num_chips++;
  20412. + }
  20413. +
  20414. + INIT_LIST_HEAD(&sc->sc_pkq);
  20415. + spin_lock_init(&sc->sc_pkmtx);
  20416. +
  20417. + pci_set_drvdata(sc->sc_pcidev, sc);
  20418. +
  20419. + /* we read its hardware registers as memory */
  20420. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  20421. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  20422. +
  20423. + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
  20424. + if (!sc->sc_base_addr) {
  20425. + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
  20426. + mem_start, mem_start + mem_len - 1);
  20427. + goto out;
  20428. + }
  20429. +
  20430. + /* fix up the bus size */
  20431. + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  20432. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  20433. + goto out;
  20434. + }
  20435. + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  20436. + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
  20437. + goto out;
  20438. + }
  20439. +
  20440. + pci_set_master(sc->sc_pcidev);
  20441. +
  20442. + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
  20443. +
  20444. + if (!(cmd & PCI_COMMAND_MEMORY)) {
  20445. + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
  20446. + goto out;
  20447. + }
  20448. +
  20449. + if (!(cmd & PCI_COMMAND_MASTER)) {
  20450. + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
  20451. + goto out;
  20452. + }
  20453. +
  20454. + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
  20455. + if (rc) {
  20456. + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
  20457. + goto out;
  20458. + }
  20459. + sc->sc_irq = dev->irq;
  20460. +
  20461. + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
  20462. + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
  20463. +
  20464. + /*
  20465. + * Allocate packet engine descriptors.
  20466. + */
  20467. + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  20468. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  20469. + &sc->sc_ringalloc.dma_paddr);
  20470. + if (!sc->sc_ringalloc.dma_vaddr) {
  20471. + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
  20472. + goto out;
  20473. + }
  20474. +
  20475. + /*
  20476. + * Hookup the static portion of all our data structures.
  20477. + */
  20478. + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
  20479. + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
  20480. + sc->sc_front = sc->sc_ring;
  20481. + sc->sc_back = sc->sc_ring;
  20482. + raddr = sc->sc_ringalloc.dma_paddr;
  20483. + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
  20484. + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
  20485. + struct safe_ringentry *re = &sc->sc_ring[i];
  20486. +
  20487. + re->re_desc.d_sa = raddr +
  20488. + offsetof(struct safe_ringentry, re_sa);
  20489. + re->re_sa.sa_staterec = raddr +
  20490. + offsetof(struct safe_ringentry, re_sastate);
  20491. +
  20492. + raddr += sizeof (struct safe_ringentry);
  20493. + }
  20494. + spin_lock_init(&sc->sc_ringmtx);
  20495. +
  20496. + /*
  20497. + * Allocate scatter and gather particle descriptors.
  20498. + */
  20499. + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  20500. + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
  20501. + &sc->sc_spalloc.dma_paddr);
  20502. + if (!sc->sc_spalloc.dma_vaddr) {
  20503. + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
  20504. + goto out;
  20505. + }
  20506. + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
  20507. + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
  20508. + sc->sc_spfree = sc->sc_spring;
  20509. + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
  20510. +
  20511. + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  20512. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20513. + &sc->sc_dpalloc.dma_paddr);
  20514. + if (!sc->sc_dpalloc.dma_vaddr) {
  20515. + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
  20516. + goto out;
  20517. + }
  20518. + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
  20519. + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
  20520. + sc->sc_dpfree = sc->sc_dpring;
  20521. + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
  20522. +
  20523. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
  20524. + if (sc->sc_cid < 0) {
  20525. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  20526. + goto out;
  20527. + }
  20528. +
  20529. + printf("%s:", device_get_nameunit(sc->sc_dev));
  20530. +
  20531. + devinfo = READ_REG(sc, SAFE_DEVINFO);
  20532. + if (devinfo & SAFE_DEVINFO_RNG) {
  20533. + sc->sc_flags |= SAFE_FLAGS_RNG;
  20534. + printf(" rng");
  20535. + }
  20536. + if (devinfo & SAFE_DEVINFO_PKEY) {
  20537. + printf(" key");
  20538. + sc->sc_flags |= SAFE_FLAGS_KEY;
  20539. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
  20540. +#if 0
  20541. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
  20542. +#endif
  20543. + init_timer(&sc->sc_pkto);
  20544. + sc->sc_pkto.function = safe_kpoll;
  20545. + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
  20546. + }
  20547. + if (devinfo & SAFE_DEVINFO_DES) {
  20548. + printf(" des/3des");
  20549. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  20550. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  20551. + }
  20552. + if (devinfo & SAFE_DEVINFO_AES) {
  20553. + printf(" aes");
  20554. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  20555. + }
  20556. + if (devinfo & SAFE_DEVINFO_MD5) {
  20557. + printf(" md5");
  20558. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  20559. + }
  20560. + if (devinfo & SAFE_DEVINFO_SHA1) {
  20561. + printf(" sha1");
  20562. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  20563. + }
  20564. + printf(" null");
  20565. + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
  20566. + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
  20567. + /* XXX other supported algorithms */
  20568. + printf("\n");
  20569. +
  20570. + safe_reset_board(sc); /* reset h/w */
  20571. + safe_init_board(sc); /* init h/w */
  20572. +
  20573. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  20574. + if (sc->sc_flags & SAFE_FLAGS_RNG) {
  20575. + safe_rng_init(sc);
  20576. + crypto_rregister(sc->sc_cid, safe_read_random, sc);
  20577. + }
  20578. +#endif /* SAFE_NO_RNG */
  20579. +
  20580. + return (0);
  20581. +
  20582. +out:
  20583. + if (sc->sc_cid >= 0)
  20584. + crypto_unregister_all(sc->sc_cid);
  20585. + if (sc->sc_irq != -1)
  20586. + free_irq(sc->sc_irq, sc);
  20587. + if (sc->sc_ringalloc.dma_vaddr)
  20588. + pci_free_consistent(sc->sc_pcidev,
  20589. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  20590. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  20591. + if (sc->sc_spalloc.dma_vaddr)
  20592. + pci_free_consistent(sc->sc_pcidev,
  20593. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20594. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  20595. + if (sc->sc_dpalloc.dma_vaddr)
  20596. + pci_free_consistent(sc->sc_pcidev,
  20597. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20598. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  20599. + kfree(sc);
  20600. + return(-ENODEV);
  20601. +}
  20602. +
  20603. +static void safe_remove(struct pci_dev *dev)
  20604. +{
  20605. + struct safe_softc *sc = pci_get_drvdata(dev);
  20606. +
  20607. + DPRINTF(("%s()\n", __FUNCTION__));
  20608. +
  20609. + /* XXX wait/abort active ops */
  20610. +
  20611. + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
  20612. +
  20613. + del_timer_sync(&sc->sc_pkto);
  20614. +
  20615. + crypto_unregister_all(sc->sc_cid);
  20616. +
  20617. + safe_cleanchip(sc);
  20618. +
  20619. + if (sc->sc_irq != -1)
  20620. + free_irq(sc->sc_irq, sc);
  20621. + if (sc->sc_ringalloc.dma_vaddr)
  20622. + pci_free_consistent(sc->sc_pcidev,
  20623. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  20624. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  20625. + if (sc->sc_spalloc.dma_vaddr)
  20626. + pci_free_consistent(sc->sc_pcidev,
  20627. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20628. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  20629. + if (sc->sc_dpalloc.dma_vaddr)
  20630. + pci_free_consistent(sc->sc_pcidev,
  20631. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20632. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  20633. + sc->sc_irq = -1;
  20634. + sc->sc_ringalloc.dma_vaddr = NULL;
  20635. + sc->sc_spalloc.dma_vaddr = NULL;
  20636. + sc->sc_dpalloc.dma_vaddr = NULL;
  20637. +}
  20638. +
  20639. +static struct pci_device_id safe_pci_tbl[] = {
  20640. + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
  20641. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  20642. + { },
  20643. +};
  20644. +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
  20645. +
  20646. +static struct pci_driver safe_driver = {
  20647. + .name = "safe",
  20648. + .id_table = safe_pci_tbl,
  20649. + .probe = safe_probe,
  20650. + .remove = safe_remove,
  20651. + /* add PM stuff here one day */
  20652. +};
  20653. +
  20654. +static int __init safe_init (void)
  20655. +{
  20656. + struct safe_softc *sc = NULL;
  20657. + int rc;
  20658. +
  20659. + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
  20660. +
  20661. + rc = pci_register_driver(&safe_driver);
  20662. + pci_register_driver_compat(&safe_driver, rc);
  20663. +
  20664. + return rc;
  20665. +}
  20666. +
  20667. +static void __exit safe_exit (void)
  20668. +{
  20669. + pci_unregister_driver(&safe_driver);
  20670. +}
  20671. +
  20672. +module_init(safe_init);
  20673. +module_exit(safe_exit);
  20674. +
  20675. +MODULE_LICENSE("BSD");
  20676. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  20677. +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
  20678. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/safereg.h linux-2.6.27.10/crypto/ocf/safe/safereg.h
  20679. --- linux-2.6.27.10.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
  20680. +++ linux-2.6.27.10/crypto/ocf/safe/safereg.h 2008-12-23 19:31:44.000000000 +0100
  20681. @@ -0,0 +1,421 @@
  20682. +/*-
  20683. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  20684. + * Copyright (c) 2003 Global Technology Associates, Inc.
  20685. + * All rights reserved.
  20686. + *
  20687. + * Redistribution and use in source and binary forms, with or without
  20688. + * modification, are permitted provided that the following conditions
  20689. + * are met:
  20690. + * 1. Redistributions of source code must retain the above copyright
  20691. + * notice, this list of conditions and the following disclaimer.
  20692. + * 2. Redistributions in binary form must reproduce the above copyright
  20693. + * notice, this list of conditions and the following disclaimer in the
  20694. + * documentation and/or other materials provided with the distribution.
  20695. + *
  20696. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20697. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20698. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20699. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20700. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20701. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20702. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20703. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  20704. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  20705. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  20706. + * SUCH DAMAGE.
  20707. + *
  20708. + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
  20709. + */
  20710. +#ifndef _SAFE_SAFEREG_H_
  20711. +#define _SAFE_SAFEREG_H_
  20712. +
  20713. +/*
  20714. + * Register definitions for SafeNet SafeXcel-1141 crypto device.
  20715. + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
  20716. + */
  20717. +
  20718. +#define BS_BAR 0x10 /* DMA base address register */
  20719. +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
  20720. +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
  20721. +
  20722. +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
  20723. +
  20724. +/* SafeNet */
  20725. +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
  20726. +
  20727. +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
  20728. +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
  20729. +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
  20730. +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
  20731. +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
  20732. +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
  20733. +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
  20734. +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
  20735. +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
  20736. +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
  20737. +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
  20738. +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
  20739. +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
  20740. +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
  20741. +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
  20742. +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
  20743. +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
  20744. +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
  20745. +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
  20746. +#define SAFE_DEVID 0x0084 /* Device ID */
  20747. +#define SAFE_DEVINFO 0x0088 /* Device Info */
  20748. +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
  20749. +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
  20750. +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
  20751. +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
  20752. +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
  20753. +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
  20754. +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
  20755. +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
  20756. +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
  20757. +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
  20758. +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
  20759. +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
  20760. +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
  20761. +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
  20762. +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
  20763. +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
  20764. +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
  20765. +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
  20766. +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
  20767. +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
  20768. +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
  20769. +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
  20770. +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
  20771. +
  20772. +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
  20773. +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
  20774. +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
  20775. +#define SAFE_RNG_A 0x010c /* RNG A */
  20776. +#define SAFE_RNG_B 0x0110 /* RNG B */
  20777. +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
  20778. +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
  20779. +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
  20780. +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
  20781. +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
  20782. +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
  20783. +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
  20784. +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
  20785. +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
  20786. +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
  20787. +
  20788. +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
  20789. +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
  20790. +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
  20791. +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
  20792. +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
  20793. +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
  20794. +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
  20795. +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
  20796. +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
  20797. +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
  20798. +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
  20799. +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
  20800. +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
  20801. +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
  20802. +#define SAFE_PE_CSR_XECODE_S 20
  20803. +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
  20804. +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
  20805. +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
  20806. +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
  20807. +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
  20808. +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
  20809. +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
  20810. +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
  20811. +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
  20812. +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
  20813. +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
  20814. +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
  20815. +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
  20816. +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
  20817. +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
  20818. +
  20819. +/*
  20820. + * Check the CSR to see if the PE has returned ownership to
  20821. + * the host. Note that before processing a descriptor this
  20822. + * must be done followed by a check of the SAFE_PE_LEN register
  20823. + * status bits to avoid premature processing of a descriptor
  20824. + * on its way back to the host.
  20825. + */
  20826. +#define SAFE_PE_CSR_IS_DONE(_csr) \
  20827. + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
  20828. +
  20829. +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
  20830. +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
  20831. +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
  20832. +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
  20833. +#define SAFE_PE_LEN_BYPASS_S 24
  20834. +
  20835. +#define SAFE_PE_LEN_IS_DONE(_len) \
  20836. + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
  20837. +
  20838. +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
  20839. +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
  20840. +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
  20841. +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
  20842. +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
  20843. +
  20844. +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
  20845. +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
  20846. +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
  20847. +
  20848. +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
  20849. +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
  20850. +
  20851. +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
  20852. +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
  20853. +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
  20854. +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
  20855. +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
  20856. +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
  20857. +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
  20858. +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
  20859. +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
  20860. +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
  20861. +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
  20862. +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
  20863. +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
  20864. +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
  20865. +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
  20866. +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
  20867. +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
  20868. +
  20869. +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
  20870. +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
  20871. +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
  20872. +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
  20873. +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
  20874. +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
  20875. +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
  20876. +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
  20877. +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
  20878. +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
  20879. +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
  20880. +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
  20881. +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
  20882. +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
  20883. +
  20884. +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
  20885. +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
  20886. +#define SAFE_PE_RINGCFG_OFFSET_S 16
  20887. +
  20888. +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
  20889. +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
  20890. +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
  20891. +
  20892. +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
  20893. +
  20894. +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
  20895. +#define SAFE_PE_ERNGSTAT_NEXT_S 16
  20896. +
  20897. +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
  20898. +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
  20899. +
  20900. +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
  20901. +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
  20902. +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
  20903. +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
  20904. +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
  20905. +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
  20906. +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
  20907. +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
  20908. +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
  20909. +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
  20910. +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
  20911. +
  20912. +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
  20913. +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
  20914. +
  20915. +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
  20916. +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
  20917. +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
  20918. +
  20919. +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
  20920. +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
  20921. +#define SAFE_DEVINFO_REV_MAJ_S 4
  20922. +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
  20923. +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
  20924. +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
  20925. +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
  20926. +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
  20927. +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
  20928. +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
  20929. +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
  20930. +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
  20931. +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
  20932. +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
  20933. +
  20934. +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
  20935. +#define SAFE_REV_MAJ(_chiprev) \
  20936. + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
  20937. +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
  20938. +
  20939. +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
  20940. +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
  20941. +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
  20942. +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
  20943. +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
  20944. +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
  20945. +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
  20946. +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
  20947. +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
  20948. +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
  20949. +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
  20950. +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
  20951. +
  20952. +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
  20953. +
  20954. +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
  20955. +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
  20956. +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
  20957. +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
  20958. +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
  20959. +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
  20960. +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
  20961. +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
  20962. +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
  20963. +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
  20964. +
  20965. +/*
  20966. + * Packet engine descriptor. Note that d_csr is a copy of the
  20967. + * SAFE_PE_CSR register and all definitions apply, and d_len
  20968. + * is a copy of the SAFE_PE_LEN register and all definitions apply.
  20969. + * d_src and d_len may point directly to contiguous data or to a
  20970. + * list of ``particle descriptors'' when using scatter/gather i/o.
  20971. + */
  20972. +struct safe_desc {
  20973. + u_int32_t d_csr; /* per-packet control/status */
  20974. + u_int32_t d_src; /* source address */
  20975. + u_int32_t d_dst; /* destination address */
  20976. + u_int32_t d_sa; /* SA address */
  20977. + u_int32_t d_len; /* length, bypass, status */
  20978. +};
  20979. +
  20980. +/*
  20981. + * Scatter/Gather particle descriptor.
  20982. + *
  20983. + * NB: scatter descriptors do not specify a size; this is fixed
  20984. + * by the setting of the SAFE_PE_PARTCFG register.
  20985. + */
  20986. +struct safe_pdesc {
  20987. + u_int32_t pd_addr; /* particle address */
  20988. +#ifdef __BIG_ENDIAN
  20989. + u_int16_t pd_flags; /* control word */
  20990. + u_int16_t pd_size; /* particle size (bytes) */
  20991. +#else
  20992. + u_int16_t pd_flags; /* control word */
  20993. + u_int16_t pd_size; /* particle size (bytes) */
  20994. +#endif
  20995. +};
  20996. +
  20997. +#define SAFE_PD_READY 0x0001 /* ready for processing */
  20998. +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
  20999. +
  21000. +/*
  21001. + * Security Association (SA) Record (Rev 1). One of these is
  21002. + * required for each operation processed by the packet engine.
  21003. + */
  21004. +struct safe_sarec {
  21005. + u_int32_t sa_cmd0;
  21006. + u_int32_t sa_cmd1;
  21007. + u_int32_t sa_resv0;
  21008. + u_int32_t sa_resv1;
  21009. + u_int32_t sa_key[8]; /* DES/3DES/AES key */
  21010. + u_int32_t sa_indigest[5]; /* inner digest */
  21011. + u_int32_t sa_outdigest[5]; /* outer digest */
  21012. + u_int32_t sa_spi; /* SPI */
  21013. + u_int32_t sa_seqnum; /* sequence number */
  21014. + u_int32_t sa_seqmask[2]; /* sequence number mask */
  21015. + u_int32_t sa_resv2;
  21016. + u_int32_t sa_staterec; /* address of state record */
  21017. + u_int32_t sa_resv3[2];
  21018. + u_int32_t sa_samgmt0; /* SA management field 0 */
  21019. + u_int32_t sa_samgmt1; /* SA management field 0 */
  21020. +};
  21021. +
  21022. +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
  21023. +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
  21024. +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
  21025. +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
  21026. +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
  21027. +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
  21028. +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
  21029. +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
  21030. +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
  21031. +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
  21032. +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
  21033. +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
  21034. +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
  21035. +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
  21036. +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
  21037. +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
  21038. +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
  21039. +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
  21040. +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
  21041. +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
  21042. +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
  21043. +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
  21044. +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
  21045. +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
  21046. +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
  21047. +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
  21048. +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
  21049. +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
  21050. +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
  21051. +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
  21052. +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
  21053. +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
  21054. +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
  21055. +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
  21056. +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
  21057. +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
  21058. +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
  21059. +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
  21060. +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
  21061. +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
  21062. +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
  21063. +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
  21064. +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
  21065. +
  21066. +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
  21067. +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
  21068. +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
  21069. +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
  21070. +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
  21071. +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
  21072. +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
  21073. +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
  21074. +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
  21075. +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
  21076. +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
  21077. +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
  21078. +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
  21079. +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
  21080. +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
  21081. +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
  21082. +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
  21083. +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
  21084. +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
  21085. +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
  21086. +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
  21087. +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
  21088. +#define SAFE_SA_CMD1_OFFSET_S 16
  21089. +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
  21090. +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
  21091. +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
  21092. +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
  21093. +
  21094. +/*
  21095. + * Security Associate State Record (Rev 1).
  21096. + */
  21097. +struct safe_sastate {
  21098. + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
  21099. + u_int32_t sa_saved_hashbc; /* saved hash byte count */
  21100. + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
  21101. +};
  21102. +#endif /* _SAFE_SAFEREG_H_ */
  21103. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/safevar.h linux-2.6.27.10/crypto/ocf/safe/safevar.h
  21104. --- linux-2.6.27.10.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
  21105. +++ linux-2.6.27.10/crypto/ocf/safe/safevar.h 2008-12-23 19:31:44.000000000 +0100
  21106. @@ -0,0 +1,230 @@
  21107. +/*-
  21108. + * The linux port of this code done by David McCullough
  21109. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
  21110. + * The license and original author are listed below.
  21111. + *
  21112. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  21113. + * Copyright (c) 2003 Global Technology Associates, Inc.
  21114. + * All rights reserved.
  21115. + *
  21116. + * Redistribution and use in source and binary forms, with or without
  21117. + * modification, are permitted provided that the following conditions
  21118. + * are met:
  21119. + * 1. Redistributions of source code must retain the above copyright
  21120. + * notice, this list of conditions and the following disclaimer.
  21121. + * 2. Redistributions in binary form must reproduce the above copyright
  21122. + * notice, this list of conditions and the following disclaimer in the
  21123. + * documentation and/or other materials provided with the distribution.
  21124. + *
  21125. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  21126. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21127. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21128. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21129. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21130. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21131. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21132. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21133. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21134. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  21135. + * SUCH DAMAGE.
  21136. + *
  21137. + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
  21138. + */
  21139. +#ifndef _SAFE_SAFEVAR_H_
  21140. +#define _SAFE_SAFEVAR_H_
  21141. +
  21142. +/* Maximum queue length */
  21143. +#ifndef SAFE_MAX_NQUEUE
  21144. +#define SAFE_MAX_NQUEUE 60
  21145. +#endif
  21146. +
  21147. +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
  21148. +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
  21149. +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
  21150. +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
  21151. +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
  21152. +/* total src+dst particle descriptors */
  21153. +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  21154. +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  21155. +
  21156. +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
  21157. +
  21158. +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
  21159. +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
  21160. +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  21161. +
  21162. +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
  21163. +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
  21164. +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
  21165. +
  21166. +#ifdef __KERNEL__
  21167. +/*
  21168. + * State associated with the allocation of each chunk
  21169. + * of memory setup for DMA.
  21170. + */
  21171. +struct safe_dma_alloc {
  21172. + dma_addr_t dma_paddr;
  21173. + void *dma_vaddr;
  21174. +};
  21175. +
  21176. +/*
  21177. + * Cryptographic operand state. One of these exists for each
  21178. + * source and destination operand passed in from the crypto
  21179. + * subsystem. When possible source and destination operands
  21180. + * refer to the same memory. More often they are distinct.
  21181. + * We track the virtual address of each operand as well as
  21182. + * where each is mapped for DMA.
  21183. + */
  21184. +struct safe_operand {
  21185. + union {
  21186. + struct sk_buff *skb;
  21187. + struct uio *io;
  21188. + } u;
  21189. + void *map;
  21190. + int mapsize; /* total number of bytes in segs */
  21191. + struct {
  21192. + dma_addr_t ds_addr;
  21193. + int ds_len;
  21194. + int ds_tlen;
  21195. + } segs[SAFE_MAX_PART];
  21196. + int nsegs;
  21197. +};
  21198. +
  21199. +/*
  21200. + * Packet engine ring entry and cryptographic operation state.
  21201. + * The packet engine requires a ring of descriptors that contain
  21202. + * pointers to various cryptographic state. However the ring
  21203. + * configuration register allows you to specify an arbitrary size
  21204. + * for ring entries. We use this feature to collect most of the
  21205. + * state for each cryptographic request into one spot. Other than
  21206. + * ring entries only the ``particle descriptors'' (scatter/gather
  21207. + * lists) and the actual operand data are kept separate. The
  21208. + * particle descriptors must also be organized in rings. The
  21209. + * operand data can be located aribtrarily (modulo alignment constraints).
  21210. + *
  21211. + * Note that the descriptor ring is mapped onto the PCI bus so
  21212. + * the hardware can DMA data. This means the entire ring must be
  21213. + * contiguous.
  21214. + */
  21215. +struct safe_ringentry {
  21216. + struct safe_desc re_desc; /* command descriptor */
  21217. + struct safe_sarec re_sa; /* SA record */
  21218. + struct safe_sastate re_sastate; /* SA state record */
  21219. +
  21220. + struct cryptop *re_crp; /* crypto operation */
  21221. +
  21222. + struct safe_operand re_src; /* source operand */
  21223. + struct safe_operand re_dst; /* destination operand */
  21224. +
  21225. + int re_sesn; /* crypto session ID */
  21226. + int re_flags;
  21227. +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
  21228. +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
  21229. +};
  21230. +
  21231. +#define re_src_skb re_src.u.skb
  21232. +#define re_src_io re_src.u.io
  21233. +#define re_src_map re_src.map
  21234. +#define re_src_nsegs re_src.nsegs
  21235. +#define re_src_segs re_src.segs
  21236. +#define re_src_mapsize re_src.mapsize
  21237. +
  21238. +#define re_dst_skb re_dst.u.skb
  21239. +#define re_dst_io re_dst.u.io
  21240. +#define re_dst_map re_dst.map
  21241. +#define re_dst_nsegs re_dst.nsegs
  21242. +#define re_dst_segs re_dst.segs
  21243. +#define re_dst_mapsize re_dst.mapsize
  21244. +
  21245. +struct rndstate_test;
  21246. +
  21247. +struct safe_session {
  21248. + u_int32_t ses_used;
  21249. + u_int32_t ses_klen; /* key length in bits */
  21250. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  21251. + u_int32_t ses_mlen; /* hmac length in bytes */
  21252. + u_int32_t ses_hminner[5]; /* hmac inner state */
  21253. + u_int32_t ses_hmouter[5]; /* hmac outer state */
  21254. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  21255. +};
  21256. +
  21257. +struct safe_pkq {
  21258. + struct list_head pkq_list;
  21259. + struct cryptkop *pkq_krp;
  21260. +};
  21261. +
  21262. +struct safe_softc {
  21263. + softc_device_decl sc_dev;
  21264. + u32 sc_irq;
  21265. +
  21266. + struct pci_dev *sc_pcidev;
  21267. + ocf_iomem_t sc_base_addr;
  21268. +
  21269. + u_int sc_chiprev; /* major/minor chip revision */
  21270. + int sc_flags; /* device specific flags */
  21271. +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
  21272. +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
  21273. + int sc_suspended;
  21274. + int sc_needwakeup; /* notify crypto layer */
  21275. + int32_t sc_cid; /* crypto tag */
  21276. +
  21277. + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
  21278. + struct safe_ringentry *sc_ring; /* PE ring */
  21279. + struct safe_ringentry *sc_ringtop; /* PE ring top */
  21280. + struct safe_ringentry *sc_front; /* next free entry */
  21281. + struct safe_ringentry *sc_back; /* next pending entry */
  21282. + int sc_nqchip; /* # passed to chip */
  21283. + spinlock_t sc_ringmtx; /* PE ring lock */
  21284. + struct safe_pdesc *sc_spring; /* src particle ring */
  21285. + struct safe_pdesc *sc_springtop; /* src particle ring top */
  21286. + struct safe_pdesc *sc_spfree; /* next free src particle */
  21287. + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
  21288. + struct safe_pdesc *sc_dpring; /* dest particle ring */
  21289. + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
  21290. + struct safe_pdesc *sc_dpfree; /* next free dest particle */
  21291. + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
  21292. + int sc_nsessions; /* # of sessions */
  21293. + struct safe_session *sc_sessions; /* sessions */
  21294. +
  21295. + struct timer_list sc_pkto; /* PK polling */
  21296. + spinlock_t sc_pkmtx; /* PK lock */
  21297. + struct list_head sc_pkq; /* queue of PK requests */
  21298. + struct safe_pkq *sc_pkq_cur; /* current processing request */
  21299. + u_int32_t sc_pk_reslen, sc_pk_resoff;
  21300. +
  21301. + int sc_max_dsize; /* maximum safe DMA size */
  21302. +};
  21303. +#endif /* __KERNEL__ */
  21304. +
  21305. +struct safe_stats {
  21306. + u_int64_t st_ibytes;
  21307. + u_int64_t st_obytes;
  21308. + u_int32_t st_ipackets;
  21309. + u_int32_t st_opackets;
  21310. + u_int32_t st_invalid; /* invalid argument */
  21311. + u_int32_t st_badsession; /* invalid session id */
  21312. + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
  21313. + u_int32_t st_nodesc; /* op submitted w/o descriptors */
  21314. + u_int32_t st_badalg; /* unsupported algorithm */
  21315. + u_int32_t st_ringfull; /* PE descriptor ring full */
  21316. + u_int32_t st_peoperr; /* PE marked error */
  21317. + u_int32_t st_dmaerr; /* PE DMA error */
  21318. + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
  21319. + u_int32_t st_skipmismatch; /* enc part begins before auth part */
  21320. + u_int32_t st_lenmismatch; /* enc length different auth length */
  21321. + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
  21322. + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
  21323. + u_int32_t st_iovmisaligned; /* iov op not aligned */
  21324. + u_int32_t st_iovnotuniform; /* iov op not suitable */
  21325. + u_int32_t st_unaligned; /* unaligned src caused copy */
  21326. + u_int32_t st_notuniform; /* non-uniform src caused copy */
  21327. + u_int32_t st_nomap; /* bus_dmamap_create failed */
  21328. + u_int32_t st_noload; /* bus_dmamap_load_* failed */
  21329. + u_int32_t st_nombuf; /* MGET* failed */
  21330. + u_int32_t st_nomcl; /* MCLGET* failed */
  21331. + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
  21332. + u_int32_t st_rng; /* RNG requests */
  21333. + u_int32_t st_rngalarm; /* RNG alarm requests */
  21334. + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
  21335. +};
  21336. +#endif /* _SAFE_SAFEVAR_H_ */
  21337. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/sha1.c linux-2.6.27.10/crypto/ocf/safe/sha1.c
  21338. --- linux-2.6.27.10.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
  21339. +++ linux-2.6.27.10/crypto/ocf/safe/sha1.c 2008-12-23 19:31:44.000000000 +0100
  21340. @@ -0,0 +1,279 @@
  21341. +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  21342. +/*
  21343. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  21344. + * All rights reserved.
  21345. + *
  21346. + * Redistribution and use in source and binary forms, with or without
  21347. + * modification, are permitted provided that the following conditions
  21348. + * are met:
  21349. + * 1. Redistributions of source code must retain the above copyright
  21350. + * notice, this list of conditions and the following disclaimer.
  21351. + * 2. Redistributions in binary form must reproduce the above copyright
  21352. + * notice, this list of conditions and the following disclaimer in the
  21353. + * documentation and/or other materials provided with the distribution.
  21354. + * 3. Neither the name of the project nor the names of its contributors
  21355. + * may be used to endorse or promote products derived from this software
  21356. + * without specific prior written permission.
  21357. + *
  21358. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  21359. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21360. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21361. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  21362. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21363. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21364. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21365. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21366. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21367. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  21368. + * SUCH DAMAGE.
  21369. + */
  21370. +
  21371. +/*
  21372. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  21373. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  21374. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  21375. + */
  21376. +
  21377. +#if 0
  21378. +#include <sys/cdefs.h>
  21379. +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
  21380. +
  21381. +#include <sys/types.h>
  21382. +#include <sys/cdefs.h>
  21383. +#include <sys/time.h>
  21384. +#include <sys/systm.h>
  21385. +
  21386. +#include <crypto/sha1.h>
  21387. +#endif
  21388. +
  21389. +/* sanity check */
  21390. +#if BYTE_ORDER != BIG_ENDIAN
  21391. +# if BYTE_ORDER != LITTLE_ENDIAN
  21392. +# define unsupported 1
  21393. +# endif
  21394. +#endif
  21395. +
  21396. +#ifndef unsupported
  21397. +
  21398. +/* constant table */
  21399. +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
  21400. +#define K(t) _K[(t) / 20]
  21401. +
  21402. +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
  21403. +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
  21404. +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  21405. +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
  21406. +
  21407. +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
  21408. +
  21409. +#undef H
  21410. +#define H(n) (ctxt->h.b32[(n)])
  21411. +#define COUNT (ctxt->count)
  21412. +#define BCOUNT (ctxt->c.b64[0] / 8)
  21413. +#define W(n) (ctxt->m.b32[(n)])
  21414. +
  21415. +#define PUTBYTE(x) { \
  21416. + ctxt->m.b8[(COUNT % 64)] = (x); \
  21417. + COUNT++; \
  21418. + COUNT %= 64; \
  21419. + ctxt->c.b64[0] += 8; \
  21420. + if (COUNT % 64 == 0) \
  21421. + sha1_step(ctxt); \
  21422. + }
  21423. +
  21424. +#define PUTPAD(x) { \
  21425. + ctxt->m.b8[(COUNT % 64)] = (x); \
  21426. + COUNT++; \
  21427. + COUNT %= 64; \
  21428. + if (COUNT % 64 == 0) \
  21429. + sha1_step(ctxt); \
  21430. + }
  21431. +
  21432. +static void sha1_step(struct sha1_ctxt *);
  21433. +
  21434. +static void
  21435. +sha1_step(ctxt)
  21436. + struct sha1_ctxt *ctxt;
  21437. +{
  21438. + u_int32_t a, b, c, d, e;
  21439. + size_t t, s;
  21440. + u_int32_t tmp;
  21441. +
  21442. +#if BYTE_ORDER == LITTLE_ENDIAN
  21443. + struct sha1_ctxt tctxt;
  21444. + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
  21445. + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
  21446. + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
  21447. + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
  21448. + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
  21449. + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
  21450. + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
  21451. + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
  21452. + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
  21453. + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
  21454. + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
  21455. + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
  21456. + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
  21457. + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
  21458. + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
  21459. + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
  21460. + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
  21461. + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
  21462. + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
  21463. + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
  21464. + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
  21465. + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
  21466. + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
  21467. + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
  21468. + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
  21469. + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
  21470. + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
  21471. + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
  21472. + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
  21473. + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
  21474. + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
  21475. + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
  21476. + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
  21477. +#endif
  21478. +
  21479. + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
  21480. +
  21481. + for (t = 0; t < 20; t++) {
  21482. + s = t & 0x0f;
  21483. + if (t >= 16) {
  21484. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21485. + }
  21486. + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
  21487. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21488. + }
  21489. + for (t = 20; t < 40; t++) {
  21490. + s = t & 0x0f;
  21491. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21492. + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
  21493. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21494. + }
  21495. + for (t = 40; t < 60; t++) {
  21496. + s = t & 0x0f;
  21497. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21498. + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
  21499. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21500. + }
  21501. + for (t = 60; t < 80; t++) {
  21502. + s = t & 0x0f;
  21503. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21504. + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
  21505. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21506. + }
  21507. +
  21508. + H(0) = H(0) + a;
  21509. + H(1) = H(1) + b;
  21510. + H(2) = H(2) + c;
  21511. + H(3) = H(3) + d;
  21512. + H(4) = H(4) + e;
  21513. +
  21514. + bzero(&ctxt->m.b8[0], 64);
  21515. +}
  21516. +
  21517. +/*------------------------------------------------------------*/
  21518. +
  21519. +void
  21520. +sha1_init(ctxt)
  21521. + struct sha1_ctxt *ctxt;
  21522. +{
  21523. + bzero(ctxt, sizeof(struct sha1_ctxt));
  21524. + H(0) = 0x67452301;
  21525. + H(1) = 0xefcdab89;
  21526. + H(2) = 0x98badcfe;
  21527. + H(3) = 0x10325476;
  21528. + H(4) = 0xc3d2e1f0;
  21529. +}
  21530. +
  21531. +void
  21532. +sha1_pad(ctxt)
  21533. + struct sha1_ctxt *ctxt;
  21534. +{
  21535. + size_t padlen; /*pad length in bytes*/
  21536. + size_t padstart;
  21537. +
  21538. + PUTPAD(0x80);
  21539. +
  21540. + padstart = COUNT % 64;
  21541. + padlen = 64 - padstart;
  21542. + if (padlen < 8) {
  21543. + bzero(&ctxt->m.b8[padstart], padlen);
  21544. + COUNT += padlen;
  21545. + COUNT %= 64;
  21546. + sha1_step(ctxt);
  21547. + padstart = COUNT % 64; /* should be 0 */
  21548. + padlen = 64 - padstart; /* should be 64 */
  21549. + }
  21550. + bzero(&ctxt->m.b8[padstart], padlen - 8);
  21551. + COUNT += (padlen - 8);
  21552. + COUNT %= 64;
  21553. +#if BYTE_ORDER == BIG_ENDIAN
  21554. + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
  21555. + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
  21556. + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
  21557. + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
  21558. +#else
  21559. + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
  21560. + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
  21561. + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
  21562. + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
  21563. +#endif
  21564. +}
  21565. +
  21566. +void
  21567. +sha1_loop(ctxt, input, len)
  21568. + struct sha1_ctxt *ctxt;
  21569. + const u_int8_t *input;
  21570. + size_t len;
  21571. +{
  21572. + size_t gaplen;
  21573. + size_t gapstart;
  21574. + size_t off;
  21575. + size_t copysiz;
  21576. +
  21577. + off = 0;
  21578. +
  21579. + while (off < len) {
  21580. + gapstart = COUNT % 64;
  21581. + gaplen = 64 - gapstart;
  21582. +
  21583. + copysiz = (gaplen < len - off) ? gaplen : len - off;
  21584. + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
  21585. + COUNT += copysiz;
  21586. + COUNT %= 64;
  21587. + ctxt->c.b64[0] += copysiz * 8;
  21588. + if (COUNT % 64 == 0)
  21589. + sha1_step(ctxt);
  21590. + off += copysiz;
  21591. + }
  21592. +}
  21593. +
  21594. +void
  21595. +sha1_result(ctxt, digest0)
  21596. + struct sha1_ctxt *ctxt;
  21597. + caddr_t digest0;
  21598. +{
  21599. + u_int8_t *digest;
  21600. +
  21601. + digest = (u_int8_t *)digest0;
  21602. + sha1_pad(ctxt);
  21603. +#if BYTE_ORDER == BIG_ENDIAN
  21604. + bcopy(&ctxt->h.b8[0], digest, 20);
  21605. +#else
  21606. + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
  21607. + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
  21608. + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
  21609. + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
  21610. + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
  21611. + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
  21612. + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
  21613. + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
  21614. + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
  21615. + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
  21616. +#endif
  21617. +}
  21618. +
  21619. +#endif /*unsupported*/
  21620. diff -Nur linux-2.6.27.10.orig/crypto/ocf/safe/sha1.h linux-2.6.27.10/crypto/ocf/safe/sha1.h
  21621. --- linux-2.6.27.10.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
  21622. +++ linux-2.6.27.10/crypto/ocf/safe/sha1.h 2008-12-23 19:31:44.000000000 +0100
  21623. @@ -0,0 +1,72 @@
  21624. +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
  21625. +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
  21626. +
  21627. +/*
  21628. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  21629. + * All rights reserved.
  21630. + *
  21631. + * Redistribution and use in source and binary forms, with or without
  21632. + * modification, are permitted provided that the following conditions
  21633. + * are met:
  21634. + * 1. Redistributions of source code must retain the above copyright
  21635. + * notice, this list of conditions and the following disclaimer.
  21636. + * 2. Redistributions in binary form must reproduce the above copyright
  21637. + * notice, this list of conditions and the following disclaimer in the
  21638. + * documentation and/or other materials provided with the distribution.
  21639. + * 3. Neither the name of the project nor the names of its contributors
  21640. + * may be used to endorse or promote products derived from this software
  21641. + * without specific prior written permission.
  21642. + *
  21643. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  21644. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21645. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21646. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  21647. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21648. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21649. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21650. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21651. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21652. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  21653. + * SUCH DAMAGE.
  21654. + */
  21655. +/*
  21656. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  21657. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  21658. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  21659. + */
  21660. +
  21661. +#ifndef _NETINET6_SHA1_H_
  21662. +#define _NETINET6_SHA1_H_
  21663. +
  21664. +struct sha1_ctxt {
  21665. + union {
  21666. + u_int8_t b8[20];
  21667. + u_int32_t b32[5];
  21668. + } h;
  21669. + union {
  21670. + u_int8_t b8[8];
  21671. + u_int64_t b64[1];
  21672. + } c;
  21673. + union {
  21674. + u_int8_t b8[64];
  21675. + u_int32_t b32[16];
  21676. + } m;
  21677. + u_int8_t count;
  21678. +};
  21679. +
  21680. +#ifdef __KERNEL__
  21681. +extern void sha1_init(struct sha1_ctxt *);
  21682. +extern void sha1_pad(struct sha1_ctxt *);
  21683. +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
  21684. +extern void sha1_result(struct sha1_ctxt *, caddr_t);
  21685. +
  21686. +/* compatibilty with other SHA1 source codes */
  21687. +typedef struct sha1_ctxt SHA1_CTX;
  21688. +#define SHA1Init(x) sha1_init((x))
  21689. +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
  21690. +#define SHA1Final(x, y) sha1_result((y), (x))
  21691. +#endif /* __KERNEL__ */
  21692. +
  21693. +#define SHA1_RESULTLEN (160/8)
  21694. +
  21695. +#endif /*_NETINET6_SHA1_H_*/
  21696. diff -Nur linux-2.6.27.10.orig/crypto/ocf/talitos/Makefile linux-2.6.27.10/crypto/ocf/talitos/Makefile
  21697. --- linux-2.6.27.10.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
  21698. +++ linux-2.6.27.10/crypto/ocf/talitos/Makefile 2008-12-23 19:31:44.000000000 +0100
  21699. @@ -0,0 +1,12 @@
  21700. +# for SGlinux builds
  21701. +-include $(ROOTDIR)/modules/.config
  21702. +
  21703. +obj-$(CONFIG_OCF_TALITOS) += talitos.o
  21704. +
  21705. +obj ?= .
  21706. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  21707. +
  21708. +ifdef TOPDIR
  21709. +-include $(TOPDIR)/Rules.make
  21710. +endif
  21711. +
  21712. diff -Nur linux-2.6.27.10.orig/crypto/ocf/talitos/talitos.c linux-2.6.27.10/crypto/ocf/talitos/talitos.c
  21713. --- linux-2.6.27.10.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
  21714. +++ linux-2.6.27.10/crypto/ocf/talitos/talitos.c 2008-12-23 19:31:44.000000000 +0100
  21715. @@ -0,0 +1,1359 @@
  21716. +/*
  21717. + * crypto/ocf/talitos/talitos.c
  21718. + *
  21719. + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
  21720. + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
  21721. + *
  21722. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  21723. + *
  21724. + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
  21725. + * some code copied from files with the following:
  21726. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com
  21727. + *
  21728. + * Redistribution and use in source and binary forms, with or without
  21729. + * modification, are permitted provided that the following conditions
  21730. + * are met:
  21731. + *
  21732. + * 1. Redistributions of source code must retain the above copyright
  21733. + * notice, this list of conditions and the following disclaimer.
  21734. + * 2. Redistributions in binary form must reproduce the above copyright
  21735. + * notice, this list of conditions and the following disclaimer in the
  21736. + * documentation and/or other materials provided with the distribution.
  21737. + * 3. The name of the author may not be used to endorse or promote products
  21738. + * derived from this software without specific prior written permission.
  21739. + *
  21740. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  21741. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21742. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21743. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21744. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21745. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21746. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21747. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21748. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21749. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21750. + *
  21751. + * ---------------------------------------------------------------------------
  21752. + *
  21753. + * NOTES:
  21754. + *
  21755. + * The Freescale SEC (also known as 'talitos') resides on the
  21756. + * internal bus, and runs asynchronous to the processor core. It has
  21757. + * a wide gamut of cryptographic acceleration features, including single-
  21758. + * pass IPsec (also known as algorithm chaining). To properly utilize
  21759. + * all of the SEC's performance enhancing features, further reworking
  21760. + * of higher level code (framework, applications) will be necessary.
  21761. + *
  21762. + * The following table shows which SEC version is present in which devices:
  21763. + *
  21764. + * Devices SEC version
  21765. + *
  21766. + * 8272, 8248 SEC 1.0
  21767. + * 885, 875 SEC 1.2
  21768. + * 8555E, 8541E SEC 2.0
  21769. + * 8349E SEC 2.01
  21770. + * 8548E SEC 2.1
  21771. + *
  21772. + * The following table shows the features offered by each SEC version:
  21773. + *
  21774. + * Max. chan-
  21775. + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
  21776. + *
  21777. + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
  21778. + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
  21779. + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
  21780. + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
  21781. + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
  21782. + *
  21783. + * Each execution unit in the SEC has two modes of execution; channel and
  21784. + * slave/debug. This driver employs the channel infrastructure in the
  21785. + * device for convenience. Only the RNG is directly accessed due to the
  21786. + * convenience of its random fifo pool. The relationship between the
  21787. + * channels and execution units is depicted in the following diagram:
  21788. + *
  21789. + * ------- ------------
  21790. + * ---| ch0 |---| |
  21791. + * ------- | |
  21792. + * | |------+-------+-------+-------+------------
  21793. + * ------- | | | | | | |
  21794. + * ---| ch1 |---| | | | | | |
  21795. + * ------- | | ------ ------ ------ ------ ------
  21796. + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
  21797. + * ------- | | ------ ------ ------ ------ ------
  21798. + * ---| ch2 |---| | | | | | |
  21799. + * ------- | | | | | | |
  21800. + * | |------+-------+-------+-------+------------
  21801. + * ------- | |
  21802. + * ---| ch3 |---| |
  21803. + * ------- ------------
  21804. + *
  21805. + * Channel ch0 may drive an aes operation to the aes unit (AESU),
  21806. + * and, at the same time, ch1 may drive a message digest operation
  21807. + * to the mdeu. Each channel has an input descriptor FIFO, and the
  21808. + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
  21809. + * a buffer overrun error is triggered. The controller is responsible
  21810. + * for fetching the data from descriptor pointers, and passing the
  21811. + * data to the appropriate EUs. The controller also writes the
  21812. + * cryptographic operation's result to memory. The SEC notifies
  21813. + * completion by triggering an interrupt and/or setting the 1st byte
  21814. + * of the hdr field to 0xff.
  21815. + *
  21816. + * TODO:
  21817. + * o support more algorithms
  21818. + * o support more versions of the SEC
  21819. + * o add support for linux 2.4
  21820. + * o scatter-gather (sg) support
  21821. + * o add support for public key ops (PKEU)
  21822. + * o add statistics
  21823. + */
  21824. +
  21825. +#ifndef AUTOCONF_INCLUDED
  21826. +#include <linux/config.h>
  21827. +#endif
  21828. +#include <linux/module.h>
  21829. +#include <linux/init.h>
  21830. +#include <linux/interrupt.h>
  21831. +#include <linux/spinlock.h>
  21832. +#include <linux/random.h>
  21833. +#include <linux/skbuff.h>
  21834. +#include <asm/scatterlist.h>
  21835. +#include <linux/dma-mapping.h> /* dma_map_single() */
  21836. +#include <linux/moduleparam.h>
  21837. +
  21838. +#include <linux/version.h>
  21839. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
  21840. +#include <linux/platform_device.h>
  21841. +#endif
  21842. +
  21843. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  21844. +#include <linux/of_platform.h>
  21845. +#endif
  21846. +
  21847. +#include <cryptodev.h>
  21848. +#include <uio.h>
  21849. +
  21850. +#define DRV_NAME "talitos"
  21851. +
  21852. +#include "talitos_dev.h"
  21853. +#include "talitos_soft.h"
  21854. +
  21855. +#define read_random(p,l) get_random_bytes(p,l)
  21856. +
  21857. +const char talitos_driver_name[] = "Talitos OCF";
  21858. +const char talitos_driver_version[] = "0.2";
  21859. +
  21860. +static int talitos_newsession(device_t dev, u_int32_t *sidp,
  21861. + struct cryptoini *cri);
  21862. +static int talitos_freesession(device_t dev, u_int64_t tid);
  21863. +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
  21864. +static void dump_talitos_status(struct talitos_softc *sc);
  21865. +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
  21866. + int chsel);
  21867. +static void talitos_doneprocessing(struct talitos_softc *sc);
  21868. +static void talitos_init_device(struct talitos_softc *sc);
  21869. +static void talitos_reset_device_master(struct talitos_softc *sc);
  21870. +static void talitos_reset_device(struct talitos_softc *sc);
  21871. +static void talitos_errorprocessing(struct talitos_softc *sc);
  21872. +#ifdef CONFIG_PPC_MERGE
  21873. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
  21874. +static int talitos_remove(struct of_device *ofdev);
  21875. +#else
  21876. +static int talitos_probe(struct platform_device *pdev);
  21877. +static int talitos_remove(struct platform_device *pdev);
  21878. +#endif
  21879. +#ifdef CONFIG_OCF_RANDOMHARVEST
  21880. +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
  21881. +static void talitos_rng_init(struct talitos_softc *sc);
  21882. +#endif
  21883. +
  21884. +static device_method_t talitos_methods = {
  21885. + /* crypto device methods */
  21886. + DEVMETHOD(cryptodev_newsession, talitos_newsession),
  21887. + DEVMETHOD(cryptodev_freesession,talitos_freesession),
  21888. + DEVMETHOD(cryptodev_process, talitos_process),
  21889. +};
  21890. +
  21891. +#define debug talitos_debug
  21892. +int talitos_debug = 0;
  21893. +module_param(talitos_debug, int, 0644);
  21894. +MODULE_PARM_DESC(talitos_debug, "Enable debug");
  21895. +
  21896. +static inline void talitos_write(volatile unsigned *addr, u32 val)
  21897. +{
  21898. + out_be32(addr, val);
  21899. +}
  21900. +
  21901. +static inline u32 talitos_read(volatile unsigned *addr)
  21902. +{
  21903. + u32 val;
  21904. + val = in_be32(addr);
  21905. + return val;
  21906. +}
  21907. +
  21908. +static void dump_talitos_status(struct talitos_softc *sc)
  21909. +{
  21910. + unsigned int v, v_hi, i, *ptr;
  21911. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  21912. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
  21913. + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
  21914. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  21915. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  21916. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  21917. + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
  21918. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  21919. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  21920. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  21921. + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
  21922. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  21923. + for (i = 0; i < sc->sc_num_channels; i++) {
  21924. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21925. + TALITOS_CH_CDPR);
  21926. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21927. + TALITOS_CH_CDPR_HI);
  21928. + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
  21929. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  21930. + }
  21931. + for (i = 0; i < sc->sc_num_channels; i++) {
  21932. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21933. + TALITOS_CH_CCPSR);
  21934. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21935. + TALITOS_CH_CCPSR_HI);
  21936. + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
  21937. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  21938. + }
  21939. + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
  21940. + for (i = 0; i < 16; i++) {
  21941. + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
  21942. + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
  21943. + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
  21944. + }
  21945. + return;
  21946. +}
  21947. +
  21948. +
  21949. +#ifdef CONFIG_OCF_RANDOMHARVEST
  21950. +/*
  21951. + * pull random numbers off the RNG FIFO, not exceeding amount available
  21952. + */
  21953. +static int
  21954. +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
  21955. +{
  21956. + struct talitos_softc *sc = (struct talitos_softc *) arg;
  21957. + int rc;
  21958. + u_int32_t v;
  21959. +
  21960. + DPRINTF("%s()\n", __FUNCTION__);
  21961. +
  21962. + /* check for things like FIFO underflow */
  21963. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  21964. + if (unlikely(v)) {
  21965. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  21966. + device_get_nameunit(sc->sc_cdev), v);
  21967. + return 0;
  21968. + }
  21969. + /*
  21970. + * OFL is number of available 64-bit words,
  21971. + * shift and convert to a 32-bit word count
  21972. + */
  21973. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
  21974. + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
  21975. + if (maxwords > v)
  21976. + maxwords = v;
  21977. + for (rc = 0; rc < maxwords; rc++) {
  21978. + buf[rc] = talitos_read(sc->sc_base_addr +
  21979. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  21980. + }
  21981. + if (maxwords & 1) {
  21982. + /*
  21983. + * RNG will complain with an AE in the RNGISR
  21984. + * if we don't complete the pairs of 32-bit reads
  21985. + * to its 64-bit register based FIFO
  21986. + */
  21987. + v = talitos_read(sc->sc_base_addr +
  21988. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  21989. + }
  21990. +
  21991. + return rc;
  21992. +}
  21993. +
  21994. +static void
  21995. +talitos_rng_init(struct talitos_softc *sc)
  21996. +{
  21997. + u_int32_t v;
  21998. +
  21999. + DPRINTF("%s()\n", __FUNCTION__);
  22000. + /* reset RNG EU */
  22001. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
  22002. + v |= TALITOS_RNGRCR_HI_SR;
  22003. + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
  22004. + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
  22005. + & TALITOS_RNGSR_HI_RD) == 0)
  22006. + cpu_relax();
  22007. + /*
  22008. + * we tell the RNG to start filling the RNG FIFO
  22009. + * by writing the RNGDSR
  22010. + */
  22011. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
  22012. + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
  22013. + /*
  22014. + * 64 bits of data will be pushed onto the FIFO every
  22015. + * 256 SEC cycles until the FIFO is full. The RNG then
  22016. + * attempts to keep the FIFO full.
  22017. + */
  22018. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  22019. + if (v) {
  22020. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  22021. + device_get_nameunit(sc->sc_cdev), v);
  22022. + return;
  22023. + }
  22024. + /*
  22025. + * n.b. we need to add a FIPS test here - if the RNG is going
  22026. + * to fail, it's going to fail at reset time
  22027. + */
  22028. + return;
  22029. +}
  22030. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  22031. +
  22032. +/*
  22033. + * Generate a new software session.
  22034. + */
  22035. +static int
  22036. +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  22037. +{
  22038. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  22039. + struct talitos_softc *sc = device_get_softc(dev);
  22040. + struct talitos_session *ses = NULL;
  22041. + int sesn;
  22042. +
  22043. + DPRINTF("%s()\n", __FUNCTION__);
  22044. + if (sidp == NULL || cri == NULL || sc == NULL) {
  22045. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  22046. + return EINVAL;
  22047. + }
  22048. + for (c = cri; c != NULL; c = c->cri_next) {
  22049. + if (c->cri_alg == CRYPTO_MD5 ||
  22050. + c->cri_alg == CRYPTO_MD5_HMAC ||
  22051. + c->cri_alg == CRYPTO_SHA1 ||
  22052. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  22053. + c->cri_alg == CRYPTO_NULL_HMAC) {
  22054. + if (macini)
  22055. + return EINVAL;
  22056. + macini = c;
  22057. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  22058. + c->cri_alg == CRYPTO_3DES_CBC ||
  22059. + c->cri_alg == CRYPTO_AES_CBC ||
  22060. + c->cri_alg == CRYPTO_NULL_CBC) {
  22061. + if (encini)
  22062. + return EINVAL;
  22063. + encini = c;
  22064. + } else {
  22065. + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
  22066. + return EINVAL;
  22067. + }
  22068. + }
  22069. + if (encini == NULL && macini == NULL)
  22070. + return EINVAL;
  22071. + if (encini) {
  22072. + /* validate key length */
  22073. + switch (encini->cri_alg) {
  22074. + case CRYPTO_DES_CBC:
  22075. + if (encini->cri_klen != 64)
  22076. + return EINVAL;
  22077. + break;
  22078. + case CRYPTO_3DES_CBC:
  22079. + if (encini->cri_klen != 192) {
  22080. + return EINVAL;
  22081. + }
  22082. + break;
  22083. + case CRYPTO_AES_CBC:
  22084. + if (encini->cri_klen != 128 &&
  22085. + encini->cri_klen != 192 &&
  22086. + encini->cri_klen != 256)
  22087. + return EINVAL;
  22088. + break;
  22089. + default:
  22090. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  22091. + encini->cri_alg);
  22092. + return EINVAL;
  22093. + }
  22094. + }
  22095. +
  22096. + if (sc->sc_sessions == NULL) {
  22097. + ses = sc->sc_sessions = (struct talitos_session *)
  22098. + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
  22099. + if (ses == NULL)
  22100. + return ENOMEM;
  22101. + memset(ses, 0, sizeof(struct talitos_session));
  22102. + sesn = 0;
  22103. + sc->sc_nsessions = 1;
  22104. + } else {
  22105. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  22106. + if (sc->sc_sessions[sesn].ses_used == 0) {
  22107. + ses = &sc->sc_sessions[sesn];
  22108. + break;
  22109. + }
  22110. + }
  22111. +
  22112. + if (ses == NULL) {
  22113. + /* allocating session */
  22114. + sesn = sc->sc_nsessions;
  22115. + ses = (struct talitos_session *) kmalloc(
  22116. + (sesn + 1) * sizeof(struct talitos_session),
  22117. + SLAB_ATOMIC);
  22118. + if (ses == NULL)
  22119. + return ENOMEM;
  22120. + memset(ses, 0,
  22121. + (sesn + 1) * sizeof(struct talitos_session));
  22122. + memcpy(ses, sc->sc_sessions,
  22123. + sesn * sizeof(struct talitos_session));
  22124. + memset(sc->sc_sessions, 0,
  22125. + sesn * sizeof(struct talitos_session));
  22126. + kfree(sc->sc_sessions);
  22127. + sc->sc_sessions = ses;
  22128. + ses = &sc->sc_sessions[sesn];
  22129. + sc->sc_nsessions++;
  22130. + }
  22131. + }
  22132. +
  22133. + ses->ses_used = 1;
  22134. +
  22135. + if (encini) {
  22136. + /* get an IV */
  22137. + /* XXX may read fewer than requested */
  22138. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  22139. +
  22140. + ses->ses_klen = (encini->cri_klen + 7) / 8;
  22141. + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
  22142. + if (macini) {
  22143. + /* doing hash on top of cipher */
  22144. + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
  22145. + memcpy(ses->ses_hmac, macini->cri_key,
  22146. + ses->ses_hmac_len);
  22147. + }
  22148. + } else if (macini) {
  22149. + /* doing hash */
  22150. + ses->ses_klen = (macini->cri_klen + 7) / 8;
  22151. + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
  22152. + }
  22153. +
  22154. + /* back compat way of determining MSC result len */
  22155. + if (macini) {
  22156. + ses->ses_mlen = macini->cri_mlen;
  22157. + if (ses->ses_mlen == 0) {
  22158. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  22159. + ses->ses_mlen = MD5_HASH_LEN;
  22160. + else
  22161. + ses->ses_mlen = SHA1_HASH_LEN;
  22162. + }
  22163. + }
  22164. +
  22165. + /* really should make up a template td here,
  22166. + * and only fill things like i/o and direction in process() */
  22167. +
  22168. + /* assign session ID */
  22169. + *sidp = TALITOS_SID(sc->sc_num, sesn);
  22170. + return 0;
  22171. +}
  22172. +
  22173. +/*
  22174. + * Deallocate a session.
  22175. + */
  22176. +static int
  22177. +talitos_freesession(device_t dev, u_int64_t tid)
  22178. +{
  22179. + struct talitos_softc *sc = device_get_softc(dev);
  22180. + int session, ret;
  22181. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  22182. +
  22183. + if (sc == NULL)
  22184. + return EINVAL;
  22185. + session = TALITOS_SESSION(sid);
  22186. + if (session < sc->sc_nsessions) {
  22187. + memset(&sc->sc_sessions[session], 0,
  22188. + sizeof(sc->sc_sessions[session]));
  22189. + ret = 0;
  22190. + } else
  22191. + ret = EINVAL;
  22192. + return ret;
  22193. +}
  22194. +
  22195. +/*
  22196. + * launch device processing - it will come back with done notification
  22197. + * in the form of an interrupt and/or HDR_DONE_BITS in header
  22198. + */
  22199. +static int
  22200. +talitos_submit(
  22201. + struct talitos_softc *sc,
  22202. + struct talitos_desc *td,
  22203. + int chsel)
  22204. +{
  22205. + u_int32_t v;
  22206. +
  22207. + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
  22208. + talitos_write(sc->sc_base_addr +
  22209. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
  22210. + talitos_write(sc->sc_base_addr +
  22211. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
  22212. + return 0;
  22213. +}
  22214. +
  22215. +static int
  22216. +talitos_process(device_t dev, struct cryptop *crp, int hint)
  22217. +{
  22218. + int i, err = 0, ivsize;
  22219. + struct talitos_softc *sc = device_get_softc(dev);
  22220. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  22221. + caddr_t iv;
  22222. + struct talitos_session *ses;
  22223. + struct talitos_desc *td;
  22224. + unsigned long flags;
  22225. + /* descriptor mappings */
  22226. + int hmac_key, hmac_data, cipher_iv, cipher_key,
  22227. + in_fifo, out_fifo, cipher_iv_out;
  22228. + static int chsel = -1;
  22229. +
  22230. + DPRINTF("%s()\n", __FUNCTION__);
  22231. +
  22232. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  22233. + return EINVAL;
  22234. + }
  22235. + crp->crp_etype = 0;
  22236. + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  22237. + return EINVAL;
  22238. + }
  22239. +
  22240. + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
  22241. +
  22242. + /* enter the channel scheduler */
  22243. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22244. +
  22245. + /* reuse channel that already had/has requests for the required EU */
  22246. + for (i = 0; i < sc->sc_num_channels; i++) {
  22247. + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
  22248. + break;
  22249. + }
  22250. + if (i == sc->sc_num_channels) {
  22251. + /*
  22252. + * haven't seen this algo the last sc_num_channels or more
  22253. + * use round robin in this case
  22254. + * nb: sc->sc_num_channels must be power of 2
  22255. + */
  22256. + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
  22257. + } else {
  22258. + /*
  22259. + * matches channel with same target execution unit;
  22260. + * use same channel in this case
  22261. + */
  22262. + chsel = i;
  22263. + }
  22264. + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
  22265. +
  22266. + /* release the channel scheduler lock */
  22267. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22268. +
  22269. + /* acquire the selected channel fifo lock */
  22270. + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
  22271. +
  22272. + /* find and reserve next available descriptor-cryptop pair */
  22273. + for (i = 0; i < sc->sc_chfifo_len; i++) {
  22274. + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
  22275. + /*
  22276. + * ensure correct descriptor formation by
  22277. + * avoiding inadvertently setting "optional" entries
  22278. + * e.g. not using "optional" dptr2 for MD/HMAC descs
  22279. + */
  22280. + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
  22281. + 0, sizeof(*td));
  22282. + /* reserve it with done notification request bit */
  22283. + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
  22284. + TALITOS_DONE_NOTIFY;
  22285. + break;
  22286. + }
  22287. + }
  22288. + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
  22289. +
  22290. + if (i == sc->sc_chfifo_len) {
  22291. + /* fifo full */
  22292. + err = ERESTART;
  22293. + goto errout;
  22294. + }
  22295. +
  22296. + td = &sc->sc_chnfifo[chsel][i].cf_desc;
  22297. + sc->sc_chnfifo[chsel][i].cf_crp = crp;
  22298. +
  22299. + crd1 = crp->crp_desc;
  22300. + if (crd1 == NULL) {
  22301. + err = EINVAL;
  22302. + goto errout;
  22303. + }
  22304. + crd2 = crd1->crd_next;
  22305. + /* prevent compiler warning */
  22306. + hmac_key = 0;
  22307. + hmac_data = 0;
  22308. + if (crd2 == NULL) {
  22309. + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
  22310. + /* assign descriptor dword ptr mappings for this desc. type */
  22311. + cipher_iv = 1;
  22312. + cipher_key = 2;
  22313. + in_fifo = 3;
  22314. + cipher_iv_out = 5;
  22315. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  22316. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  22317. + crd1->crd_alg == CRYPTO_SHA1 ||
  22318. + crd1->crd_alg == CRYPTO_MD5) {
  22319. + out_fifo = 5;
  22320. + maccrd = crd1;
  22321. + enccrd = NULL;
  22322. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  22323. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  22324. + crd1->crd_alg == CRYPTO_AES_CBC ||
  22325. + crd1->crd_alg == CRYPTO_ARC4) {
  22326. + out_fifo = 4;
  22327. + maccrd = NULL;
  22328. + enccrd = crd1;
  22329. + } else {
  22330. + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
  22331. + err = EINVAL;
  22332. + goto errout;
  22333. + }
  22334. + } else {
  22335. + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
  22336. + td->hdr |= TD_TYPE_IPSEC_ESP;
  22337. + } else {
  22338. + DPRINTF("unimplemented: multiple descriptor ipsec\n");
  22339. + err = EINVAL;
  22340. + goto errout;
  22341. + }
  22342. + /* assign descriptor dword ptr mappings for this desc. type */
  22343. + hmac_key = 0;
  22344. + hmac_data = 1;
  22345. + cipher_iv = 2;
  22346. + cipher_key = 3;
  22347. + in_fifo = 4;
  22348. + out_fifo = 5;
  22349. + cipher_iv_out = 6;
  22350. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  22351. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  22352. + crd1->crd_alg == CRYPTO_MD5 ||
  22353. + crd1->crd_alg == CRYPTO_SHA1) &&
  22354. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  22355. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  22356. + crd2->crd_alg == CRYPTO_AES_CBC ||
  22357. + crd2->crd_alg == CRYPTO_ARC4) &&
  22358. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  22359. + maccrd = crd1;
  22360. + enccrd = crd2;
  22361. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  22362. + crd1->crd_alg == CRYPTO_ARC4 ||
  22363. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  22364. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  22365. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  22366. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  22367. + crd2->crd_alg == CRYPTO_MD5 ||
  22368. + crd2->crd_alg == CRYPTO_SHA1) &&
  22369. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  22370. + enccrd = crd1;
  22371. + maccrd = crd2;
  22372. + } else {
  22373. + /* We cannot order the SEC as requested */
  22374. + printk("%s: cannot do the order\n",
  22375. + device_get_nameunit(sc->sc_cdev));
  22376. + err = EINVAL;
  22377. + goto errout;
  22378. + }
  22379. + }
  22380. + /* assign in_fifo and out_fifo based on input/output struct type */
  22381. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  22382. + /* using SKB buffers */
  22383. + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
  22384. + if (skb_shinfo(skb)->nr_frags) {
  22385. + printk("%s: skb frags unimplemented\n",
  22386. + device_get_nameunit(sc->sc_cdev));
  22387. + err = EINVAL;
  22388. + goto errout;
  22389. + }
  22390. + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
  22391. + skb->len, DMA_TO_DEVICE);
  22392. + td->ptr[in_fifo].len = skb->len;
  22393. + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
  22394. + skb->len, DMA_TO_DEVICE);
  22395. + td->ptr[out_fifo].len = skb->len;
  22396. + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
  22397. + skb->len, DMA_TO_DEVICE);
  22398. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  22399. + /* using IOV buffers */
  22400. + struct uio *uiop = (struct uio *)crp->crp_buf;
  22401. + if (uiop->uio_iovcnt > 1) {
  22402. + printk("%s: iov frags unimplemented\n",
  22403. + device_get_nameunit(sc->sc_cdev));
  22404. + err = EINVAL;
  22405. + goto errout;
  22406. + }
  22407. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  22408. + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
  22409. + td->ptr[in_fifo].len = crp->crp_ilen;
  22410. + /* crp_olen is never set; always use crp_ilen */
  22411. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  22412. + uiop->uio_iov->iov_base,
  22413. + crp->crp_ilen, DMA_TO_DEVICE);
  22414. + td->ptr[out_fifo].len = crp->crp_ilen;
  22415. + } else {
  22416. + /* using contig buffers */
  22417. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  22418. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  22419. + td->ptr[in_fifo].len = crp->crp_ilen;
  22420. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  22421. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  22422. + td->ptr[out_fifo].len = crp->crp_ilen;
  22423. + }
  22424. + if (enccrd) {
  22425. + switch (enccrd->crd_alg) {
  22426. + case CRYPTO_3DES_CBC:
  22427. + td->hdr |= TALITOS_MODE0_DEU_3DES;
  22428. + /* FALLTHROUGH */
  22429. + case CRYPTO_DES_CBC:
  22430. + td->hdr |= TALITOS_SEL0_DEU
  22431. + | TALITOS_MODE0_DEU_CBC;
  22432. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  22433. + td->hdr |= TALITOS_MODE0_DEU_ENC;
  22434. + ivsize = 2*sizeof(u_int32_t);
  22435. + DPRINTF("%cDES ses %d ch %d len %d\n",
  22436. + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
  22437. + (u32)TALITOS_SESSION(crp->crp_sid),
  22438. + chsel, td->ptr[in_fifo].len);
  22439. + break;
  22440. + case CRYPTO_AES_CBC:
  22441. + td->hdr |= TALITOS_SEL0_AESU
  22442. + | TALITOS_MODE0_AESU_CBC;
  22443. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  22444. + td->hdr |= TALITOS_MODE0_AESU_ENC;
  22445. + ivsize = 4*sizeof(u_int32_t);
  22446. + DPRINTF("AES ses %d ch %d len %d\n",
  22447. + (u32)TALITOS_SESSION(crp->crp_sid),
  22448. + chsel, td->ptr[in_fifo].len);
  22449. + break;
  22450. + default:
  22451. + printk("%s: unimplemented enccrd->crd_alg %d\n",
  22452. + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
  22453. + err = EINVAL;
  22454. + goto errout;
  22455. + }
  22456. + /*
  22457. + * Setup encrypt/decrypt state. When using basic ops
  22458. + * we can't use an inline IV because hash/crypt offset
  22459. + * must be from the end of the IV to the start of the
  22460. + * crypt data and this leaves out the preceding header
  22461. + * from the hash calculation. Instead we place the IV
  22462. + * in the state record and set the hash/crypt offset to
  22463. + * copy both the header+IV.
  22464. + */
  22465. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  22466. + td->hdr |= TALITOS_DIR_OUTBOUND;
  22467. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  22468. + iv = enccrd->crd_iv;
  22469. + else
  22470. + iv = (caddr_t) ses->ses_iv;
  22471. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  22472. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  22473. + enccrd->crd_inject, ivsize, iv);
  22474. + }
  22475. + } else {
  22476. + td->hdr |= TALITOS_DIR_INBOUND;
  22477. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  22478. + iv = enccrd->crd_iv;
  22479. + bcopy(enccrd->crd_iv, iv, ivsize);
  22480. + } else {
  22481. + iv = (caddr_t) ses->ses_iv;
  22482. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  22483. + enccrd->crd_inject, ivsize, iv);
  22484. + }
  22485. + }
  22486. + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
  22487. + DMA_TO_DEVICE);
  22488. + td->ptr[cipher_iv].len = ivsize;
  22489. + /*
  22490. + * we don't need the cipher iv out length/pointer
  22491. + * field to do ESP IPsec. Therefore we set the len field as 0,
  22492. + * which tells the SEC not to do anything with this len/ptr
  22493. + * field. Previously, when length/pointer as pointing to iv,
  22494. + * it gave us corruption of packets.
  22495. + */
  22496. + td->ptr[cipher_iv_out].len = 0;
  22497. + }
  22498. + if (enccrd && maccrd) {
  22499. + /* this is ipsec only for now */
  22500. + td->hdr |= TALITOS_SEL1_MDEU
  22501. + | TALITOS_MODE1_MDEU_INIT
  22502. + | TALITOS_MODE1_MDEU_PAD;
  22503. + switch (maccrd->crd_alg) {
  22504. + case CRYPTO_MD5:
  22505. + td->hdr |= TALITOS_MODE1_MDEU_MD5;
  22506. + break;
  22507. + case CRYPTO_MD5_HMAC:
  22508. + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
  22509. + break;
  22510. + case CRYPTO_SHA1:
  22511. + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
  22512. + break;
  22513. + case CRYPTO_SHA1_HMAC:
  22514. + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
  22515. + break;
  22516. + default:
  22517. + /* We cannot order the SEC as requested */
  22518. + printk("%s: cannot do the order\n",
  22519. + device_get_nameunit(sc->sc_cdev));
  22520. + err = EINVAL;
  22521. + goto errout;
  22522. + }
  22523. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  22524. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  22525. + /*
  22526. + * The offset from hash data to the start of
  22527. + * crypt data is the difference in the skips.
  22528. + */
  22529. + /* ipsec only for now */
  22530. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  22531. + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
  22532. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  22533. + td->ptr[in_fifo].ptr += enccrd->crd_skip;
  22534. + td->ptr[in_fifo].len = enccrd->crd_len;
  22535. + td->ptr[out_fifo].ptr += enccrd->crd_skip;
  22536. + td->ptr[out_fifo].len = enccrd->crd_len;
  22537. + /* bytes of HMAC to postpend to ciphertext */
  22538. + td->ptr[out_fifo].extent = ses->ses_mlen;
  22539. + td->ptr[hmac_data].ptr += maccrd->crd_skip;
  22540. + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
  22541. + }
  22542. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  22543. + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
  22544. + device_get_nameunit(sc->sc_cdev));
  22545. + }
  22546. + }
  22547. + if (!enccrd && maccrd) {
  22548. + /* single MD5 or SHA */
  22549. + td->hdr |= TALITOS_SEL0_MDEU
  22550. + | TALITOS_MODE0_MDEU_INIT
  22551. + | TALITOS_MODE0_MDEU_PAD;
  22552. + switch (maccrd->crd_alg) {
  22553. + case CRYPTO_MD5:
  22554. + td->hdr |= TALITOS_MODE0_MDEU_MD5;
  22555. + DPRINTF("MD5 ses %d ch %d len %d\n",
  22556. + (u32)TALITOS_SESSION(crp->crp_sid),
  22557. + chsel, td->ptr[in_fifo].len);
  22558. + break;
  22559. + case CRYPTO_MD5_HMAC:
  22560. + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
  22561. + break;
  22562. + case CRYPTO_SHA1:
  22563. + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
  22564. + DPRINTF("SHA1 ses %d ch %d len %d\n",
  22565. + (u32)TALITOS_SESSION(crp->crp_sid),
  22566. + chsel, td->ptr[in_fifo].len);
  22567. + break;
  22568. + case CRYPTO_SHA1_HMAC:
  22569. + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
  22570. + break;
  22571. + default:
  22572. + /* We cannot order the SEC as requested */
  22573. + DPRINTF("cannot do the order\n");
  22574. + err = EINVAL;
  22575. + goto errout;
  22576. + }
  22577. +
  22578. + if (crp->crp_flags & CRYPTO_F_IOV)
  22579. + td->ptr[out_fifo].ptr += maccrd->crd_inject;
  22580. +
  22581. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  22582. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  22583. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  22584. + ses->ses_hmac, ses->ses_hmac_len,
  22585. + DMA_TO_DEVICE);
  22586. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  22587. + }
  22588. + }
  22589. + else {
  22590. + /* using process key (session data has duplicate) */
  22591. + td->ptr[cipher_key].ptr = dma_map_single(NULL,
  22592. + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
  22593. + DMA_TO_DEVICE);
  22594. + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
  22595. + }
  22596. + /* descriptor complete - GO! */
  22597. + return talitos_submit(sc, td, chsel);
  22598. +
  22599. +errout:
  22600. + if (err != ERESTART) {
  22601. + crp->crp_etype = err;
  22602. + crypto_done(crp);
  22603. + }
  22604. + return err;
  22605. +}
  22606. +
  22607. +/* go through all channels descriptors, notifying OCF what has
  22608. + * _and_hasn't_ successfully completed and reset the device
  22609. + * (otherwise it's up to decoding desc hdrs!)
  22610. + */
  22611. +static void talitos_errorprocessing(struct talitos_softc *sc)
  22612. +{
  22613. + unsigned long flags;
  22614. + int i, j;
  22615. +
  22616. + /* disable further scheduling until under control */
  22617. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22618. +
  22619. + if (debug) dump_talitos_status(sc);
  22620. + /* go through descriptors, try and salvage those successfully done,
  22621. + * and EIO those that weren't
  22622. + */
  22623. + for (i = 0; i < sc->sc_num_channels; i++) {
  22624. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  22625. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  22626. + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
  22627. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  22628. + & TALITOS_HDR_DONE_BITS)
  22629. + != TALITOS_HDR_DONE_BITS) {
  22630. + /* this one didn't finish */
  22631. + /* signify in crp->etype */
  22632. + sc->sc_chnfifo[i][j].cf_crp->crp_etype
  22633. + = EIO;
  22634. + }
  22635. + } else
  22636. + continue; /* free entry */
  22637. + /* either way, notify ocf */
  22638. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  22639. + /* and tag it available again
  22640. + *
  22641. + * memset to ensure correct descriptor formation by
  22642. + * avoiding inadvertently setting "optional" entries
  22643. + * e.g. not using "optional" dptr2 MD/HMAC processing
  22644. + */
  22645. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  22646. + 0, sizeof(struct talitos_desc));
  22647. + }
  22648. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  22649. + }
  22650. + /* reset and initialize the SEC h/w device */
  22651. + talitos_reset_device(sc);
  22652. + talitos_init_device(sc);
  22653. +#ifdef CONFIG_OCF_RANDOMHARVEST
  22654. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
  22655. + talitos_rng_init(sc);
  22656. +#endif
  22657. +
  22658. + /* Okay. Stand by. */
  22659. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22660. +
  22661. + return;
  22662. +}
  22663. +
  22664. +/* go through all channels descriptors, notifying OCF what's been done */
  22665. +static void talitos_doneprocessing(struct talitos_softc *sc)
  22666. +{
  22667. + unsigned long flags;
  22668. + int i, j;
  22669. +
  22670. + /* go through descriptors looking for done bits */
  22671. + for (i = 0; i < sc->sc_num_channels; i++) {
  22672. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  22673. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  22674. + /* descriptor has done bits set? */
  22675. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  22676. + & TALITOS_HDR_DONE_BITS)
  22677. + == TALITOS_HDR_DONE_BITS) {
  22678. + /* notify ocf */
  22679. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  22680. + /* and tag it available again
  22681. + *
  22682. + * memset to ensure correct descriptor formation by
  22683. + * avoiding inadvertently setting "optional" entries
  22684. + * e.g. not using "optional" dptr2 MD/HMAC processing
  22685. + */
  22686. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  22687. + 0, sizeof(struct talitos_desc));
  22688. + }
  22689. + }
  22690. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  22691. + }
  22692. + return;
  22693. +}
  22694. +
  22695. +static irqreturn_t
  22696. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  22697. +talitos_intr(int irq, void *arg)
  22698. +#else
  22699. +talitos_intr(int irq, void *arg, struct pt_regs *regs)
  22700. +#endif
  22701. +{
  22702. + struct talitos_softc *sc = arg;
  22703. + u_int32_t v, v_hi;
  22704. +
  22705. + /* ack */
  22706. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  22707. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  22708. + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
  22709. + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
  22710. +
  22711. + if (unlikely(v & TALITOS_ISR_ERROR)) {
  22712. + /* Okay, Houston, we've had a problem here. */
  22713. + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
  22714. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  22715. + talitos_errorprocessing(sc);
  22716. + } else
  22717. + if (likely(v & TALITOS_ISR_DONE)) {
  22718. + talitos_doneprocessing(sc);
  22719. + }
  22720. + return IRQ_HANDLED;
  22721. +}
  22722. +
  22723. +/*
  22724. + * Initialize registers we need to touch only once.
  22725. + */
  22726. +static void
  22727. +talitos_init_device(struct talitos_softc *sc)
  22728. +{
  22729. + u_int32_t v;
  22730. + int i;
  22731. +
  22732. + DPRINTF("%s()\n", __FUNCTION__);
  22733. +
  22734. + /* init all channels */
  22735. + for (i = 0; i < sc->sc_num_channels; i++) {
  22736. + v = talitos_read(sc->sc_base_addr +
  22737. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
  22738. + v |= TALITOS_CH_CCCR_HI_CDWE
  22739. + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
  22740. + talitos_write(sc->sc_base_addr +
  22741. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
  22742. + }
  22743. + /* enable all interrupts */
  22744. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  22745. + v |= TALITOS_IMR_ALL;
  22746. + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
  22747. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  22748. + v |= TALITOS_IMR_HI_ERRONLY;
  22749. + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
  22750. + return;
  22751. +}
  22752. +
  22753. +/*
  22754. + * set the master reset bit on the device.
  22755. + */
  22756. +static void
  22757. +talitos_reset_device_master(struct talitos_softc *sc)
  22758. +{
  22759. + u_int32_t v;
  22760. +
  22761. + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
  22762. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  22763. + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
  22764. +
  22765. + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
  22766. + cpu_relax();
  22767. +
  22768. + return;
  22769. +}
  22770. +
  22771. +/*
  22772. + * Resets the device. Values in the registers are left as is
  22773. + * from the reset (i.e. initial values are assigned elsewhere).
  22774. + */
  22775. +static void
  22776. +talitos_reset_device(struct talitos_softc *sc)
  22777. +{
  22778. + u_int32_t v;
  22779. + int i;
  22780. +
  22781. + DPRINTF("%s()\n", __FUNCTION__);
  22782. +
  22783. + /*
  22784. + * Master reset
  22785. + * errata documentation: warning: certain SEC interrupts
  22786. + * are not fully cleared by writing the MCR:SWR bit,
  22787. + * set bit twice to completely reset
  22788. + */
  22789. + talitos_reset_device_master(sc); /* once */
  22790. + talitos_reset_device_master(sc); /* and once again */
  22791. +
  22792. + /* reset all channels */
  22793. + for (i = 0; i < sc->sc_num_channels; i++) {
  22794. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  22795. + TALITOS_CH_CCCR);
  22796. + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  22797. + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
  22798. + }
  22799. +}
  22800. +
  22801. +/* Set up the crypto device structure, private data,
  22802. + * and anything else we need before we start */
  22803. +#ifdef CONFIG_PPC_MERGE
  22804. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
  22805. +#else
  22806. +static int talitos_probe(struct platform_device *pdev)
  22807. +#endif
  22808. +{
  22809. + struct talitos_softc *sc = NULL;
  22810. + struct resource *r;
  22811. +#ifdef CONFIG_PPC_MERGE
  22812. + struct device *device = &ofdev->dev;
  22813. + struct device_node *np = ofdev->node;
  22814. + const unsigned int *prop;
  22815. + int err;
  22816. + struct resource res;
  22817. +#endif
  22818. + static int num_chips = 0;
  22819. + int rc;
  22820. + int i;
  22821. +
  22822. + DPRINTF("%s()\n", __FUNCTION__);
  22823. +
  22824. + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  22825. + if (!sc)
  22826. + return -ENOMEM;
  22827. + memset(sc, 0, sizeof(*sc));
  22828. +
  22829. + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
  22830. +
  22831. + sc->sc_irq = -1;
  22832. + sc->sc_cid = -1;
  22833. +#ifndef CONFIG_PPC_MERGE
  22834. + sc->sc_dev = pdev;
  22835. +#endif
  22836. + sc->sc_num = num_chips++;
  22837. +
  22838. +#ifdef CONFIG_PPC_MERGE
  22839. + dev_set_drvdata(device, sc);
  22840. +#else
  22841. + platform_set_drvdata(sc->sc_dev, sc);
  22842. +#endif
  22843. +
  22844. + /* get the irq line */
  22845. +#ifdef CONFIG_PPC_MERGE
  22846. + err = of_address_to_resource(np, 0, &res);
  22847. + if (err)
  22848. + return -EINVAL;
  22849. + r = &res;
  22850. +
  22851. + sc->sc_irq = irq_of_parse_and_map(np, 0);
  22852. +#else
  22853. + /* get a pointer to the register memory */
  22854. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  22855. +
  22856. + sc->sc_irq = platform_get_irq(pdev, 0);
  22857. +#endif
  22858. + rc = request_irq(sc->sc_irq, talitos_intr, 0,
  22859. + device_get_nameunit(sc->sc_cdev), sc);
  22860. + if (rc) {
  22861. + printk(KERN_ERR "%s: failed to hook irq %d\n",
  22862. + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
  22863. + sc->sc_irq = -1;
  22864. + goto out;
  22865. + }
  22866. +
  22867. + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
  22868. + if (!sc->sc_base_addr) {
  22869. + printk(KERN_ERR "%s: failed to ioremap\n",
  22870. + device_get_nameunit(sc->sc_cdev));
  22871. + goto out;
  22872. + }
  22873. +
  22874. + /* figure out our SEC's properties and capabilities */
  22875. + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
  22876. + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
  22877. + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
  22878. +
  22879. +#ifdef CONFIG_PPC_MERGE
  22880. + /* get SEC properties from device tree, defaulting to SEC 2.0 */
  22881. +
  22882. + prop = of_get_property(np, "num-channels", NULL);
  22883. + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
  22884. +
  22885. + prop = of_get_property(np, "channel-fifo-len", NULL);
  22886. + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
  22887. +
  22888. + prop = of_get_property(np, "exec-units-mask", NULL);
  22889. + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
  22890. +
  22891. + prop = of_get_property(np, "descriptor-types-mask", NULL);
  22892. + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
  22893. +#else
  22894. + /* bulk should go away with openfirmware flat device tree support */
  22895. + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
  22896. + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
  22897. + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
  22898. + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
  22899. + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
  22900. + } else {
  22901. + printk(KERN_ERR "%s: failed to id device\n",
  22902. + device_get_nameunit(sc->sc_cdev));
  22903. + goto out;
  22904. + }
  22905. +#endif
  22906. +
  22907. + /* + 1 is for the meta-channel lock used by the channel scheduler */
  22908. + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
  22909. + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
  22910. + if (!sc->sc_chnfifolock)
  22911. + goto out;
  22912. + for (i = 0; i < sc->sc_num_channels + 1; i++) {
  22913. + spin_lock_init(&sc->sc_chnfifolock[i]);
  22914. + }
  22915. +
  22916. + sc->sc_chnlastalg = (int *) kmalloc(
  22917. + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
  22918. + if (!sc->sc_chnlastalg)
  22919. + goto out;
  22920. + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
  22921. +
  22922. + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
  22923. + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
  22924. + GFP_KERNEL);
  22925. + if (!sc->sc_chnfifo)
  22926. + goto out;
  22927. + for (i = 0; i < sc->sc_num_channels; i++) {
  22928. + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
  22929. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
  22930. + GFP_KERNEL);
  22931. + if (!sc->sc_chnfifo[i])
  22932. + goto out;
  22933. + memset(sc->sc_chnfifo[i], 0,
  22934. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
  22935. + }
  22936. +
  22937. + /* reset and initialize the SEC h/w device */
  22938. + talitos_reset_device(sc);
  22939. + talitos_init_device(sc);
  22940. +
  22941. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  22942. + if (sc->sc_cid < 0) {
  22943. + printk(KERN_ERR "%s: could not get crypto driver id\n",
  22944. + device_get_nameunit(sc->sc_cdev));
  22945. + goto out;
  22946. + }
  22947. +
  22948. + /* register algorithms with the framework */
  22949. + printk("%s:", device_get_nameunit(sc->sc_cdev));
  22950. +
  22951. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
  22952. + printk(" rng");
  22953. +#ifdef CONFIG_OCF_RANDOMHARVEST
  22954. + talitos_rng_init(sc);
  22955. + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
  22956. +#endif
  22957. + }
  22958. + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
  22959. + printk(" des/3des");
  22960. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  22961. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  22962. + }
  22963. + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
  22964. + printk(" aes");
  22965. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  22966. + }
  22967. + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
  22968. + printk(" md5");
  22969. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  22970. + /* HMAC support only with IPsec for now */
  22971. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  22972. + printk(" sha1");
  22973. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  22974. + /* HMAC support only with IPsec for now */
  22975. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  22976. + }
  22977. + printk("\n");
  22978. + return 0;
  22979. +
  22980. +out:
  22981. +#ifndef CONFIG_PPC_MERGE
  22982. + talitos_remove(pdev);
  22983. +#endif
  22984. + return -ENOMEM;
  22985. +}
  22986. +
  22987. +#ifdef CONFIG_PPC_MERGE
  22988. +static int talitos_remove(struct of_device *ofdev)
  22989. +#else
  22990. +static int talitos_remove(struct platform_device *pdev)
  22991. +#endif
  22992. +{
  22993. +#ifdef CONFIG_PPC_MERGE
  22994. + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
  22995. +#else
  22996. + struct talitos_softc *sc = platform_get_drvdata(pdev);
  22997. +#endif
  22998. + int i;
  22999. +
  23000. + DPRINTF("%s()\n", __FUNCTION__);
  23001. + if (sc->sc_cid >= 0)
  23002. + crypto_unregister_all(sc->sc_cid);
  23003. + if (sc->sc_chnfifo) {
  23004. + for (i = 0; i < sc->sc_num_channels; i++)
  23005. + if (sc->sc_chnfifo[i])
  23006. + kfree(sc->sc_chnfifo[i]);
  23007. + kfree(sc->sc_chnfifo);
  23008. + }
  23009. + if (sc->sc_chnlastalg)
  23010. + kfree(sc->sc_chnlastalg);
  23011. + if (sc->sc_chnfifolock)
  23012. + kfree(sc->sc_chnfifolock);
  23013. + if (sc->sc_irq != -1)
  23014. + free_irq(sc->sc_irq, sc);
  23015. + if (sc->sc_base_addr)
  23016. + iounmap((void *) sc->sc_base_addr);
  23017. + kfree(sc);
  23018. + return 0;
  23019. +}
  23020. +
  23021. +#ifdef CONFIG_PPC_MERGE
  23022. +static struct of_device_id talitos_match[] = {
  23023. + {
  23024. + .type = "crypto",
  23025. + .compatible = "talitos",
  23026. + },
  23027. + {},
  23028. +};
  23029. +
  23030. +MODULE_DEVICE_TABLE(of, talitos_match);
  23031. +
  23032. +static struct of_platform_driver talitos_driver = {
  23033. + .name = DRV_NAME,
  23034. + .match_table = talitos_match,
  23035. + .probe = talitos_probe,
  23036. + .remove = talitos_remove,
  23037. +};
  23038. +
  23039. +static int __init talitos_init(void)
  23040. +{
  23041. + return of_register_platform_driver(&talitos_driver);
  23042. +}
  23043. +
  23044. +static void __exit talitos_exit(void)
  23045. +{
  23046. + of_unregister_platform_driver(&talitos_driver);
  23047. +}
  23048. +#else
  23049. +/* Structure for a platform device driver */
  23050. +static struct platform_driver talitos_driver = {
  23051. + .probe = talitos_probe,
  23052. + .remove = talitos_remove,
  23053. + .driver = {
  23054. + .name = "fsl-sec2",
  23055. + }
  23056. +};
  23057. +
  23058. +static int __init talitos_init(void)
  23059. +{
  23060. + return platform_driver_register(&talitos_driver);
  23061. +}
  23062. +
  23063. +static void __exit talitos_exit(void)
  23064. +{
  23065. + platform_driver_unregister(&talitos_driver);
  23066. +}
  23067. +#endif
  23068. +
  23069. +module_init(talitos_init);
  23070. +module_exit(talitos_exit);
  23071. +
  23072. +MODULE_LICENSE("Dual BSD/GPL");
  23073. +MODULE_AUTHOR("kim.phillips@freescale.com");
  23074. +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
  23075. diff -Nur linux-2.6.27.10.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.27.10/crypto/ocf/talitos/talitos_dev.h
  23076. --- linux-2.6.27.10.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
  23077. +++ linux-2.6.27.10/crypto/ocf/talitos/talitos_dev.h 2008-12-23 19:31:44.000000000 +0100
  23078. @@ -0,0 +1,277 @@
  23079. +/*
  23080. + * Freescale SEC (talitos) device dependent data structures
  23081. + *
  23082. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  23083. + *
  23084. + * Redistribution and use in source and binary forms, with or without
  23085. + * modification, are permitted provided that the following conditions
  23086. + * are met:
  23087. + *
  23088. + * 1. Redistributions of source code must retain the above copyright
  23089. + * notice, this list of conditions and the following disclaimer.
  23090. + * 2. Redistributions in binary form must reproduce the above copyright
  23091. + * notice, this list of conditions and the following disclaimer in the
  23092. + * documentation and/or other materials provided with the distribution.
  23093. + * 3. The name of the author may not be used to endorse or promote products
  23094. + * derived from this software without specific prior written permission.
  23095. + *
  23096. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23097. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23098. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23099. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23100. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23101. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23102. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23103. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23104. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23105. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23106. + *
  23107. + */
  23108. +
  23109. +/* device ID register values */
  23110. +#define TALITOS_ID_SEC_2_0 0x40
  23111. +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
  23112. +
  23113. +/*
  23114. + * following num_channels, channel-fifo-depth, exec-unit-mask, and
  23115. + * descriptor-types-mask are for forward-compatibility with openfirmware
  23116. + * flat device trees
  23117. + */
  23118. +
  23119. +/*
  23120. + * num_channels : the number of channels available in each SEC version.
  23121. + */
  23122. +
  23123. +/* n.b. this driver requires these values be a power of 2 */
  23124. +#define TALITOS_NCHANNELS_SEC_1_0 4
  23125. +#define TALITOS_NCHANNELS_SEC_1_2 1
  23126. +#define TALITOS_NCHANNELS_SEC_2_0 4
  23127. +#define TALITOS_NCHANNELS_SEC_2_01 4
  23128. +#define TALITOS_NCHANNELS_SEC_2_1 4
  23129. +#define TALITOS_NCHANNELS_SEC_2_4 4
  23130. +
  23131. +/*
  23132. + * channel-fifo-depth : The number of descriptor
  23133. + * pointers a channel fetch fifo can hold.
  23134. + */
  23135. +#define TALITOS_CHFIFOLEN_SEC_1_0 1
  23136. +#define TALITOS_CHFIFOLEN_SEC_1_2 1
  23137. +#define TALITOS_CHFIFOLEN_SEC_2_0 24
  23138. +#define TALITOS_CHFIFOLEN_SEC_2_01 24
  23139. +#define TALITOS_CHFIFOLEN_SEC_2_1 24
  23140. +#define TALITOS_CHFIFOLEN_SEC_2_4 24
  23141. +
  23142. +/*
  23143. + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
  23144. + * are available. EU information should be encoded following the SEC's
  23145. + * EU_SEL0 bitfield documentation, i.e. as follows:
  23146. + *
  23147. + * bit 31 = set if SEC permits no-EU selection (should be always set)
  23148. + * bit 30 = set if SEC has the ARC4 EU (AFEU)
  23149. + * bit 29 = set if SEC has the des/3des EU (DEU)
  23150. + * bit 28 = set if SEC has the message digest EU (MDEU)
  23151. + * bit 27 = set if SEC has the random number generator EU (RNG)
  23152. + * bit 26 = set if SEC has the public key EU (PKEU)
  23153. + * bit 25 = set if SEC has the aes EU (AESU)
  23154. + * bit 24 = set if SEC has the Kasumi EU (KEU)
  23155. + *
  23156. + */
  23157. +#define TALITOS_HAS_EU_NONE (1<<0)
  23158. +#define TALITOS_HAS_EU_AFEU (1<<1)
  23159. +#define TALITOS_HAS_EU_DEU (1<<2)
  23160. +#define TALITOS_HAS_EU_MDEU (1<<3)
  23161. +#define TALITOS_HAS_EU_RNG (1<<4)
  23162. +#define TALITOS_HAS_EU_PKEU (1<<5)
  23163. +#define TALITOS_HAS_EU_AESU (1<<6)
  23164. +#define TALITOS_HAS_EU_KEU (1<<7)
  23165. +
  23166. +/* the corresponding masks for each SEC version */
  23167. +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
  23168. +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
  23169. +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
  23170. +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
  23171. +#define TALITOS_HAS_EUS_SEC_2_1 0xff
  23172. +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
  23173. +
  23174. +/*
  23175. + * descriptor-types-mask : The bitmask representing what descriptors
  23176. + * are available. Descriptor type information should be encoded
  23177. + * following the SEC's Descriptor Header Dword DESC_TYPE field
  23178. + * documentation, i.e. as follows:
  23179. + *
  23180. + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
  23181. + * bit 1 = set if SEC supports the ipsec_esp descriptor type
  23182. + * bit 2 = set if SEC supports the common_nonsnoop desc. type
  23183. + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
  23184. + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
  23185. + * bit 5 = set if SEC supports the srtp descriptor type
  23186. + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
  23187. + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
  23188. + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
  23189. + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
  23190. + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
  23191. + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
  23192. + *
  23193. + * ..and so on and so forth.
  23194. + */
  23195. +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
  23196. +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
  23197. +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
  23198. +
  23199. +/* the corresponding masks for each SEC version */
  23200. +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
  23201. +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
  23202. +
  23203. +/*
  23204. + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
  23205. + */
  23206. +
  23207. +/* global register offset addresses */
  23208. +#define TALITOS_ID 0x1020
  23209. +#define TALITOS_ID_HI 0x1024
  23210. +#define TALITOS_MCR 0x1030 /* master control register */
  23211. +#define TALITOS_MCR_HI 0x1038 /* master control register */
  23212. +#define TALITOS_MCR_SWR 0x1
  23213. +#define TALITOS_IMR 0x1008 /* interrupt mask register */
  23214. +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
  23215. +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
  23216. +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
  23217. +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
  23218. +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
  23219. +#define TALITOS_ISR 0x1010 /* interrupt status register */
  23220. +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
  23221. +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
  23222. +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
  23223. +#define TALITOS_ICR 0x1018 /* interrupt clear register */
  23224. +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
  23225. +
  23226. +/* channel register address stride */
  23227. +#define TALITOS_CH_OFFSET 0x100
  23228. +
  23229. +/* channel register offset addresses and bits */
  23230. +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
  23231. +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
  23232. +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
  23233. +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
  23234. +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
  23235. +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
  23236. +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
  23237. +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
  23238. +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
  23239. +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
  23240. +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
  23241. +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
  23242. +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
  23243. + * Descriptor Buffer (debug) */
  23244. +
  23245. +/* execution unit register offset addresses and bits */
  23246. +#define TALITOS_DEUSR 0x2028 /* DEU status register */
  23247. +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
  23248. +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
  23249. +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
  23250. +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
  23251. +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
  23252. +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
  23253. +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
  23254. +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
  23255. +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
  23256. +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
  23257. +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
  23258. +#define TALITOS_RNGSR 0xa028 /* RNG status register */
  23259. +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
  23260. +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
  23261. +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
  23262. +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
  23263. +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
  23264. +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
  23265. +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
  23266. +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
  23267. +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
  23268. +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
  23269. +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
  23270. +
  23271. +/* descriptor pointer entry */
  23272. +struct talitos_desc_ptr {
  23273. + u16 len; /* length */
  23274. + u8 extent; /* jump (to s/g link table) and extent */
  23275. + u8 res; /* reserved */
  23276. + u32 ptr; /* pointer */
  23277. +};
  23278. +
  23279. +/* descriptor */
  23280. +struct talitos_desc {
  23281. + u32 hdr; /* header */
  23282. + u32 res; /* reserved */
  23283. + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
  23284. +};
  23285. +
  23286. +/* talitos descriptor header (hdr) bits */
  23287. +
  23288. +/* primary execution unit select */
  23289. +#define TALITOS_SEL0_AFEU 0x10000000
  23290. +#define TALITOS_SEL0_DEU 0x20000000
  23291. +#define TALITOS_SEL0_MDEU 0x30000000
  23292. +#define TALITOS_SEL0_RNG 0x40000000
  23293. +#define TALITOS_SEL0_PKEU 0x50000000
  23294. +#define TALITOS_SEL0_AESU 0x60000000
  23295. +
  23296. +/* primary execution unit mode (MODE0) and derivatives */
  23297. +#define TALITOS_MODE0_AESU_CBC 0x00200000
  23298. +#define TALITOS_MODE0_AESU_ENC 0x00100000
  23299. +#define TALITOS_MODE0_DEU_CBC 0x00400000
  23300. +#define TALITOS_MODE0_DEU_3DES 0x00200000
  23301. +#define TALITOS_MODE0_DEU_ENC 0x00100000
  23302. +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
  23303. +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
  23304. +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
  23305. +#define TALITOS_MODE0_MDEU_MD5 0x00200000
  23306. +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
  23307. +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
  23308. +#define TALITOS_MODE0_MDEU_MD5_HMAC \
  23309. + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
  23310. +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
  23311. + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
  23312. +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
  23313. + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
  23314. +
  23315. +/* secondary execution unit select (SEL1) */
  23316. +/* it's MDEU or nothing */
  23317. +#define TALITOS_SEL1_MDEU 0x00030000
  23318. +
  23319. +/* secondary execution unit mode (MODE1) and derivatives */
  23320. +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
  23321. +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
  23322. +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
  23323. +#define TALITOS_MODE1_MDEU_MD5 0x00000200
  23324. +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
  23325. +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
  23326. +#define TALITOS_MODE1_MDEU_MD5_HMAC \
  23327. + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
  23328. +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
  23329. + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
  23330. +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
  23331. + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
  23332. +
  23333. +/* direction of overall data flow (DIR) */
  23334. +#define TALITOS_DIR_OUTBOUND 0x00000000
  23335. +#define TALITOS_DIR_INBOUND 0x00000002
  23336. +
  23337. +/* done notification (DN) */
  23338. +#define TALITOS_DONE_NOTIFY 0x00000001
  23339. +
  23340. +/* descriptor types */
  23341. +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
  23342. +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
  23343. +#define TD_TYPE_IPSEC_ESP (1 << 3)
  23344. +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
  23345. +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
  23346. +
  23347. +#define TALITOS_HDR_DONE_BITS 0xff000000
  23348. +
  23349. +#define DPRINTF(a...) do { \
  23350. + if (debug) { \
  23351. + printk("%s: ", sc ? \
  23352. + device_get_nameunit(sc->sc_cdev) : "talitos"); \
  23353. + printk(a); \
  23354. + } \
  23355. + } while (0)
  23356. diff -Nur linux-2.6.27.10.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.27.10/crypto/ocf/talitos/talitos_soft.h
  23357. --- linux-2.6.27.10.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
  23358. +++ linux-2.6.27.10/crypto/ocf/talitos/talitos_soft.h 2008-12-23 19:31:44.000000000 +0100
  23359. @@ -0,0 +1,77 @@
  23360. +/*
  23361. + * Freescale SEC data structures for integration with ocf-linux
  23362. + *
  23363. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  23364. + *
  23365. + * Redistribution and use in source and binary forms, with or without
  23366. + * modification, are permitted provided that the following conditions
  23367. + * are met:
  23368. + *
  23369. + * 1. Redistributions of source code must retain the above copyright
  23370. + * notice, this list of conditions and the following disclaimer.
  23371. + * 2. Redistributions in binary form must reproduce the above copyright
  23372. + * notice, this list of conditions and the following disclaimer in the
  23373. + * documentation and/or other materials provided with the distribution.
  23374. + * 3. The name of the author may not be used to endorse or promote products
  23375. + * derived from this software without specific prior written permission.
  23376. + *
  23377. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23378. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23379. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23380. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23381. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23382. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23383. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23384. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23385. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23386. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23387. + */
  23388. +
  23389. +/*
  23390. + * paired descriptor and associated crypto operation
  23391. + */
  23392. +struct desc_cryptop_pair {
  23393. + struct talitos_desc cf_desc; /* descriptor ptr */
  23394. + struct cryptop *cf_crp; /* cryptop ptr */
  23395. +};
  23396. +
  23397. +/*
  23398. + * Holds data specific to a single talitos device.
  23399. + */
  23400. +struct talitos_softc {
  23401. + softc_device_decl sc_cdev;
  23402. + struct platform_device *sc_dev; /* device backpointer */
  23403. + ocf_iomem_t sc_base_addr;
  23404. + int sc_irq;
  23405. + int sc_num; /* if we have multiple chips */
  23406. + int32_t sc_cid; /* crypto tag */
  23407. + u64 sc_chiprev; /* major/minor chip revision */
  23408. + int sc_nsessions;
  23409. + struct talitos_session *sc_sessions;
  23410. + int sc_num_channels;/* number of crypto channels */
  23411. + int sc_chfifo_len; /* channel fetch fifo len */
  23412. + int sc_exec_units; /* execution units mask */
  23413. + int sc_desc_types; /* descriptor types mask */
  23414. + /*
  23415. + * mutual exclusion for intra-channel resources, e.g. fetch fifos
  23416. + * the last entry is a meta-channel lock used by the channel scheduler
  23417. + */
  23418. + spinlock_t *sc_chnfifolock;
  23419. + /* sc_chnlastalgo contains last algorithm for that channel */
  23420. + int *sc_chnlastalg;
  23421. + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
  23422. + struct desc_cryptop_pair **sc_chnfifo;
  23423. +};
  23424. +
  23425. +struct talitos_session {
  23426. + u_int32_t ses_used;
  23427. + u_int32_t ses_klen; /* key length in bits */
  23428. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  23429. + u_int32_t ses_hmac[5]; /* hmac inner state */
  23430. + u_int32_t ses_hmac_len; /* hmac length */
  23431. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  23432. + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
  23433. +};
  23434. +
  23435. +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
  23436. +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  23437. diff -Nur linux-2.6.27.10.orig/crypto/ocf/uio.h linux-2.6.27.10/crypto/ocf/uio.h
  23438. --- linux-2.6.27.10.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
  23439. +++ linux-2.6.27.10/crypto/ocf/uio.h 2008-12-23 19:31:44.000000000 +0100
  23440. @@ -0,0 +1,54 @@
  23441. +#ifndef _OCF_UIO_H_
  23442. +#define _OCF_UIO_H_
  23443. +
  23444. +#include <linux/uio.h>
  23445. +
  23446. +/*
  23447. + * The linux uio.h doesn't have all we need. To be fully api compatible
  23448. + * with the BSD cryptodev, we need to keep this around. Perhaps this can
  23449. + * be moved back into the linux/uio.h
  23450. + *
  23451. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  23452. + * Copyright (C) 2006-2007 David McCullough
  23453. + * Copyright (C) 2004-2005 Intel Corporation.
  23454. + *
  23455. + * LICENSE TERMS
  23456. + *
  23457. + * The free distribution and use of this software in both source and binary
  23458. + * form is allowed (with or without changes) provided that:
  23459. + *
  23460. + * 1. distributions of this source code include the above copyright
  23461. + * notice, this list of conditions and the following disclaimer;
  23462. + *
  23463. + * 2. distributions in binary form include the above copyright
  23464. + * notice, this list of conditions and the following disclaimer
  23465. + * in the documentation and/or other associated materials;
  23466. + *
  23467. + * 3. the copyright holder's name is not used to endorse products
  23468. + * built using this software without specific written permission.
  23469. + *
  23470. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  23471. + * may be distributed under the terms of the GNU General Public License (GPL),
  23472. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  23473. + *
  23474. + * DISCLAIMER
  23475. + *
  23476. + * This software is provided 'as is' with no explicit or implied warranties
  23477. + * in respect of its properties, including, but not limited to, correctness
  23478. + * and/or fitness for purpose.
  23479. + * ---------------------------------------------------------------------------
  23480. + */
  23481. +
  23482. +struct uio {
  23483. + struct iovec *uio_iov;
  23484. + int uio_iovcnt;
  23485. + off_t uio_offset;
  23486. + int uio_resid;
  23487. +#if 0
  23488. + enum uio_seg uio_segflg;
  23489. + enum uio_rw uio_rw;
  23490. + struct thread *uio_td;
  23491. +#endif
  23492. +};
  23493. +
  23494. +#endif
  23495. diff -Nur linux-2.6.27.10.orig/drivers/char/random.c linux-2.6.27.10/drivers/char/random.c
  23496. --- linux-2.6.27.10.orig/drivers/char/random.c 2008-12-18 18:13:59.000000000 +0100
  23497. +++ linux-2.6.27.10/drivers/char/random.c 2008-12-23 19:31:44.000000000 +0100
  23498. @@ -129,6 +129,9 @@
  23499. * unsigned int value);
  23500. * void add_interrupt_randomness(int irq);
  23501. *
  23502. + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  23503. + * int random_input_wait(void);
  23504. + *
  23505. * add_input_randomness() uses the input layer interrupt timing, as well as
  23506. * the event type information from the hardware.
  23507. *
  23508. @@ -140,6 +143,13 @@
  23509. * a better measure, since the timing of the disk interrupts are more
  23510. * unpredictable.
  23511. *
  23512. + * random_input_words() just provides a raw block of entropy to the input
  23513. + * pool, such as from a hardware entropy generator.
  23514. + *
  23515. + * random_input_wait() suspends the caller until such time as the
  23516. + * entropy pool falls below the write threshold, and returns a count of how
  23517. + * much entropy (in bits) is needed to sustain the pool.
  23518. + *
  23519. * All of these routines try to estimate how many bits of randomness a
  23520. * particular randomness source. They do this by keeping track of the
  23521. * first and second order deltas of the event timings.
  23522. @@ -668,6 +678,61 @@
  23523. }
  23524. #endif
  23525. +/*
  23526. + * random_input_words - add bulk entropy to pool
  23527. + *
  23528. + * @buf: buffer to add
  23529. + * @wordcount: number of __u32 words to add
  23530. + * @ent_count: total amount of entropy (in bits) to credit
  23531. + *
  23532. + * this provides bulk input of entropy to the input pool
  23533. + *
  23534. + */
  23535. +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  23536. +{
  23537. + mix_pool_bytes(&input_pool, buf, wordcount*4);
  23538. +
  23539. + credit_entropy_bits(&input_pool, ent_count);
  23540. +
  23541. + DEBUG_ENT("crediting %d bits => %d\n",
  23542. + ent_count, input_pool.entropy_count);
  23543. + /*
  23544. + * Wake up waiting processes if we have enough
  23545. + * entropy.
  23546. + */
  23547. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  23548. + wake_up_interruptible(&random_read_wait);
  23549. +}
  23550. +EXPORT_SYMBOL(random_input_words);
  23551. +
  23552. +/*
  23553. + * random_input_wait - wait until random needs entropy
  23554. + *
  23555. + * this function sleeps until the /dev/random subsystem actually
  23556. + * needs more entropy, and then return the amount of entropy
  23557. + * that it would be nice to have added to the system.
  23558. + */
  23559. +int random_input_wait(void)
  23560. +{
  23561. + int count;
  23562. +
  23563. + wait_event_interruptible(random_write_wait,
  23564. + input_pool.entropy_count < random_write_wakeup_thresh);
  23565. +
  23566. + count = random_write_wakeup_thresh - input_pool.entropy_count;
  23567. +
  23568. + /* likely we got woken up due to a signal */
  23569. + if (count <= 0) count = random_read_wakeup_thresh;
  23570. +
  23571. + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
  23572. + count,
  23573. + input_pool.entropy_count, random_write_wakeup_thresh);
  23574. +
  23575. + return count;
  23576. +}
  23577. +EXPORT_SYMBOL(random_input_wait);
  23578. +
  23579. +
  23580. #define EXTRACT_SIZE 10
  23581. /*********************************************************************
  23582. diff -Nur linux-2.6.27.10.orig/fs/fcntl.c linux-2.6.27.10/fs/fcntl.c
  23583. --- linux-2.6.27.10.orig/fs/fcntl.c 2008-12-18 18:13:59.000000000 +0100
  23584. +++ linux-2.6.27.10/fs/fcntl.c 2008-12-23 19:31:44.000000000 +0100
  23585. @@ -140,6 +140,7 @@
  23586. }
  23587. return ret;
  23588. }
  23589. +EXPORT_SYMBOL(sys_dup);
  23590. #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME)
  23591. diff -Nur linux-2.6.27.10.orig/include/linux/miscdevice.h linux-2.6.27.10/include/linux/miscdevice.h
  23592. --- linux-2.6.27.10.orig/include/linux/miscdevice.h 2008-12-18 18:13:59.000000000 +0100
  23593. +++ linux-2.6.27.10/include/linux/miscdevice.h 2008-12-23 19:31:46.000000000 +0100
  23594. @@ -12,6 +12,7 @@
  23595. #define APOLLO_MOUSE_MINOR 7
  23596. #define PC110PAD_MINOR 9
  23597. /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
  23598. +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
  23599. #define WATCHDOG_MINOR 130 /* Watchdog timer */
  23600. #define TEMP_MINOR 131 /* Temperature Sensor */
  23601. #define RTC_MINOR 135
  23602. diff -Nur linux-2.6.27.10.orig/include/linux/random.h linux-2.6.27.10/include/linux/random.h
  23603. --- linux-2.6.27.10.orig/include/linux/random.h 2008-12-18 18:13:59.000000000 +0100
  23604. +++ linux-2.6.27.10/include/linux/random.h 2008-12-23 19:31:46.000000000 +0100
  23605. @@ -8,6 +8,7 @@
  23606. #define _LINUX_RANDOM_H
  23607. #include <linux/ioctl.h>
  23608. +#include <linux/types.h> /* for __u32 in user space */
  23609. /* ioctl()'s for the random number generator */
  23610. @@ -32,6 +33,30 @@
  23611. /* Clear the entropy pool and associated counters. (Superuser only.) */
  23612. #define RNDCLEARPOOL _IO( 'R', 0x06 )
  23613. +#ifdef CONFIG_FIPS_RNG
  23614. +
  23615. +/* Size of seed value - equal to AES blocksize */
  23616. +#define AES_BLOCK_SIZE_BYTES 16
  23617. +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
  23618. +/* Size of AES key */
  23619. +#define KEY_SIZE_BYTES 16
  23620. +
  23621. +/* ioctl() structure used by FIPS 140-2 Tests */
  23622. +struct rand_fips_test {
  23623. + unsigned char key[KEY_SIZE_BYTES]; /* Input */
  23624. + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
  23625. + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
  23626. + unsigned char result[SEED_SIZE_BYTES]; /* Output */
  23627. +};
  23628. +
  23629. +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
  23630. +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
  23631. +
  23632. +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
  23633. +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
  23634. +
  23635. +#endif /* #ifdef CONFIG_FIPS_RNG */
  23636. +
  23637. struct rand_pool_info {
  23638. int entropy_count;
  23639. int buf_size;
  23640. @@ -48,6 +73,10 @@
  23641. unsigned int value);
  23642. extern void add_interrupt_randomness(int irq);
  23643. +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
  23644. +extern int random_input_wait(void);
  23645. +#define HAS_RANDOM_INPUT_WAIT 1
  23646. +
  23647. extern void get_random_bytes(void *buf, int nbytes);
  23648. void generate_random_uuid(unsigned char uuid_out[16]);