libsodium.c 120 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Frank Denis <jedisct1@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. # include "config.h"
  20. #endif
  21. #include "php.h"
  22. #include "php_ini.h"
  23. #include "ext/standard/info.h"
  24. #include "php_libsodium.h"
  25. #include "zend_exceptions.h"
  26. #include <sodium.h>
  27. #include <stdint.h>
  28. #include <string.h>
  29. #define PHP_SODIUM_ZSTR_TRUNCATE(zs, len) do { ZSTR_LEN(zs) = (len); } while(0)
  30. static zend_class_entry *sodium_exception_ce;
  31. ZEND_BEGIN_ARG_INFO_EX(AI_None, 0, 0, 0)
  32. ZEND_END_ARG_INFO()
  33. ZEND_BEGIN_ARG_INFO_EX(AI_FirstArgByReference, 0, 0, 1)
  34. ZEND_ARG_INFO(1, reference)
  35. ZEND_END_ARG_INFO()
  36. ZEND_BEGIN_ARG_INFO_EX(AI_String, 0, 0, 1)
  37. ZEND_ARG_INFO(0, string)
  38. ZEND_END_ARG_INFO()
  39. ZEND_BEGIN_ARG_INFO_EX(AI_StringRef, 0, 0, 1)
  40. ZEND_ARG_INFO(1, string)
  41. ZEND_END_ARG_INFO()
  42. ZEND_BEGIN_ARG_INFO_EX(AI_TwoStrings, 0, 0, 2)
  43. ZEND_ARG_INFO(0, string_1)
  44. ZEND_ARG_INFO(0, string_2)
  45. ZEND_END_ARG_INFO()
  46. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndMaybeString, 0, 0, 1)
  47. ZEND_ARG_INFO(0, string_1)
  48. /* optional */
  49. ZEND_ARG_INFO(0, string_2)
  50. ZEND_END_ARG_INFO()
  51. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndIdAndMaybeString, 0, 0, 2)
  52. ZEND_ARG_INFO(0, string_1)
  53. ZEND_ARG_INFO(0, id)
  54. /* optional */
  55. ZEND_ARG_INFO(0, string_2)
  56. ZEND_END_ARG_INFO()
  57. ZEND_BEGIN_ARG_INFO_EX(AI_StringRefAndString, 0, 0, 2)
  58. ZEND_ARG_INFO(1, string_1)
  59. ZEND_ARG_INFO(0, string_2)
  60. ZEND_END_ARG_INFO()
  61. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndKey, 0, 0, 2)
  62. ZEND_ARG_INFO(0, string)
  63. ZEND_ARG_INFO(0, key)
  64. ZEND_END_ARG_INFO()
  65. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndLength, 0, 0, 2)
  66. ZEND_ARG_INFO(0, string)
  67. ZEND_ARG_INFO(0, length)
  68. ZEND_END_ARG_INFO()
  69. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndId, 0, 0, 2)
  70. ZEND_ARG_INFO(0, string)
  71. ZEND_ARG_INFO(0, id)
  72. ZEND_END_ARG_INFO()
  73. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndKeyPair, 0, 0, 2)
  74. ZEND_ARG_INFO(0, string)
  75. ZEND_ARG_INFO(0, keypair)
  76. ZEND_END_ARG_INFO()
  77. ZEND_BEGIN_ARG_INFO_EX(AI_SignatureAndStringAndKey, 0, 0, 3)
  78. ZEND_ARG_INFO(0, signature)
  79. ZEND_ARG_INFO(0, string)
  80. ZEND_ARG_INFO(0, key)
  81. ZEND_END_ARG_INFO()
  82. ZEND_BEGIN_ARG_INFO_EX(AI_Key, 0, 0, 1)
  83. ZEND_ARG_INFO(0, key)
  84. ZEND_END_ARG_INFO()
  85. ZEND_BEGIN_ARG_INFO_EX(AI_SecretKeyAndPublicKey, 0, 0, 2)
  86. ZEND_ARG_INFO(0, secret_key)
  87. ZEND_ARG_INFO(0, public_key)
  88. ZEND_END_ARG_INFO()
  89. ZEND_BEGIN_ARG_INFO_EX(AI_LengthAndNonceAndKey, 0, 0, 3)
  90. ZEND_ARG_INFO(0, length)
  91. ZEND_ARG_INFO(0, nonce)
  92. ZEND_ARG_INFO(0, key)
  93. ZEND_END_ARG_INFO()
  94. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndNonceAndKey, 0, 0, 3)
  95. ZEND_ARG_INFO(0, string)
  96. ZEND_ARG_INFO(0, nonce)
  97. ZEND_ARG_INFO(0, key)
  98. ZEND_END_ARG_INFO()
  99. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndNonceAndKeyPair, 0, 0, 3)
  100. ZEND_ARG_INFO(0, string)
  101. ZEND_ARG_INFO(0, nonce)
  102. ZEND_ARG_INFO(0, key)
  103. ZEND_END_ARG_INFO()
  104. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndMaybeKeyAndLength, 0, 0, 1)
  105. ZEND_ARG_INFO(0, string)
  106. /* optional */
  107. ZEND_ARG_INFO(0, key)
  108. ZEND_ARG_INFO(0, length)
  109. ZEND_END_ARG_INFO()
  110. ZEND_BEGIN_ARG_INFO_EX(AI_LengthAndPasswordAndSaltAndOpsLimitAndMemLimit, 0, 0, 5)
  111. ZEND_ARG_INFO(0, length)
  112. ZEND_ARG_INFO(0, password)
  113. ZEND_ARG_INFO(0, salt)
  114. ZEND_ARG_INFO(0, opslimit)
  115. ZEND_ARG_INFO(0, memlimit)
  116. /* optional */
  117. ZEND_ARG_INFO(0, alg)
  118. ZEND_END_ARG_INFO()
  119. ZEND_BEGIN_ARG_INFO_EX(AI_PasswordAndOpsLimitAndMemLimit, 0, 0, 3)
  120. ZEND_ARG_INFO(0, password)
  121. ZEND_ARG_INFO(0, opslimit)
  122. ZEND_ARG_INFO(0, memlimit)
  123. ZEND_END_ARG_INFO()
  124. ZEND_BEGIN_ARG_INFO_EX(AI_HashAndPassword, 0, 0, 2)
  125. ZEND_ARG_INFO(0, hash)
  126. ZEND_ARG_INFO(0, password)
  127. ZEND_END_ARG_INFO()
  128. ZEND_BEGIN_ARG_INFO_EX(AI_StringAndADAndNonceAndKey, 0, 0, 4)
  129. ZEND_ARG_INFO(0, string)
  130. ZEND_ARG_INFO(0, ad)
  131. ZEND_ARG_INFO(0, nonce)
  132. ZEND_ARG_INFO(0, key)
  133. ZEND_END_ARG_INFO()
  134. ZEND_BEGIN_ARG_INFO_EX(AI_StateByReference, 0, 0, 1)
  135. ZEND_ARG_INFO(1, state)
  136. ZEND_END_ARG_INFO()
  137. ZEND_BEGIN_ARG_INFO_EX(AI_StateByReferenceAndStringAndMaybeStringAndLong, 0, 0, 2)
  138. ZEND_ARG_INFO(1, state)
  139. ZEND_ARG_INFO(0, string)
  140. /* optional */
  141. ZEND_ARG_INFO(0, string)
  142. ZEND_ARG_INFO(0, long)
  143. ZEND_END_ARG_INFO()
  144. ZEND_BEGIN_ARG_INFO_EX(AI_StateByReferenceAndStringAndMaybeString, 0, 0, 2)
  145. ZEND_ARG_INFO(1, state)
  146. ZEND_ARG_INFO(0, string)
  147. /* optional */
  148. ZEND_ARG_INFO(0, string)
  149. ZEND_END_ARG_INFO()
  150. ZEND_BEGIN_ARG_INFO_EX(AI_StateByReferenceAndMaybeLength, 0, 0, 1)
  151. ZEND_ARG_INFO(1, state)
  152. /* optional */
  153. ZEND_ARG_INFO(0, length)
  154. ZEND_END_ARG_INFO()
  155. ZEND_BEGIN_ARG_INFO_EX(AI_StateByReferenceAndString, 0, 0, 2)
  156. ZEND_ARG_INFO(1, state)
  157. ZEND_ARG_INFO(0, string)
  158. ZEND_END_ARG_INFO()
  159. ZEND_BEGIN_ARG_INFO_EX(AI_MaybeKeyAndLength, 0, 0, 0)
  160. /* optional */
  161. ZEND_ARG_INFO(0, key)
  162. ZEND_ARG_INFO(0, length)
  163. ZEND_END_ARG_INFO()
  164. ZEND_BEGIN_ARG_INFO_EX(AI_KXClientSession, 0, 0, 2)
  165. ZEND_ARG_INFO(0, client_keypair)
  166. ZEND_ARG_INFO(0, server_key)
  167. ZEND_END_ARG_INFO()
  168. ZEND_BEGIN_ARG_INFO_EX(AI_KXServerSession, 0, 0, 2)
  169. ZEND_ARG_INFO(0, server_keypair)
  170. ZEND_ARG_INFO(0, client_key)
  171. ZEND_END_ARG_INFO()
  172. ZEND_BEGIN_ARG_INFO_EX(AI_KDF, 0, 0, 4)
  173. ZEND_ARG_INFO(0, subkey_len)
  174. ZEND_ARG_INFO(0, subkey_id)
  175. ZEND_ARG_INFO(0, context)
  176. ZEND_ARG_INFO(0, key)
  177. ZEND_END_ARG_INFO()
  178. #if (defined(__amd64) || defined(__amd64__) || defined(__x86_64__) || defined(__i386__) || \
  179. defined(_M_AMD64) || defined(_M_IX86))
  180. # define HAVE_AESGCM 1
  181. #endif
  182. #ifndef crypto_aead_chacha20poly1305_IETF_KEYBYTES
  183. # define crypto_aead_chacha20poly1305_IETF_KEYBYTES crypto_aead_chacha20poly1305_KEYBYTES
  184. #endif
  185. #ifndef crypto_aead_chacha20poly1305_IETF_NSECBYTES
  186. # define crypto_aead_chacha20poly1305_IETF_NSECBYTES crypto_aead_chacha20poly1305_NSECBYTES
  187. #endif
  188. #ifndef crypto_aead_chacha20poly1305_IETF_ABYTES
  189. # define crypto_aead_chacha20poly1305_IETF_ABYTES crypto_aead_chacha20poly1305_ABYTES
  190. #endif
  191. #if defined(crypto_secretstream_xchacha20poly1305_ABYTES) && SODIUM_LIBRARY_VERSION_MAJOR < 10
  192. # undef crypto_secretstream_xchacha20poly1305_ABYTES
  193. #endif
  194. #ifndef crypto_pwhash_OPSLIMIT_MIN
  195. # define crypto_pwhash_OPSLIMIT_MIN crypto_pwhash_OPSLIMIT_INTERACTIVE
  196. #endif
  197. #ifndef crypto_pwhash_MEMLIMIT_MIN
  198. # define crypto_pwhash_MEMLIMIT_MIN crypto_pwhash_MEMLIMIT_INTERACTIVE
  199. #endif
  200. #ifndef crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN
  201. # define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE
  202. #endif
  203. #ifndef crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN
  204. # define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE
  205. #endif
  206. static const zend_function_entry sodium_functions[] = {
  207. PHP_FE(sodium_crypto_aead_aes256gcm_is_available, AI_None)
  208. #ifdef HAVE_AESGCM
  209. PHP_FE(sodium_crypto_aead_aes256gcm_decrypt, AI_StringAndADAndNonceAndKey)
  210. PHP_FE(sodium_crypto_aead_aes256gcm_encrypt, AI_StringAndADAndNonceAndKey)
  211. PHP_FE(sodium_crypto_aead_aes256gcm_keygen, AI_None)
  212. #endif
  213. PHP_FE(sodium_crypto_aead_chacha20poly1305_decrypt, AI_StringAndADAndNonceAndKey)
  214. PHP_FE(sodium_crypto_aead_chacha20poly1305_encrypt, AI_StringAndADAndNonceAndKey)
  215. PHP_FE(sodium_crypto_aead_chacha20poly1305_keygen, AI_None)
  216. PHP_FE(sodium_crypto_aead_chacha20poly1305_ietf_decrypt, AI_StringAndADAndNonceAndKey)
  217. PHP_FE(sodium_crypto_aead_chacha20poly1305_ietf_encrypt, AI_StringAndADAndNonceAndKey)
  218. PHP_FE(sodium_crypto_aead_chacha20poly1305_ietf_keygen, AI_None)
  219. #ifdef crypto_aead_xchacha20poly1305_IETF_NPUBBYTES
  220. PHP_FE(sodium_crypto_aead_xchacha20poly1305_ietf_decrypt, AI_StringAndADAndNonceAndKey)
  221. PHP_FE(sodium_crypto_aead_xchacha20poly1305_ietf_keygen, AI_None)
  222. PHP_FE(sodium_crypto_aead_xchacha20poly1305_ietf_encrypt, AI_StringAndADAndNonceAndKey)
  223. #endif
  224. PHP_FE(sodium_crypto_auth, AI_StringAndKey)
  225. PHP_FE(sodium_crypto_auth_keygen, AI_None)
  226. PHP_FE(sodium_crypto_auth_verify, AI_SignatureAndStringAndKey)
  227. PHP_FE(sodium_crypto_box, AI_StringAndNonceAndKeyPair)
  228. PHP_FE(sodium_crypto_box_keypair, AI_None)
  229. PHP_FE(sodium_crypto_box_seed_keypair, AI_Key)
  230. PHP_FE(sodium_crypto_box_keypair_from_secretkey_and_publickey, AI_SecretKeyAndPublicKey)
  231. PHP_FE(sodium_crypto_box_open, AI_StringAndNonceAndKey)
  232. PHP_FE(sodium_crypto_box_publickey, AI_Key)
  233. PHP_FE(sodium_crypto_box_publickey_from_secretkey, AI_Key)
  234. PHP_FE(sodium_crypto_box_seal, AI_StringAndKey)
  235. PHP_FE(sodium_crypto_box_seal_open, AI_StringAndKey)
  236. PHP_FE(sodium_crypto_box_secretkey, AI_Key)
  237. PHP_FE(sodium_crypto_kx_keypair, AI_None)
  238. PHP_FE(sodium_crypto_kx_publickey, AI_Key)
  239. PHP_FE(sodium_crypto_kx_secretkey, AI_Key)
  240. PHP_FE(sodium_crypto_kx_seed_keypair, AI_String)
  241. PHP_FE(sodium_crypto_kx_client_session_keys, AI_KXClientSession)
  242. PHP_FE(sodium_crypto_kx_server_session_keys, AI_KXServerSession)
  243. PHP_FE(sodium_crypto_generichash, AI_StringAndMaybeKeyAndLength)
  244. PHP_FE(sodium_crypto_generichash_keygen, AI_None)
  245. PHP_FE(sodium_crypto_generichash_init, AI_MaybeKeyAndLength)
  246. PHP_FE(sodium_crypto_generichash_update, AI_StateByReferenceAndString)
  247. PHP_FE(sodium_crypto_generichash_final, AI_StateByReferenceAndMaybeLength)
  248. PHP_FE(sodium_crypto_kdf_derive_from_key, AI_KDF)
  249. PHP_FE(sodium_crypto_kdf_keygen, AI_None)
  250. #ifdef crypto_pwhash_SALTBYTES
  251. PHP_FE(sodium_crypto_pwhash, AI_LengthAndPasswordAndSaltAndOpsLimitAndMemLimit)
  252. PHP_FE(sodium_crypto_pwhash_str, AI_PasswordAndOpsLimitAndMemLimit)
  253. PHP_FE(sodium_crypto_pwhash_str_verify, AI_HashAndPassword)
  254. #endif
  255. #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6)
  256. PHP_FE(sodium_crypto_pwhash_str_needs_rehash, AI_PasswordAndOpsLimitAndMemLimit)
  257. #endif
  258. #ifdef crypto_pwhash_scryptsalsa208sha256_SALTBYTES
  259. PHP_FE(sodium_crypto_pwhash_scryptsalsa208sha256, AI_LengthAndPasswordAndSaltAndOpsLimitAndMemLimit)
  260. PHP_FE(sodium_crypto_pwhash_scryptsalsa208sha256_str, AI_PasswordAndOpsLimitAndMemLimit)
  261. PHP_FE(sodium_crypto_pwhash_scryptsalsa208sha256_str_verify, AI_HashAndPassword)
  262. #endif
  263. PHP_FE(sodium_crypto_scalarmult, AI_TwoStrings)
  264. PHP_FE(sodium_crypto_secretbox, AI_StringAndNonceAndKey)
  265. PHP_FE(sodium_crypto_secretbox_keygen, AI_None)
  266. PHP_FE(sodium_crypto_secretbox_open, AI_StringAndNonceAndKey)
  267. #ifdef crypto_secretstream_xchacha20poly1305_ABYTES
  268. PHP_FE(sodium_crypto_secretstream_xchacha20poly1305_keygen, AI_None)
  269. PHP_FE(sodium_crypto_secretstream_xchacha20poly1305_init_push, AI_Key)
  270. PHP_FE(sodium_crypto_secretstream_xchacha20poly1305_push, AI_StateByReferenceAndStringAndMaybeStringAndLong)
  271. PHP_FE(sodium_crypto_secretstream_xchacha20poly1305_init_pull, AI_StringAndKey)
  272. PHP_FE(sodium_crypto_secretstream_xchacha20poly1305_pull, AI_StateByReferenceAndStringAndMaybeString)
  273. PHP_FE(sodium_crypto_secretstream_xchacha20poly1305_rekey, AI_StateByReference)
  274. #endif
  275. PHP_FE(sodium_crypto_shorthash, AI_StringAndKey)
  276. PHP_FE(sodium_crypto_shorthash_keygen, AI_None)
  277. PHP_FE(sodium_crypto_sign, AI_StringAndKeyPair)
  278. PHP_FE(sodium_crypto_sign_detached, AI_StringAndKeyPair)
  279. PHP_FE(sodium_crypto_sign_ed25519_pk_to_curve25519, AI_Key)
  280. PHP_FE(sodium_crypto_sign_ed25519_sk_to_curve25519, AI_Key)
  281. PHP_FE(sodium_crypto_sign_keypair, AI_None)
  282. PHP_FE(sodium_crypto_sign_keypair_from_secretkey_and_publickey, AI_SecretKeyAndPublicKey)
  283. PHP_FE(sodium_crypto_sign_open, AI_StringAndKeyPair)
  284. PHP_FE(sodium_crypto_sign_publickey, AI_Key)
  285. PHP_FE(sodium_crypto_sign_secretkey, AI_Key)
  286. PHP_FE(sodium_crypto_sign_publickey_from_secretkey, AI_Key)
  287. PHP_FE(sodium_crypto_sign_seed_keypair, AI_Key)
  288. PHP_FE(sodium_crypto_sign_verify_detached, AI_SignatureAndStringAndKey)
  289. PHP_FE(sodium_crypto_stream, AI_LengthAndNonceAndKey)
  290. PHP_FE(sodium_crypto_stream_keygen, AI_None)
  291. PHP_FE(sodium_crypto_stream_xor, AI_StringAndNonceAndKey)
  292. /* helpers */
  293. PHP_FE(sodium_add, AI_StringRefAndString)
  294. PHP_FE(sodium_compare, AI_TwoStrings)
  295. PHP_FE(sodium_increment, AI_StringRef)
  296. PHP_FE(sodium_memcmp, AI_TwoStrings)
  297. PHP_FE(sodium_memzero, AI_FirstArgByReference)
  298. PHP_FE(sodium_pad, AI_StringAndLength)
  299. PHP_FE(sodium_unpad, AI_StringAndLength)
  300. /* codecs */
  301. PHP_FE(sodium_bin2hex, AI_String)
  302. PHP_FE(sodium_hex2bin, AI_StringAndMaybeString)
  303. #ifdef sodium_base64_VARIANT_ORIGINAL
  304. PHP_FE(sodium_bin2base64, AI_StringAndId)
  305. PHP_FE(sodium_base642bin, AI_StringAndIdAndMaybeString)
  306. #endif
  307. /* aliases */
  308. PHP_FALIAS(sodium_crypto_scalarmult_base, sodium_crypto_box_publickey_from_secretkey, AI_TwoStrings)
  309. PHP_FE_END
  310. };
  311. zend_module_entry sodium_module_entry = {
  312. STANDARD_MODULE_HEADER,
  313. "sodium",
  314. sodium_functions,
  315. PHP_MINIT(sodium),
  316. PHP_MSHUTDOWN(sodium),
  317. NULL,
  318. NULL,
  319. PHP_MINFO(sodium),
  320. PHP_SODIUM_VERSION,
  321. STANDARD_MODULE_PROPERTIES
  322. };
  323. /* }}} */
  324. #ifdef COMPILE_DL_SODIUM
  325. ZEND_GET_MODULE(sodium)
  326. #endif
  327. /* Remove argument information from backtrace to prevent information leaks */
  328. static void sodium_remove_param_values_from_backtrace(zend_object *obj) {
  329. zval obj_zv, rv, *trace;
  330. ZVAL_OBJ(&obj_zv, obj);
  331. trace = zend_read_property(zend_get_exception_base(&obj_zv), &obj_zv, "trace", sizeof("trace")-1, 0, &rv);
  332. if (trace && Z_TYPE_P(trace) == IS_ARRAY) {
  333. zval *frame;
  334. ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(trace), frame) {
  335. if (Z_TYPE_P(frame) == IS_ARRAY) {
  336. zval *args = zend_hash_str_find(Z_ARRVAL_P(frame), "args", sizeof("args")-1);
  337. if (args) {
  338. zval_ptr_dtor(args);
  339. ZVAL_EMPTY_ARRAY(args);
  340. }
  341. }
  342. } ZEND_HASH_FOREACH_END();
  343. }
  344. }
  345. static zend_object *sodium_exception_create_object(zend_class_entry *ce) {
  346. zend_object *obj = zend_ce_exception->create_object(ce);
  347. sodium_remove_param_values_from_backtrace(obj);
  348. return obj;
  349. }
  350. static void sodium_separate_string(zval *zv) {
  351. ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
  352. if (!Z_REFCOUNTED_P(zv) || Z_REFCOUNT_P(zv) > 1) {
  353. zend_string *copy = zend_string_init(Z_STRVAL_P(zv), Z_STRLEN_P(zv), 0);
  354. Z_TRY_DELREF_P(zv);
  355. ZVAL_STR(zv, copy);
  356. }
  357. }
  358. PHP_MINIT_FUNCTION(sodium)
  359. {
  360. zend_class_entry ce;
  361. if (sodium_init() < 0) {
  362. zend_error(E_ERROR, "sodium_init()");
  363. }
  364. INIT_CLASS_ENTRY(ce, "SodiumException", NULL);
  365. sodium_exception_ce = zend_register_internal_class_ex(&ce, zend_ce_exception);
  366. sodium_exception_ce->create_object = sodium_exception_create_object;
  367. REGISTER_STRING_CONSTANT("SODIUM_LIBRARY_VERSION",
  368. (char *) (void *) sodium_version_string(), CONST_CS | CONST_PERSISTENT);
  369. REGISTER_LONG_CONSTANT("SODIUM_LIBRARY_MAJOR_VERSION",
  370. sodium_library_version_major(), CONST_CS | CONST_PERSISTENT);
  371. REGISTER_LONG_CONSTANT("SODIUM_LIBRARY_MINOR_VERSION",
  372. sodium_library_version_minor(), CONST_CS | CONST_PERSISTENT);
  373. #ifdef HAVE_AESGCM
  374. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES",
  375. crypto_aead_aes256gcm_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  376. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES",
  377. crypto_aead_aes256gcm_NSECBYTES, CONST_CS | CONST_PERSISTENT);
  378. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES",
  379. crypto_aead_aes256gcm_NPUBBYTES, CONST_CS | CONST_PERSISTENT);
  380. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES",
  381. crypto_aead_aes256gcm_ABYTES, CONST_CS | CONST_PERSISTENT);
  382. #endif
  383. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES",
  384. crypto_aead_chacha20poly1305_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  385. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES",
  386. crypto_aead_chacha20poly1305_NSECBYTES, CONST_CS | CONST_PERSISTENT);
  387. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES",
  388. crypto_aead_chacha20poly1305_NPUBBYTES, CONST_CS | CONST_PERSISTENT);
  389. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES",
  390. crypto_aead_chacha20poly1305_ABYTES, CONST_CS | CONST_PERSISTENT);
  391. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES",
  392. crypto_aead_chacha20poly1305_IETF_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  393. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES",
  394. crypto_aead_chacha20poly1305_IETF_NSECBYTES, CONST_CS | CONST_PERSISTENT);
  395. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES",
  396. crypto_aead_chacha20poly1305_IETF_NPUBBYTES, CONST_CS | CONST_PERSISTENT);
  397. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES",
  398. crypto_aead_chacha20poly1305_IETF_ABYTES, CONST_CS | CONST_PERSISTENT);
  399. #ifdef crypto_aead_xchacha20poly1305_IETF_NPUBBYTES
  400. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES",
  401. crypto_aead_xchacha20poly1305_IETF_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  402. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES",
  403. crypto_aead_xchacha20poly1305_IETF_NSECBYTES, CONST_CS | CONST_PERSISTENT);
  404. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES",
  405. crypto_aead_xchacha20poly1305_IETF_NPUBBYTES, CONST_CS | CONST_PERSISTENT);
  406. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES",
  407. crypto_aead_xchacha20poly1305_IETF_ABYTES, CONST_CS | CONST_PERSISTENT);
  408. #endif
  409. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AUTH_BYTES",
  410. crypto_auth_BYTES, CONST_CS | CONST_PERSISTENT);
  411. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_AUTH_KEYBYTES",
  412. crypto_auth_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  413. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_SEALBYTES",
  414. crypto_box_SEALBYTES, CONST_CS | CONST_PERSISTENT);
  415. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_SECRETKEYBYTES",
  416. crypto_box_SECRETKEYBYTES, CONST_CS | CONST_PERSISTENT);
  417. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_PUBLICKEYBYTES",
  418. crypto_box_PUBLICKEYBYTES, CONST_CS | CONST_PERSISTENT);
  419. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_KEYPAIRBYTES",
  420. crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES,
  421. CONST_CS | CONST_PERSISTENT);
  422. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_MACBYTES",
  423. crypto_box_MACBYTES, CONST_CS | CONST_PERSISTENT);
  424. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_NONCEBYTES",
  425. crypto_box_NONCEBYTES, CONST_CS | CONST_PERSISTENT);
  426. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_BOX_SEEDBYTES",
  427. crypto_box_SEEDBYTES, CONST_CS | CONST_PERSISTENT);
  428. #ifndef crypto_kdf_BYTES_MIN
  429. # define crypto_kdf_BYTES_MIN 16
  430. # define crypto_kdf_BYTES_MAX 64
  431. # define crypto_kdf_CONTEXTBYTES 8
  432. # define crypto_kdf_KEYBYTES 32
  433. #endif
  434. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KDF_BYTES_MIN",
  435. crypto_kdf_BYTES_MIN, CONST_CS | CONST_PERSISTENT);
  436. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KDF_BYTES_MAX",
  437. crypto_kdf_BYTES_MAX, CONST_CS | CONST_PERSISTENT);
  438. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KDF_CONTEXTBYTES",
  439. crypto_kdf_CONTEXTBYTES, CONST_CS | CONST_PERSISTENT);
  440. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KDF_KEYBYTES",
  441. crypto_kdf_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  442. #ifndef crypto_kx_SEEDBYTES
  443. # define crypto_kx_SEEDBYTES 32
  444. # define crypto_kx_SESSIONKEYBYTES 32
  445. # define crypto_kx_PUBLICKEYBYTES 32
  446. # define crypto_kx_SECRETKEYBYTES 32
  447. #endif
  448. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KX_SEEDBYTES",
  449. crypto_kx_SEEDBYTES, CONST_CS | CONST_PERSISTENT);
  450. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KX_SESSIONKEYBYTES",
  451. crypto_kx_SESSIONKEYBYTES, CONST_CS | CONST_PERSISTENT);
  452. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KX_PUBLICKEYBYTES",
  453. crypto_kx_PUBLICKEYBYTES, CONST_CS | CONST_PERSISTENT);
  454. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KX_SECRETKEYBYTES",
  455. crypto_kx_SECRETKEYBYTES, CONST_CS | CONST_PERSISTENT);
  456. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_KX_KEYPAIRBYTES",
  457. crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES,
  458. CONST_CS | CONST_PERSISTENT);
  459. #ifdef crypto_secretstream_xchacha20poly1305_ABYTES
  460. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES",
  461. crypto_secretstream_xchacha20poly1305_ABYTES,
  462. CONST_CS | CONST_PERSISTENT);
  463. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES",
  464. crypto_secretstream_xchacha20poly1305_HEADERBYTES,
  465. CONST_CS | CONST_PERSISTENT);
  466. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES",
  467. crypto_secretstream_xchacha20poly1305_KEYBYTES,
  468. CONST_CS | CONST_PERSISTENT);
  469. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX",
  470. crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX,
  471. CONST_CS | CONST_PERSISTENT);
  472. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE",
  473. crypto_secretstream_xchacha20poly1305_TAG_MESSAGE,
  474. CONST_CS | CONST_PERSISTENT);
  475. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH",
  476. crypto_secretstream_xchacha20poly1305_TAG_PUSH,
  477. CONST_CS | CONST_PERSISTENT);
  478. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY",
  479. crypto_secretstream_xchacha20poly1305_TAG_REKEY,
  480. CONST_CS | CONST_PERSISTENT);
  481. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL",
  482. crypto_secretstream_xchacha20poly1305_TAG_FINAL,
  483. CONST_CS | CONST_PERSISTENT);
  484. #endif
  485. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_GENERICHASH_BYTES",
  486. crypto_generichash_BYTES, CONST_CS | CONST_PERSISTENT);
  487. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_GENERICHASH_BYTES_MIN",
  488. crypto_generichash_BYTES_MIN, CONST_CS | CONST_PERSISTENT);
  489. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_GENERICHASH_BYTES_MAX",
  490. crypto_generichash_BYTES_MAX, CONST_CS | CONST_PERSISTENT);
  491. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_GENERICHASH_KEYBYTES",
  492. crypto_generichash_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  493. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN",
  494. crypto_generichash_KEYBYTES_MIN, CONST_CS | CONST_PERSISTENT);
  495. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX",
  496. crypto_generichash_KEYBYTES_MAX, CONST_CS | CONST_PERSISTENT);
  497. #ifdef crypto_pwhash_SALTBYTES
  498. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13",
  499. crypto_pwhash_ALG_ARGON2I13, CONST_CS | CONST_PERSISTENT);
  500. # ifdef crypto_pwhash_ALG_ARGON2ID13
  501. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13",
  502. crypto_pwhash_ALG_ARGON2ID13, CONST_CS | CONST_PERSISTENT);
  503. # endif
  504. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_ALG_DEFAULT",
  505. crypto_pwhash_ALG_DEFAULT, CONST_CS | CONST_PERSISTENT);
  506. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_SALTBYTES",
  507. crypto_pwhash_SALTBYTES, CONST_CS | CONST_PERSISTENT);
  508. REGISTER_STRING_CONSTANT("SODIUM_CRYPTO_PWHASH_STRPREFIX",
  509. crypto_pwhash_STRPREFIX, CONST_CS | CONST_PERSISTENT);
  510. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE",
  511. crypto_pwhash_opslimit_interactive(), CONST_CS | CONST_PERSISTENT);
  512. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE",
  513. crypto_pwhash_memlimit_interactive(), CONST_CS | CONST_PERSISTENT);
  514. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE",
  515. crypto_pwhash_opslimit_moderate(), CONST_CS | CONST_PERSISTENT);
  516. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE",
  517. crypto_pwhash_memlimit_moderate(), CONST_CS | CONST_PERSISTENT);
  518. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE",
  519. crypto_pwhash_opslimit_sensitive(), CONST_CS | CONST_PERSISTENT);
  520. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE",
  521. crypto_pwhash_memlimit_sensitive(), CONST_CS | CONST_PERSISTENT);
  522. #endif
  523. #ifdef crypto_pwhash_scryptsalsa208sha256_SALTBYTES
  524. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES",
  525. crypto_pwhash_scryptsalsa208sha256_SALTBYTES, CONST_CS | CONST_PERSISTENT);
  526. REGISTER_STRING_CONSTANT("SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX",
  527. crypto_pwhash_scryptsalsa208sha256_STRPREFIX, CONST_CS | CONST_PERSISTENT);
  528. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE",
  529. crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(), CONST_CS | CONST_PERSISTENT);
  530. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE",
  531. crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(), CONST_CS | CONST_PERSISTENT);
  532. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE",
  533. crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(), CONST_CS | CONST_PERSISTENT);
  534. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE",
  535. crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(), CONST_CS | CONST_PERSISTENT);
  536. #endif
  537. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SCALARMULT_BYTES",
  538. crypto_scalarmult_BYTES, CONST_CS | CONST_PERSISTENT);
  539. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SCALARMULT_SCALARBYTES",
  540. crypto_scalarmult_SCALARBYTES, CONST_CS | CONST_PERSISTENT);
  541. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SHORTHASH_BYTES",
  542. crypto_shorthash_BYTES, CONST_CS | CONST_PERSISTENT);
  543. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SHORTHASH_KEYBYTES",
  544. crypto_shorthash_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  545. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETBOX_KEYBYTES",
  546. crypto_secretbox_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  547. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETBOX_MACBYTES",
  548. crypto_secretbox_MACBYTES, CONST_CS | CONST_PERSISTENT);
  549. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SECRETBOX_NONCEBYTES",
  550. crypto_secretbox_NONCEBYTES, CONST_CS | CONST_PERSISTENT);
  551. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SIGN_BYTES",
  552. crypto_sign_BYTES, CONST_CS | CONST_PERSISTENT);
  553. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SIGN_SEEDBYTES",
  554. crypto_sign_SEEDBYTES, CONST_CS | CONST_PERSISTENT);
  555. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES",
  556. crypto_sign_PUBLICKEYBYTES, CONST_CS | CONST_PERSISTENT);
  557. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SIGN_SECRETKEYBYTES",
  558. crypto_sign_SECRETKEYBYTES, CONST_CS | CONST_PERSISTENT);
  559. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SIGN_KEYPAIRBYTES",
  560. crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES,
  561. CONST_CS | CONST_PERSISTENT);
  562. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_STREAM_NONCEBYTES",
  563. crypto_stream_NONCEBYTES, CONST_CS | CONST_PERSISTENT);
  564. REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_STREAM_KEYBYTES",
  565. crypto_stream_KEYBYTES, CONST_CS | CONST_PERSISTENT);
  566. #ifdef sodium_base64_VARIANT_ORIGINAL
  567. REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_ORIGINAL",
  568. sodium_base64_VARIANT_ORIGINAL, CONST_CS | CONST_PERSISTENT);
  569. REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING",
  570. sodium_base64_VARIANT_ORIGINAL_NO_PADDING, CONST_CS | CONST_PERSISTENT);
  571. REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_URLSAFE",
  572. sodium_base64_VARIANT_URLSAFE, CONST_CS | CONST_PERSISTENT);
  573. REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING",
  574. sodium_base64_VARIANT_URLSAFE_NO_PADDING, CONST_CS | CONST_PERSISTENT);
  575. #endif
  576. return SUCCESS;
  577. }
  578. PHP_MSHUTDOWN_FUNCTION(sodium)
  579. {
  580. randombytes_close();
  581. return SUCCESS;
  582. }
  583. PHP_MINFO_FUNCTION(sodium)
  584. {
  585. php_info_print_table_start();
  586. php_info_print_table_header(2, "sodium support", "enabled");
  587. php_info_print_table_row(2, "libsodium headers version", SODIUM_VERSION_STRING);
  588. php_info_print_table_row(2, "libsodium library version", sodium_version_string());
  589. php_info_print_table_end();
  590. }
  591. PHP_FUNCTION(sodium_memzero)
  592. {
  593. zval *buf_zv;
  594. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(),
  595. "z", &buf_zv) == FAILURE) {
  596. sodium_remove_param_values_from_backtrace(EG(exception));
  597. return;
  598. }
  599. ZVAL_DEREF(buf_zv);
  600. if (Z_TYPE_P(buf_zv) != IS_STRING) {
  601. zend_throw_exception(sodium_exception_ce, "a PHP string is required", 0);
  602. return;
  603. }
  604. if (Z_REFCOUNTED_P(buf_zv) && Z_REFCOUNT_P(buf_zv) == 1) {
  605. char *buf = Z_STRVAL(*buf_zv);
  606. size_t buf_len = Z_STRLEN(*buf_zv);
  607. if (buf_len > 0) {
  608. sodium_memzero(buf, (size_t) buf_len);
  609. }
  610. }
  611. convert_to_null(buf_zv);
  612. }
  613. PHP_FUNCTION(sodium_increment)
  614. {
  615. zval *val_zv;
  616. unsigned char *val;
  617. size_t val_len;
  618. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(),
  619. "z", &val_zv) == FAILURE) {
  620. sodium_remove_param_values_from_backtrace(EG(exception));
  621. return;
  622. }
  623. ZVAL_DEREF(val_zv);
  624. if (Z_TYPE_P(val_zv) != IS_STRING) {
  625. zend_throw_exception(sodium_exception_ce, "a PHP string is required", 0);
  626. return;
  627. }
  628. sodium_separate_string(val_zv);
  629. val = (unsigned char *) Z_STRVAL(*val_zv);
  630. val_len = Z_STRLEN(*val_zv);
  631. sodium_increment(val, val_len);
  632. }
  633. PHP_FUNCTION(sodium_add)
  634. {
  635. zval *val_zv;
  636. unsigned char *val;
  637. unsigned char *addv;
  638. size_t val_len;
  639. size_t addv_len;
  640. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(),
  641. "zs", &val_zv, &addv, &addv_len) == FAILURE) {
  642. sodium_remove_param_values_from_backtrace(EG(exception));
  643. return;
  644. }
  645. ZVAL_DEREF(val_zv);
  646. if (Z_TYPE_P(val_zv) != IS_STRING) {
  647. zend_throw_exception(sodium_exception_ce, "PHP strings are required", 0);
  648. return;
  649. }
  650. sodium_separate_string(val_zv);
  651. val = (unsigned char *) Z_STRVAL(*val_zv);
  652. val_len = Z_STRLEN(*val_zv);
  653. if (val_len != addv_len) {
  654. zend_throw_exception(sodium_exception_ce, "values must have the same length", 0);
  655. return;
  656. }
  657. sodium_add(val, addv, val_len);
  658. }
  659. PHP_FUNCTION(sodium_memcmp)
  660. {
  661. char *buf1;
  662. char *buf2;
  663. size_t len1;
  664. size_t len2;
  665. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  666. &buf1, &len1,
  667. &buf2, &len2) == FAILURE) {
  668. sodium_remove_param_values_from_backtrace(EG(exception));
  669. return;
  670. }
  671. if (len1 != len2) {
  672. zend_throw_exception(sodium_exception_ce, "arguments have different sizes", 0);
  673. return;
  674. }
  675. RETURN_LONG(sodium_memcmp(buf1, buf2, len1));
  676. }
  677. PHP_FUNCTION(sodium_crypto_shorthash)
  678. {
  679. zend_string *hash;
  680. unsigned char *key;
  681. unsigned char *msg;
  682. size_t key_len;
  683. size_t msg_len;
  684. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  685. &msg, &msg_len,
  686. &key, &key_len) == FAILURE) {
  687. sodium_remove_param_values_from_backtrace(EG(exception));
  688. return;
  689. }
  690. if (key_len != crypto_shorthash_KEYBYTES) {
  691. zend_throw_exception(sodium_exception_ce,
  692. "key size should be SODIUM_CRYPTO_SHORTHASH_KEYBYTES bytes",
  693. 0);
  694. return;
  695. }
  696. hash = zend_string_alloc(crypto_shorthash_BYTES, 0);
  697. if (crypto_shorthash((unsigned char *) ZSTR_VAL(hash), msg,
  698. (unsigned long long) msg_len, key) != 0) {
  699. zend_string_efree(hash);
  700. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  701. return;
  702. }
  703. ZSTR_VAL(hash)[crypto_shorthash_BYTES] = 0;
  704. RETURN_NEW_STR(hash);
  705. }
  706. PHP_FUNCTION(sodium_crypto_secretbox)
  707. {
  708. zend_string *ciphertext;
  709. unsigned char *key;
  710. unsigned char *msg;
  711. unsigned char *nonce;
  712. size_t key_len;
  713. size_t msg_len;
  714. size_t nonce_len;
  715. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  716. &msg, &msg_len,
  717. &nonce, &nonce_len,
  718. &key, &key_len) == FAILURE) {
  719. sodium_remove_param_values_from_backtrace(EG(exception));
  720. return;
  721. }
  722. if (nonce_len != crypto_secretbox_NONCEBYTES) {
  723. zend_throw_exception(sodium_exception_ce,
  724. "nonce size should be SODIUM_CRYPTO_SECRETBOX_NONCEBYTES bytes",
  725. 0);
  726. return;
  727. }
  728. if (key_len != crypto_secretbox_KEYBYTES) {
  729. zend_throw_exception(sodium_exception_ce,
  730. "key size should be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes",
  731. 0);
  732. return;
  733. }
  734. if (SIZE_MAX - msg_len <= crypto_secretbox_MACBYTES) {
  735. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  736. return;
  737. }
  738. ciphertext = zend_string_alloc((size_t) msg_len + crypto_secretbox_MACBYTES, 0);
  739. if (crypto_secretbox_easy((unsigned char *) ZSTR_VAL(ciphertext),
  740. msg, (unsigned long long) msg_len,
  741. nonce, key) != 0) {
  742. zend_string_efree(ciphertext);
  743. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  744. return;
  745. }
  746. ZSTR_VAL(ciphertext)[msg_len + crypto_secretbox_MACBYTES] = 0;
  747. RETURN_NEW_STR(ciphertext);
  748. }
  749. PHP_FUNCTION(sodium_crypto_secretbox_open)
  750. {
  751. zend_string *msg;
  752. unsigned char *key;
  753. unsigned char *ciphertext;
  754. unsigned char *nonce;
  755. size_t key_len;
  756. size_t ciphertext_len;
  757. size_t nonce_len;
  758. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  759. &ciphertext, &ciphertext_len,
  760. &nonce, &nonce_len,
  761. &key, &key_len) == FAILURE) {
  762. sodium_remove_param_values_from_backtrace(EG(exception));
  763. return;
  764. }
  765. if (nonce_len != crypto_secretbox_NONCEBYTES) {
  766. zend_throw_exception(sodium_exception_ce,
  767. "nonce size should be SODIUM_CRYPTO_SECRETBOX_NONCEBYTES bytes",
  768. 0);
  769. return;
  770. }
  771. if (key_len != crypto_secretbox_KEYBYTES) {
  772. zend_throw_exception(sodium_exception_ce,
  773. "key size should be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes",
  774. 0);
  775. return;
  776. }
  777. if (ciphertext_len < crypto_secretbox_MACBYTES) {
  778. RETURN_FALSE;
  779. }
  780. msg = zend_string_alloc
  781. ((size_t) ciphertext_len - crypto_secretbox_MACBYTES, 0);
  782. if (crypto_secretbox_open_easy((unsigned char *) ZSTR_VAL(msg), ciphertext,
  783. (unsigned long long) ciphertext_len,
  784. nonce, key) != 0) {
  785. zend_string_efree(msg);
  786. RETURN_FALSE;
  787. } else {
  788. ZSTR_VAL(msg)[ciphertext_len - crypto_secretbox_MACBYTES] = 0;
  789. RETURN_NEW_STR(msg);
  790. }
  791. }
  792. PHP_FUNCTION(sodium_crypto_generichash)
  793. {
  794. zend_string *hash;
  795. unsigned char *key = NULL;
  796. unsigned char *msg;
  797. zend_long hash_len = crypto_generichash_BYTES;
  798. size_t key_len = 0;
  799. size_t msg_len;
  800. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s|sl",
  801. &msg, &msg_len,
  802. &key, &key_len,
  803. &hash_len) == FAILURE) {
  804. sodium_remove_param_values_from_backtrace(EG(exception));
  805. return;
  806. }
  807. if (hash_len < crypto_generichash_BYTES_MIN ||
  808. hash_len > crypto_generichash_BYTES_MAX) {
  809. zend_throw_exception(sodium_exception_ce, "unsupported output length", 0);
  810. return;
  811. }
  812. if (key_len != 0 &&
  813. (key_len < crypto_generichash_KEYBYTES_MIN ||
  814. key_len > crypto_generichash_KEYBYTES_MAX)) {
  815. zend_throw_exception(sodium_exception_ce, "unsupported key length", 0);
  816. return;
  817. }
  818. hash = zend_string_alloc(hash_len, 0);
  819. if (crypto_generichash((unsigned char *) ZSTR_VAL(hash), (size_t) hash_len,
  820. msg, (unsigned long long) msg_len,
  821. key, (size_t) key_len) != 0) {
  822. zend_string_efree(hash);
  823. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  824. return;
  825. }
  826. ZSTR_VAL(hash)[hash_len] = 0;
  827. RETURN_NEW_STR(hash);
  828. }
  829. PHP_FUNCTION(sodium_crypto_generichash_init)
  830. {
  831. crypto_generichash_state state_tmp;
  832. zend_string *state;
  833. unsigned char *key = NULL;
  834. size_t state_len = sizeof (crypto_generichash_state);
  835. zend_long hash_len = crypto_generichash_BYTES;
  836. size_t key_len = 0;
  837. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|sl",
  838. &key, &key_len,
  839. &hash_len) == FAILURE) {
  840. sodium_remove_param_values_from_backtrace(EG(exception));
  841. return;
  842. }
  843. if (hash_len < crypto_generichash_BYTES_MIN ||
  844. hash_len > crypto_generichash_BYTES_MAX) {
  845. zend_throw_exception(sodium_exception_ce, "unsupported output length", 0);
  846. return;
  847. }
  848. if (key_len != 0 &&
  849. (key_len < crypto_generichash_KEYBYTES_MIN ||
  850. key_len > crypto_generichash_KEYBYTES_MAX)) {
  851. zend_throw_exception(sodium_exception_ce, "unsupported key length", 0);
  852. return;
  853. }
  854. memset(&state_tmp, 0, sizeof state_tmp);
  855. if (crypto_generichash_init((void *) &state_tmp, key, (size_t) key_len,
  856. (size_t) hash_len) != 0) {
  857. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  858. return;
  859. }
  860. state = zend_string_alloc(state_len, 0);
  861. memcpy(ZSTR_VAL(state), &state_tmp, state_len);
  862. sodium_memzero(&state_tmp, sizeof state_tmp);
  863. ZSTR_VAL(state)[state_len] = 0;
  864. RETURN_STR(state);
  865. }
  866. PHP_FUNCTION(sodium_crypto_generichash_update)
  867. {
  868. crypto_generichash_state state_tmp;
  869. zval *state_zv;
  870. unsigned char *msg;
  871. unsigned char *state;
  872. size_t msg_len;
  873. size_t state_len;
  874. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zs",
  875. &state_zv, &msg, &msg_len) == FAILURE) {
  876. sodium_remove_param_values_from_backtrace(EG(exception));
  877. return;
  878. }
  879. ZVAL_DEREF(state_zv);
  880. if (Z_TYPE_P(state_zv) != IS_STRING) {
  881. zend_throw_exception(sodium_exception_ce, "a reference to a state is required", 0);
  882. return;
  883. }
  884. sodium_separate_string(state_zv);
  885. state = (unsigned char *) Z_STRVAL(*state_zv);
  886. state_len = Z_STRLEN(*state_zv);
  887. if (state_len != sizeof (crypto_generichash_state)) {
  888. zend_throw_exception(sodium_exception_ce, "incorrect state length", 0);
  889. return;
  890. }
  891. memcpy(&state_tmp, state, sizeof state_tmp);
  892. if (crypto_generichash_update((void *) &state_tmp, msg,
  893. (unsigned long long) msg_len) != 0) {
  894. sodium_memzero(&state_tmp, sizeof state_tmp);
  895. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  896. return;
  897. }
  898. memcpy(state, &state_tmp, state_len);
  899. sodium_memzero(&state_tmp, sizeof state_tmp);
  900. RETURN_TRUE;
  901. }
  902. PHP_FUNCTION(sodium_crypto_generichash_final)
  903. {
  904. crypto_generichash_state state_tmp;
  905. zend_string *hash;
  906. zval *state_zv;
  907. unsigned char *state;
  908. size_t state_len;
  909. zend_long hash_len = crypto_generichash_BYTES;
  910. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "z|l",
  911. &state_zv, &hash_len) == FAILURE) {
  912. sodium_remove_param_values_from_backtrace(EG(exception));
  913. return;
  914. }
  915. ZVAL_DEREF(state_zv);
  916. if (Z_TYPE_P(state_zv) != IS_STRING) {
  917. zend_throw_exception(sodium_exception_ce, "a reference to a state is required", 0);
  918. return;
  919. }
  920. sodium_separate_string(state_zv);
  921. state = (unsigned char *) Z_STRVAL(*state_zv);
  922. state_len = Z_STRLEN(*state_zv);
  923. if (state_len != sizeof (crypto_generichash_state)) {
  924. zend_throw_exception(sodium_exception_ce, "incorrect state length", 0);
  925. return;
  926. }
  927. if (hash_len < crypto_generichash_BYTES_MIN ||
  928. hash_len > crypto_generichash_BYTES_MAX) {
  929. zend_throw_exception(sodium_exception_ce, "unsupported output length", 0);
  930. return;
  931. }
  932. hash = zend_string_alloc(hash_len, 0);
  933. memcpy(&state_tmp, state, sizeof state_tmp);
  934. if (crypto_generichash_final((void *) &state_tmp,
  935. (unsigned char *) ZSTR_VAL(hash),
  936. (size_t) hash_len) != 0) {
  937. sodium_memzero(&state_tmp, sizeof state_tmp);
  938. zend_string_efree(hash);
  939. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  940. return;
  941. }
  942. sodium_memzero(&state_tmp, sizeof state_tmp);
  943. sodium_memzero(state, state_len);
  944. convert_to_null(state_zv);
  945. ZSTR_VAL(hash)[hash_len] = 0;
  946. RETURN_NEW_STR(hash);
  947. }
  948. PHP_FUNCTION(sodium_crypto_box_keypair)
  949. {
  950. zend_string *keypair;
  951. size_t keypair_len;
  952. if (zend_parse_parameters_none() == FAILURE) {
  953. return;
  954. }
  955. keypair_len = crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES;
  956. keypair = zend_string_alloc(keypair_len, 0);
  957. if (crypto_box_keypair((unsigned char *) ZSTR_VAL(keypair) +
  958. crypto_box_SECRETKEYBYTES,
  959. (unsigned char *) ZSTR_VAL(keypair)) != 0) {
  960. zend_string_efree(keypair);
  961. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  962. return;
  963. }
  964. ZSTR_VAL(keypair)[keypair_len] = 0;
  965. RETURN_NEW_STR(keypair);
  966. }
  967. PHP_FUNCTION(sodium_crypto_box_seed_keypair)
  968. {
  969. zend_string *keypair;
  970. unsigned char *seed;
  971. size_t keypair_len;
  972. size_t seed_len;
  973. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  974. &seed, &seed_len) == FAILURE) {
  975. sodium_remove_param_values_from_backtrace(EG(exception));
  976. return;
  977. }
  978. if (seed_len != crypto_box_SEEDBYTES) {
  979. zend_throw_exception(sodium_exception_ce,
  980. "seed should be SODIUM_CRYPTO_BOX_SEEDBYTES bytes",
  981. 0);
  982. return;
  983. }
  984. keypair_len = crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES;
  985. keypair = zend_string_alloc(keypair_len, 0);
  986. if (crypto_box_seed_keypair((unsigned char *) ZSTR_VAL(keypair) +
  987. crypto_box_SECRETKEYBYTES,
  988. (unsigned char *) ZSTR_VAL(keypair),
  989. seed) != 0) {
  990. zend_string_efree(keypair);
  991. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  992. return;
  993. }
  994. ZSTR_VAL(keypair)[keypair_len] = 0;
  995. RETURN_NEW_STR(keypair);
  996. }
  997. PHP_FUNCTION(sodium_crypto_box_keypair_from_secretkey_and_publickey)
  998. {
  999. zend_string *keypair;
  1000. char *publickey;
  1001. char *secretkey;
  1002. size_t keypair_len;
  1003. size_t publickey_len;
  1004. size_t secretkey_len;
  1005. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1006. &secretkey, &secretkey_len,
  1007. &publickey, &publickey_len) == FAILURE) {
  1008. sodium_remove_param_values_from_backtrace(EG(exception));
  1009. return;
  1010. }
  1011. if (secretkey_len != crypto_box_SECRETKEYBYTES) {
  1012. zend_throw_exception(sodium_exception_ce,
  1013. "secretkey should be SODIUM_CRYPTO_BOX_SECRETKEYBYTES bytes",
  1014. 0);
  1015. return;
  1016. }
  1017. if (publickey_len != crypto_box_PUBLICKEYBYTES) {
  1018. zend_throw_exception(sodium_exception_ce,
  1019. "publickey should be SODIUM_CRYPTO_BOX_PUBLICKEYBYTES bytes",
  1020. 0);
  1021. return;
  1022. }
  1023. keypair_len = crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES;
  1024. keypair = zend_string_alloc(keypair_len, 0);
  1025. memcpy(ZSTR_VAL(keypair), secretkey, crypto_box_SECRETKEYBYTES);
  1026. memcpy(ZSTR_VAL(keypair) + crypto_box_SECRETKEYBYTES, publickey,
  1027. crypto_box_PUBLICKEYBYTES);
  1028. ZSTR_VAL(keypair)[keypair_len] = 0;
  1029. RETURN_STR(keypair);
  1030. }
  1031. PHP_FUNCTION(sodium_crypto_box_secretkey)
  1032. {
  1033. zend_string *secretkey;
  1034. unsigned char *keypair;
  1035. size_t keypair_len;
  1036. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1037. &keypair, &keypair_len) == FAILURE) {
  1038. sodium_remove_param_values_from_backtrace(EG(exception));
  1039. return;
  1040. }
  1041. if (keypair_len !=
  1042. crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES) {
  1043. zend_throw_exception(sodium_exception_ce,
  1044. "keypair should be SODIUM_CRYPTO_BOX_KEYPAIRBYTES bytes",
  1045. 0);
  1046. return;
  1047. }
  1048. secretkey = zend_string_alloc(crypto_box_SECRETKEYBYTES, 0);
  1049. memcpy(ZSTR_VAL(secretkey), keypair, crypto_box_SECRETKEYBYTES);
  1050. ZSTR_VAL(secretkey)[crypto_box_SECRETKEYBYTES] = 0;
  1051. RETURN_STR(secretkey);
  1052. }
  1053. PHP_FUNCTION(sodium_crypto_box_publickey)
  1054. {
  1055. zend_string *publickey;
  1056. unsigned char *keypair;
  1057. size_t keypair_len;
  1058. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1059. &keypair, &keypair_len) == FAILURE) {
  1060. sodium_remove_param_values_from_backtrace(EG(exception));
  1061. return;
  1062. }
  1063. if (keypair_len !=
  1064. crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES) {
  1065. zend_throw_exception(sodium_exception_ce,
  1066. "keypair should be SODIUM_CRYPTO_BOX_KEYPAIRBYTES bytes",
  1067. 0);
  1068. return;
  1069. }
  1070. publickey = zend_string_alloc(crypto_box_PUBLICKEYBYTES, 0);
  1071. memcpy(ZSTR_VAL(publickey), keypair + crypto_box_SECRETKEYBYTES,
  1072. crypto_box_PUBLICKEYBYTES);
  1073. ZSTR_VAL(publickey)[crypto_box_PUBLICKEYBYTES] = 0;
  1074. RETURN_STR(publickey);
  1075. }
  1076. PHP_FUNCTION(sodium_crypto_box_publickey_from_secretkey)
  1077. {
  1078. zend_string *publickey;
  1079. unsigned char *secretkey;
  1080. size_t secretkey_len;
  1081. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1082. &secretkey, &secretkey_len) == FAILURE) {
  1083. sodium_remove_param_values_from_backtrace(EG(exception));
  1084. return;
  1085. }
  1086. if (secretkey_len != crypto_box_SECRETKEYBYTES) {
  1087. zend_throw_exception(sodium_exception_ce,
  1088. "key should be SODIUM_CRYPTO_BOX_SECRETKEYBYTES bytes",
  1089. 0);
  1090. return;
  1091. }
  1092. publickey = zend_string_alloc(crypto_box_PUBLICKEYBYTES, 0);
  1093. (void) sizeof(int[crypto_scalarmult_BYTES ==
  1094. crypto_box_PUBLICKEYBYTES ? 1 : -1]);
  1095. (void) sizeof(int[crypto_scalarmult_SCALARBYTES ==
  1096. crypto_box_SECRETKEYBYTES ? 1 : -1]);
  1097. crypto_scalarmult_base((unsigned char *) ZSTR_VAL(publickey), secretkey);
  1098. ZSTR_VAL(publickey)[crypto_box_PUBLICKEYBYTES] = 0;
  1099. RETURN_STR(publickey);
  1100. }
  1101. PHP_FUNCTION(sodium_crypto_box)
  1102. {
  1103. zend_string *ciphertext;
  1104. unsigned char *keypair;
  1105. unsigned char *msg;
  1106. unsigned char *nonce;
  1107. unsigned char *publickey;
  1108. unsigned char *secretkey;
  1109. size_t keypair_len;
  1110. size_t msg_len;
  1111. size_t nonce_len;
  1112. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  1113. &msg, &msg_len,
  1114. &nonce, &nonce_len,
  1115. &keypair, &keypair_len) == FAILURE) {
  1116. sodium_remove_param_values_from_backtrace(EG(exception));
  1117. return;
  1118. }
  1119. if (nonce_len != crypto_box_NONCEBYTES) {
  1120. zend_throw_exception(sodium_exception_ce,
  1121. "nonce size should be SODIUM_CRYPTO_BOX_NONCEBYTES bytes",
  1122. 0);
  1123. return;
  1124. }
  1125. if (keypair_len != crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES) {
  1126. zend_throw_exception(sodium_exception_ce,
  1127. "keypair size should be SODIUM_CRYPTO_BOX_KEYPAIRBYTES bytes",
  1128. 0);
  1129. return;
  1130. }
  1131. secretkey = keypair;
  1132. publickey = keypair + crypto_box_SECRETKEYBYTES;
  1133. if (SIZE_MAX - msg_len <= crypto_box_MACBYTES) {
  1134. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  1135. return;
  1136. }
  1137. ciphertext = zend_string_alloc((size_t) msg_len + crypto_box_MACBYTES, 0);
  1138. if (crypto_box_easy((unsigned char *) ZSTR_VAL(ciphertext), msg,
  1139. (unsigned long long) msg_len,
  1140. nonce, publickey, secretkey) != 0) {
  1141. zend_string_efree(ciphertext);
  1142. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1143. return;
  1144. }
  1145. ZSTR_VAL(ciphertext)[msg_len + crypto_box_MACBYTES] = 0;
  1146. RETURN_NEW_STR(ciphertext);
  1147. }
  1148. PHP_FUNCTION(sodium_crypto_box_open)
  1149. {
  1150. zend_string *msg;
  1151. unsigned char *ciphertext;
  1152. unsigned char *keypair;
  1153. unsigned char *nonce;
  1154. unsigned char *publickey;
  1155. unsigned char *secretkey;
  1156. size_t ciphertext_len;
  1157. size_t keypair_len;
  1158. size_t nonce_len;
  1159. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  1160. &ciphertext, &ciphertext_len,
  1161. &nonce, &nonce_len,
  1162. &keypair, &keypair_len) == FAILURE) {
  1163. sodium_remove_param_values_from_backtrace(EG(exception));
  1164. return;
  1165. }
  1166. if (nonce_len != crypto_box_NONCEBYTES) {
  1167. zend_throw_exception(sodium_exception_ce,
  1168. "nonce size should be SODIUM_CRYPTO_BOX_NONCEBYTES bytes",
  1169. 0);
  1170. return;
  1171. }
  1172. if (keypair_len != crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES) {
  1173. zend_throw_exception(sodium_exception_ce,
  1174. "keypair size should be SODIUM_CRYPTO_BOX_KEYPAIRBYTES bytes",
  1175. 0);
  1176. return;
  1177. }
  1178. secretkey = keypair;
  1179. publickey = keypair + crypto_box_SECRETKEYBYTES;
  1180. if (ciphertext_len < crypto_box_MACBYTES) {
  1181. RETURN_FALSE;
  1182. }
  1183. msg = zend_string_alloc((size_t) ciphertext_len - crypto_box_MACBYTES, 0);
  1184. if (crypto_box_open_easy((unsigned char *) ZSTR_VAL(msg), ciphertext,
  1185. (unsigned long long) ciphertext_len,
  1186. nonce, publickey, secretkey) != 0) {
  1187. zend_string_efree(msg);
  1188. RETURN_FALSE;
  1189. } else {
  1190. ZSTR_VAL(msg)[ciphertext_len - crypto_box_MACBYTES] = 0;
  1191. RETURN_NEW_STR(msg);
  1192. }
  1193. }
  1194. PHP_FUNCTION(sodium_crypto_box_seal)
  1195. {
  1196. zend_string *ciphertext;
  1197. unsigned char *msg;
  1198. unsigned char *publickey;
  1199. size_t msg_len;
  1200. size_t publickey_len;
  1201. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1202. &msg, &msg_len,
  1203. &publickey, &publickey_len) == FAILURE) {
  1204. sodium_remove_param_values_from_backtrace(EG(exception));
  1205. return;
  1206. }
  1207. if (publickey_len != crypto_box_PUBLICKEYBYTES) {
  1208. zend_throw_exception(sodium_exception_ce,
  1209. "public key size should be SODIUM_CRYPTO_BOX_PUBLICKEYBYTES bytes",
  1210. 0);
  1211. return;
  1212. }
  1213. if (SIZE_MAX - msg_len <= crypto_box_SEALBYTES) {
  1214. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  1215. return;
  1216. }
  1217. ciphertext = zend_string_alloc((size_t) msg_len + crypto_box_SEALBYTES, 0);
  1218. if (crypto_box_seal((unsigned char *) ZSTR_VAL(ciphertext), msg,
  1219. (unsigned long long) msg_len, publickey) != 0) {
  1220. zend_string_efree(ciphertext);
  1221. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1222. return;
  1223. }
  1224. ZSTR_VAL(ciphertext)[msg_len + crypto_box_SEALBYTES] = 0;
  1225. RETURN_NEW_STR(ciphertext);
  1226. }
  1227. PHP_FUNCTION(sodium_crypto_box_seal_open)
  1228. {
  1229. zend_string *msg;
  1230. unsigned char *ciphertext;
  1231. unsigned char *keypair;
  1232. unsigned char *publickey;
  1233. unsigned char *secretkey;
  1234. size_t ciphertext_len;
  1235. size_t keypair_len;
  1236. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1237. &ciphertext, &ciphertext_len,
  1238. &keypair, &keypair_len) == FAILURE) {
  1239. sodium_remove_param_values_from_backtrace(EG(exception));
  1240. return;
  1241. }
  1242. if (keypair_len != crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES) {
  1243. zend_throw_exception(sodium_exception_ce,
  1244. "keypair size should be SODIUM_CRYPTO_BOX_KEYPAIRBYTES bytes",
  1245. 0);
  1246. return;
  1247. }
  1248. secretkey = keypair;
  1249. publickey = keypair + crypto_box_SECRETKEYBYTES;
  1250. if (ciphertext_len < crypto_box_SEALBYTES) {
  1251. RETURN_FALSE;
  1252. }
  1253. msg = zend_string_alloc((size_t) ciphertext_len - crypto_box_SEALBYTES, 0);
  1254. if (crypto_box_seal_open((unsigned char *) ZSTR_VAL(msg), ciphertext,
  1255. (unsigned long long) ciphertext_len,
  1256. publickey, secretkey) != 0) {
  1257. zend_string_efree(msg);
  1258. RETURN_FALSE;
  1259. } else {
  1260. ZSTR_VAL(msg)[ciphertext_len - crypto_box_SEALBYTES] = 0;
  1261. RETURN_NEW_STR(msg);
  1262. }
  1263. }
  1264. PHP_FUNCTION(sodium_crypto_sign_keypair)
  1265. {
  1266. zend_string *keypair;
  1267. size_t keypair_len;
  1268. if (zend_parse_parameters_none() == FAILURE) {
  1269. return;
  1270. }
  1271. keypair_len = crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES;
  1272. keypair = zend_string_alloc(keypair_len, 0);
  1273. if (crypto_sign_keypair((unsigned char *) ZSTR_VAL(keypair) +
  1274. crypto_sign_SECRETKEYBYTES,
  1275. (unsigned char *) ZSTR_VAL(keypair)) != 0) {
  1276. zend_string_efree(keypair);
  1277. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1278. return;
  1279. }
  1280. ZSTR_VAL(keypair)[keypair_len] = 0;
  1281. RETURN_NEW_STR(keypair);
  1282. }
  1283. PHP_FUNCTION(sodium_crypto_sign_seed_keypair)
  1284. {
  1285. zend_string *keypair;
  1286. unsigned char *seed;
  1287. size_t keypair_len;
  1288. size_t seed_len;
  1289. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1290. &seed, &seed_len) == FAILURE) {
  1291. sodium_remove_param_values_from_backtrace(EG(exception));
  1292. return;
  1293. }
  1294. if (seed_len != crypto_sign_SEEDBYTES) {
  1295. zend_throw_exception(sodium_exception_ce,
  1296. "seed should be SODIUM_CRYPTO_SIGN_SEEDBYTES bytes",
  1297. 0);
  1298. return;
  1299. }
  1300. keypair_len = crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES;
  1301. keypair = zend_string_alloc(keypair_len, 0);
  1302. if (crypto_sign_seed_keypair((unsigned char *) ZSTR_VAL(keypair) +
  1303. crypto_sign_SECRETKEYBYTES,
  1304. (unsigned char *) ZSTR_VAL(keypair),
  1305. seed) != 0) {
  1306. zend_string_efree(keypair);
  1307. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1308. return;
  1309. }
  1310. ZSTR_VAL(keypair)[keypair_len] = 0;
  1311. RETURN_NEW_STR(keypair);
  1312. }
  1313. PHP_FUNCTION(sodium_crypto_sign_keypair_from_secretkey_and_publickey)
  1314. {
  1315. zend_string *keypair;
  1316. char *publickey;
  1317. char *secretkey;
  1318. size_t keypair_len;
  1319. size_t publickey_len;
  1320. size_t secretkey_len;
  1321. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1322. &secretkey, &secretkey_len,
  1323. &publickey, &publickey_len) == FAILURE) {
  1324. sodium_remove_param_values_from_backtrace(EG(exception));
  1325. return;
  1326. }
  1327. if (secretkey_len != crypto_sign_SECRETKEYBYTES) {
  1328. zend_throw_exception(sodium_exception_ce,
  1329. "secretkey should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes",
  1330. 0);
  1331. return;
  1332. }
  1333. if (publickey_len != crypto_sign_PUBLICKEYBYTES) {
  1334. zend_throw_exception(sodium_exception_ce,
  1335. "publickey should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes",
  1336. 0);
  1337. return;
  1338. }
  1339. keypair_len = crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES;
  1340. keypair = zend_string_alloc(keypair_len, 0);
  1341. memcpy(ZSTR_VAL(keypair), secretkey, crypto_sign_SECRETKEYBYTES);
  1342. memcpy(ZSTR_VAL(keypair) + crypto_sign_SECRETKEYBYTES, publickey,
  1343. crypto_sign_PUBLICKEYBYTES);
  1344. ZSTR_VAL(keypair)[keypair_len] = 0;
  1345. RETURN_STR(keypair);
  1346. }
  1347. PHP_FUNCTION(sodium_crypto_sign_publickey_from_secretkey)
  1348. {
  1349. zend_string *publickey;
  1350. char *secretkey;
  1351. size_t secretkey_len;
  1352. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1353. &secretkey, &secretkey_len) == FAILURE) {
  1354. sodium_remove_param_values_from_backtrace(EG(exception));
  1355. return;
  1356. }
  1357. if (secretkey_len != crypto_sign_SECRETKEYBYTES) {
  1358. zend_throw_exception(sodium_exception_ce,
  1359. "secretkey should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes",
  1360. 0);
  1361. return;
  1362. }
  1363. publickey = zend_string_alloc(crypto_sign_PUBLICKEYBYTES, 0);
  1364. if (crypto_sign_ed25519_sk_to_pk((unsigned char *) ZSTR_VAL(publickey),
  1365. (const unsigned char *) secretkey) != 0) {
  1366. zend_throw_exception(sodium_exception_ce,
  1367. "internal error", 0);
  1368. return;
  1369. }
  1370. ZSTR_VAL(publickey)[crypto_sign_PUBLICKEYBYTES] = 0;
  1371. RETURN_STR(publickey);
  1372. }
  1373. PHP_FUNCTION(sodium_crypto_sign_secretkey)
  1374. {
  1375. zend_string *secretkey;
  1376. unsigned char *keypair;
  1377. size_t keypair_len;
  1378. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1379. &keypair, &keypair_len) == FAILURE) {
  1380. sodium_remove_param_values_from_backtrace(EG(exception));
  1381. return;
  1382. }
  1383. if (keypair_len !=
  1384. crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES) {
  1385. zend_throw_exception(sodium_exception_ce,
  1386. "keypair should be SODIUM_CRYPTO_SIGN_KEYPAIRBYTES bytes",
  1387. 0);
  1388. return;
  1389. }
  1390. secretkey = zend_string_alloc(crypto_sign_SECRETKEYBYTES, 0);
  1391. memcpy(ZSTR_VAL(secretkey), keypair, crypto_sign_SECRETKEYBYTES);
  1392. ZSTR_VAL(secretkey)[crypto_sign_SECRETKEYBYTES] = 0;
  1393. RETURN_STR(secretkey);
  1394. }
  1395. PHP_FUNCTION(sodium_crypto_sign_publickey)
  1396. {
  1397. zend_string *publickey;
  1398. unsigned char *keypair;
  1399. size_t keypair_len;
  1400. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  1401. &keypair, &keypair_len) == FAILURE) {
  1402. sodium_remove_param_values_from_backtrace(EG(exception));
  1403. return;
  1404. }
  1405. if (keypair_len !=
  1406. crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES) {
  1407. zend_throw_exception(sodium_exception_ce,
  1408. "keypair should be SODIUM_CRYPTO_SIGN_KEYPAIRBYTES bytes",
  1409. 0);
  1410. return;
  1411. }
  1412. publickey = zend_string_alloc(crypto_sign_PUBLICKEYBYTES, 0);
  1413. memcpy(ZSTR_VAL(publickey), keypair + crypto_sign_SECRETKEYBYTES,
  1414. crypto_sign_PUBLICKEYBYTES);
  1415. ZSTR_VAL(publickey)[crypto_sign_PUBLICKEYBYTES] = 0;
  1416. RETURN_STR(publickey);
  1417. }
  1418. PHP_FUNCTION(sodium_crypto_sign)
  1419. {
  1420. zend_string *msg_signed;
  1421. unsigned char *msg;
  1422. unsigned char *secretkey;
  1423. unsigned long long msg_signed_real_len;
  1424. size_t msg_len;
  1425. size_t msg_signed_len;
  1426. size_t secretkey_len;
  1427. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1428. &msg, &msg_len,
  1429. &secretkey, &secretkey_len) == FAILURE) {
  1430. sodium_remove_param_values_from_backtrace(EG(exception));
  1431. return;
  1432. }
  1433. if (secretkey_len != crypto_sign_SECRETKEYBYTES) {
  1434. zend_throw_exception(sodium_exception_ce,
  1435. "secret key size should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes",
  1436. 0);
  1437. return;
  1438. }
  1439. if (SIZE_MAX - msg_len <= crypto_sign_BYTES) {
  1440. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  1441. return;
  1442. }
  1443. msg_signed_len = msg_len + crypto_sign_BYTES;
  1444. msg_signed = zend_string_alloc((size_t) msg_signed_len, 0);
  1445. if (crypto_sign((unsigned char *) ZSTR_VAL(msg_signed),
  1446. &msg_signed_real_len, msg,
  1447. (unsigned long long) msg_len, secretkey) != 0) {
  1448. zend_string_efree(msg_signed);
  1449. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1450. return;
  1451. }
  1452. if (msg_signed_real_len >= SIZE_MAX || msg_signed_real_len > msg_signed_len) {
  1453. zend_string_efree(msg_signed);
  1454. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  1455. return;
  1456. }
  1457. PHP_SODIUM_ZSTR_TRUNCATE(msg_signed, (size_t) msg_signed_real_len);
  1458. ZSTR_VAL(msg_signed)[msg_signed_real_len] = 0;
  1459. RETURN_NEW_STR(msg_signed);
  1460. }
  1461. PHP_FUNCTION(sodium_crypto_sign_open)
  1462. {
  1463. zend_string *msg;
  1464. unsigned char *msg_signed;
  1465. unsigned char *publickey;
  1466. unsigned long long msg_real_len;
  1467. size_t msg_len;
  1468. size_t msg_signed_len;
  1469. size_t publickey_len;
  1470. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1471. &msg_signed, &msg_signed_len,
  1472. &publickey, &publickey_len) == FAILURE) {
  1473. sodium_remove_param_values_from_backtrace(EG(exception));
  1474. return;
  1475. }
  1476. if (publickey_len != crypto_sign_PUBLICKEYBYTES) {
  1477. zend_throw_exception(sodium_exception_ce,
  1478. "public key size should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes",
  1479. 0);
  1480. return;
  1481. }
  1482. msg_len = msg_signed_len;
  1483. if (msg_len >= SIZE_MAX) {
  1484. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  1485. return;
  1486. }
  1487. msg = zend_string_alloc((size_t) msg_len, 0);
  1488. if (crypto_sign_open((unsigned char *) ZSTR_VAL(msg), &msg_real_len,
  1489. msg_signed, (unsigned long long) msg_signed_len,
  1490. publickey) != 0) {
  1491. zend_string_efree(msg);
  1492. RETURN_FALSE;
  1493. }
  1494. if (msg_real_len >= SIZE_MAX || msg_real_len > msg_signed_len) {
  1495. zend_string_efree(msg);
  1496. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  1497. return;
  1498. }
  1499. PHP_SODIUM_ZSTR_TRUNCATE(msg, (size_t) msg_real_len);
  1500. ZSTR_VAL(msg)[msg_real_len] = 0;
  1501. RETURN_NEW_STR(msg);
  1502. }
  1503. PHP_FUNCTION(sodium_crypto_sign_detached)
  1504. {
  1505. zend_string *signature;
  1506. unsigned char *msg;
  1507. unsigned char *secretkey;
  1508. unsigned long long signature_real_len;
  1509. size_t msg_len;
  1510. size_t secretkey_len;
  1511. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1512. &msg, &msg_len,
  1513. &secretkey, &secretkey_len) == FAILURE) {
  1514. sodium_remove_param_values_from_backtrace(EG(exception));
  1515. return;
  1516. }
  1517. if (secretkey_len != crypto_sign_SECRETKEYBYTES) {
  1518. zend_throw_exception(sodium_exception_ce,
  1519. "secret key size should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes",
  1520. 0);
  1521. return;
  1522. }
  1523. signature = zend_string_alloc((size_t) crypto_sign_BYTES, 0);
  1524. memset(ZSTR_VAL(signature), 0, (size_t) crypto_sign_BYTES);
  1525. if (crypto_sign_detached((unsigned char *) ZSTR_VAL(signature),
  1526. &signature_real_len, msg,
  1527. (unsigned long long) msg_len, secretkey) != 0) {
  1528. zend_string_efree(signature);
  1529. zend_throw_exception(sodium_exception_ce, "signature creation failed", 0);
  1530. return;
  1531. }
  1532. if (signature_real_len <= 0U || signature_real_len > crypto_sign_BYTES) {
  1533. zend_string_efree(signature);
  1534. zend_throw_exception(sodium_exception_ce, "signature has a bogus size", 0);
  1535. return;
  1536. }
  1537. PHP_SODIUM_ZSTR_TRUNCATE(signature, (size_t) signature_real_len);
  1538. ZSTR_VAL(signature)[signature_real_len] = 0;
  1539. RETURN_NEW_STR(signature);
  1540. }
  1541. PHP_FUNCTION(sodium_crypto_sign_verify_detached)
  1542. {
  1543. unsigned char *msg;
  1544. unsigned char *publickey;
  1545. unsigned char *signature;
  1546. size_t msg_len;
  1547. size_t publickey_len;
  1548. size_t signature_len;
  1549. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  1550. &signature, &signature_len,
  1551. &msg, &msg_len,
  1552. &publickey, &publickey_len) == FAILURE) {
  1553. sodium_remove_param_values_from_backtrace(EG(exception));
  1554. return;
  1555. }
  1556. if (signature_len != crypto_sign_BYTES) {
  1557. zend_throw_exception(sodium_exception_ce,
  1558. "signature size should be SODIUM_CRYPTO_SIGN_BYTES bytes",
  1559. 0);
  1560. return;
  1561. }
  1562. if (publickey_len != crypto_sign_PUBLICKEYBYTES) {
  1563. zend_throw_exception(sodium_exception_ce,
  1564. "public key size should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes",
  1565. 0);
  1566. return;
  1567. }
  1568. if (crypto_sign_verify_detached(signature,
  1569. msg, (unsigned long long) msg_len,
  1570. publickey) != 0) {
  1571. RETURN_FALSE;
  1572. }
  1573. RETURN_TRUE;
  1574. }
  1575. PHP_FUNCTION(sodium_crypto_stream)
  1576. {
  1577. zend_string *ciphertext;
  1578. unsigned char *key;
  1579. unsigned char *nonce;
  1580. zend_long ciphertext_len;
  1581. size_t key_len;
  1582. size_t nonce_len;
  1583. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "lss",
  1584. &ciphertext_len,
  1585. &nonce, &nonce_len,
  1586. &key, &key_len) == FAILURE) {
  1587. sodium_remove_param_values_from_backtrace(EG(exception));
  1588. return;
  1589. }
  1590. if (ciphertext_len <= 0 || ciphertext_len >= SIZE_MAX) {
  1591. zend_throw_exception(sodium_exception_ce, "ciphertext length must be greater than 0", 0);
  1592. return;
  1593. }
  1594. if (nonce_len != crypto_stream_NONCEBYTES) {
  1595. zend_throw_exception(sodium_exception_ce, "nonce should be SODIUM_CRYPTO_STREAM_NONCEBYTES bytes", 0);
  1596. return;
  1597. }
  1598. if (key_len != crypto_stream_KEYBYTES) {
  1599. zend_throw_exception(sodium_exception_ce, "key should be SODIUM_CRYPTO_STREAM_KEYBYTES bytes", 0);
  1600. return;
  1601. }
  1602. ciphertext = zend_string_alloc((size_t) ciphertext_len, 0);
  1603. if (crypto_stream((unsigned char *) ZSTR_VAL(ciphertext),
  1604. (unsigned long long) ciphertext_len, nonce, key) != 0) {
  1605. zend_string_efree(ciphertext);
  1606. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1607. return;
  1608. }
  1609. ZSTR_VAL(ciphertext)[ciphertext_len] = 0;
  1610. RETURN_NEW_STR(ciphertext);
  1611. }
  1612. PHP_FUNCTION(sodium_crypto_stream_xor)
  1613. {
  1614. zend_string *ciphertext;
  1615. unsigned char *key;
  1616. unsigned char *msg;
  1617. unsigned char *nonce;
  1618. size_t ciphertext_len;
  1619. size_t key_len;
  1620. size_t msg_len;
  1621. size_t nonce_len;
  1622. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  1623. &msg, &msg_len,
  1624. &nonce, &nonce_len,
  1625. &key, &key_len) == FAILURE) {
  1626. sodium_remove_param_values_from_backtrace(EG(exception));
  1627. return;
  1628. }
  1629. if (nonce_len != crypto_stream_NONCEBYTES) {
  1630. zend_throw_exception(sodium_exception_ce, "nonce should be SODIUM_CRYPTO_STREAM_NONCEBYTES bytes", 0);
  1631. return;
  1632. }
  1633. if (key_len != crypto_stream_KEYBYTES) {
  1634. zend_throw_exception(sodium_exception_ce, "key should be SODIUM_CRYPTO_STREAM_KEYBYTES bytes", 0);
  1635. return;
  1636. }
  1637. ciphertext_len = msg_len;
  1638. ciphertext = zend_string_alloc((size_t) ciphertext_len, 0);
  1639. if (crypto_stream_xor((unsigned char *) ZSTR_VAL(ciphertext), msg,
  1640. (unsigned long long) msg_len, nonce, key) != 0) {
  1641. zend_string_efree(ciphertext);
  1642. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1643. return;
  1644. }
  1645. ZSTR_VAL(ciphertext)[ciphertext_len] = 0;
  1646. RETURN_NEW_STR(ciphertext);
  1647. }
  1648. #ifdef crypto_pwhash_SALTBYTES
  1649. PHP_FUNCTION(sodium_crypto_pwhash)
  1650. {
  1651. zend_string *hash;
  1652. unsigned char *salt;
  1653. char *passwd;
  1654. zend_long hash_len;
  1655. zend_long memlimit;
  1656. zend_long opslimit;
  1657. zend_long alg;
  1658. size_t passwd_len;
  1659. size_t salt_len;
  1660. int ret;
  1661. alg = (zend_long) crypto_pwhash_ALG_DEFAULT;
  1662. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "lssll|l",
  1663. &hash_len,
  1664. &passwd, &passwd_len,
  1665. &salt, &salt_len,
  1666. &opslimit, &memlimit, &alg) == FAILURE) {
  1667. sodium_remove_param_values_from_backtrace(EG(exception));
  1668. return;
  1669. }
  1670. if (hash_len <= 0 || hash_len >= 0xffffffff) {
  1671. zend_throw_exception(sodium_exception_ce, "hash length must be greater than 0", 0);
  1672. return;
  1673. }
  1674. if (passwd_len >= 0xffffffff) {
  1675. zend_throw_exception(sodium_exception_ce, "unsupported password length", 0);
  1676. return;
  1677. }
  1678. if (opslimit <= 0) {
  1679. zend_throw_exception(sodium_exception_ce, "ops limit must be greater than 0", 0);
  1680. return;
  1681. }
  1682. if (memlimit <= 0 || memlimit > SIZE_MAX) {
  1683. zend_throw_exception(sodium_exception_ce, "memory limit must be greater than 0", 0);
  1684. return;
  1685. }
  1686. if (alg != crypto_pwhash_ALG_ARGON2I13
  1687. # ifdef crypto_pwhash_ALG_ARGON2ID13
  1688. && alg != crypto_pwhash_ALG_ARGON2ID13
  1689. # endif
  1690. && alg != crypto_pwhash_ALG_DEFAULT) {
  1691. zend_throw_exception(sodium_exception_ce, "unsupported password hashing algorithm", 0);
  1692. return;
  1693. }
  1694. if (passwd_len <= 0) {
  1695. zend_error(E_WARNING, "empty password");
  1696. }
  1697. if (salt_len != crypto_pwhash_SALTBYTES) {
  1698. zend_throw_exception(sodium_exception_ce, "salt should be SODIUM_CRYPTO_PWHASH_SALTBYTES bytes", 0);
  1699. return;
  1700. }
  1701. if (opslimit < crypto_pwhash_OPSLIMIT_MIN) {
  1702. zend_throw_exception(sodium_exception_ce,
  1703. "number of operations for the password hashing function is too low", 0);
  1704. return;
  1705. }
  1706. if (memlimit < crypto_pwhash_MEMLIMIT_MIN) {
  1707. zend_throw_exception(sodium_exception_ce,
  1708. "maximum memory for the password hashing function is too low", 0);
  1709. }
  1710. hash = zend_string_alloc((size_t) hash_len, 0);
  1711. ret = -1;
  1712. # ifdef crypto_pwhash_ALG_ARGON2ID13
  1713. if (alg == crypto_pwhash_ALG_ARGON2ID13) {
  1714. ret = crypto_pwhash_argon2id
  1715. ((unsigned char *) ZSTR_VAL(hash), (unsigned long long) hash_len,
  1716. passwd, (unsigned long long) passwd_len, salt,
  1717. (unsigned long long) opslimit, (size_t) memlimit, (int) alg);
  1718. }
  1719. # endif
  1720. if (ret == -1) {
  1721. ret = crypto_pwhash
  1722. ((unsigned char *) ZSTR_VAL(hash), (unsigned long long) hash_len,
  1723. passwd, (unsigned long long) passwd_len, salt,
  1724. (unsigned long long) opslimit, (size_t) memlimit, (int) alg);
  1725. }
  1726. if (ret != 0) {
  1727. zend_string_efree(hash);
  1728. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1729. return;
  1730. }
  1731. ZSTR_VAL(hash)[hash_len] = 0;
  1732. RETURN_NEW_STR(hash);
  1733. }
  1734. PHP_FUNCTION(sodium_crypto_pwhash_str)
  1735. {
  1736. zend_string *hash_str;
  1737. char *passwd;
  1738. zend_long memlimit;
  1739. zend_long opslimit;
  1740. size_t passwd_len;
  1741. size_t len;
  1742. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sll",
  1743. &passwd, &passwd_len,
  1744. &opslimit, &memlimit) == FAILURE) {
  1745. sodium_remove_param_values_from_backtrace(EG(exception));
  1746. return;
  1747. }
  1748. if (opslimit <= 0) {
  1749. zend_throw_exception(sodium_exception_ce, "ops limit must be greater than 0", 0);
  1750. return;
  1751. }
  1752. if (memlimit <= 0 || memlimit > SIZE_MAX) {
  1753. zend_throw_exception(sodium_exception_ce, "memory limit must be greater than 0", 0);
  1754. return;
  1755. }
  1756. if (passwd_len >= 0xffffffff) {
  1757. zend_throw_exception(sodium_exception_ce, "unsupported password length", 0);
  1758. return;
  1759. }
  1760. if (passwd_len <= 0) {
  1761. zend_error(E_WARNING, "empty password");
  1762. }
  1763. if (opslimit < crypto_pwhash_OPSLIMIT_MIN) {
  1764. zend_throw_exception(sodium_exception_ce,
  1765. "number of operations for the password hashing function is too low", 0);
  1766. }
  1767. if (memlimit < crypto_pwhash_MEMLIMIT_MIN) {
  1768. zend_throw_exception(sodium_exception_ce,
  1769. "maximum memory for the password hashing function is too low", 0);
  1770. }
  1771. hash_str = zend_string_alloc(crypto_pwhash_STRBYTES - 1, 0);
  1772. if (crypto_pwhash_str
  1773. (ZSTR_VAL(hash_str), passwd, (unsigned long long) passwd_len,
  1774. (unsigned long long) opslimit, (size_t) memlimit) != 0) {
  1775. zend_string_efree(hash_str);
  1776. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1777. return;
  1778. }
  1779. ZSTR_VAL(hash_str)[crypto_pwhash_STRBYTES - 1] = 0;
  1780. len = strlen(ZSTR_VAL(hash_str));
  1781. PHP_SODIUM_ZSTR_TRUNCATE(hash_str, len);
  1782. RETURN_NEW_STR(hash_str);
  1783. }
  1784. #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6)
  1785. PHP_FUNCTION(sodium_crypto_pwhash_str_needs_rehash)
  1786. {
  1787. char *hash_str;
  1788. zend_long memlimit;
  1789. zend_long opslimit;
  1790. size_t hash_str_len;
  1791. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sll",
  1792. &hash_str, &hash_str_len, &opslimit, &memlimit) == FAILURE) {
  1793. zend_throw_exception(sodium_exception_ce, "a PHP string is required", 0);
  1794. return;
  1795. }
  1796. if (crypto_pwhash_str_needs_rehash(hash_str, opslimit, memlimit) == 0) {
  1797. RETURN_FALSE;
  1798. }
  1799. RETURN_TRUE;
  1800. }
  1801. #endif
  1802. PHP_FUNCTION(sodium_crypto_pwhash_str_verify)
  1803. {
  1804. char *hash_str;
  1805. char *passwd;
  1806. size_t hash_str_len;
  1807. size_t passwd_len;
  1808. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1809. &hash_str, &hash_str_len,
  1810. &passwd, &passwd_len) == FAILURE) {
  1811. sodium_remove_param_values_from_backtrace(EG(exception));
  1812. return;
  1813. }
  1814. if (passwd_len >= 0xffffffff) {
  1815. zend_throw_exception(sodium_exception_ce,
  1816. "unsupported password length", 0);
  1817. return;
  1818. }
  1819. if (passwd_len <= 0) {
  1820. zend_error(E_WARNING, "empty password");
  1821. }
  1822. if (crypto_pwhash_str_verify
  1823. (hash_str, passwd, (unsigned long long) passwd_len) == 0) {
  1824. RETURN_TRUE;
  1825. }
  1826. RETURN_FALSE;
  1827. }
  1828. #endif
  1829. #ifdef crypto_pwhash_scryptsalsa208sha256_SALTBYTES
  1830. PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256)
  1831. {
  1832. zend_string *hash;
  1833. unsigned char *salt;
  1834. char *passwd;
  1835. zend_long hash_len;
  1836. zend_long memlimit;
  1837. zend_long opslimit;
  1838. size_t passwd_len;
  1839. size_t salt_len;
  1840. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "lssll",
  1841. &hash_len,
  1842. &passwd, &passwd_len,
  1843. &salt, &salt_len,
  1844. &opslimit, &memlimit) == FAILURE) {
  1845. sodium_remove_param_values_from_backtrace(EG(exception));
  1846. return;
  1847. }
  1848. if (hash_len <= 0 || hash_len >= SIZE_MAX || hash_len > 0x1fffffffe0ULL) {
  1849. zend_throw_exception(sodium_exception_ce, "hash length must be greater than 0", 0);
  1850. return;
  1851. }
  1852. if (opslimit <= 0) {
  1853. zend_throw_exception(sodium_exception_ce, "ops limit must be greater than 0", 0);
  1854. return;
  1855. }
  1856. if (memlimit <= 0 || memlimit > SIZE_MAX) {
  1857. zend_throw_exception(sodium_exception_ce, "memory limit must be greater than 0", 0);
  1858. return;
  1859. }
  1860. if (passwd_len <= 0) {
  1861. zend_error(E_WARNING, "empty password");
  1862. }
  1863. if (salt_len != crypto_pwhash_scryptsalsa208sha256_SALTBYTES) {
  1864. zend_throw_exception(sodium_exception_ce,
  1865. "salt should be SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes",
  1866. 0);
  1867. return;
  1868. }
  1869. if (opslimit < crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE) {
  1870. zend_throw_exception(sodium_exception_ce,
  1871. "number of operations for the scrypt function is too low", 0);
  1872. }
  1873. if (memlimit < crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) {
  1874. zend_throw_exception(sodium_exception_ce,
  1875. "maximum memory for the scrypt function is too low", 0);
  1876. }
  1877. hash = zend_string_alloc((size_t) hash_len, 0);
  1878. if (crypto_pwhash_scryptsalsa208sha256
  1879. ((unsigned char *) ZSTR_VAL(hash), (unsigned long long) hash_len,
  1880. passwd, (unsigned long long) passwd_len, salt,
  1881. (unsigned long long) opslimit, (size_t) memlimit) != 0) {
  1882. zend_string_efree(hash);
  1883. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1884. return;
  1885. }
  1886. ZSTR_VAL(hash)[hash_len] = 0;
  1887. RETURN_NEW_STR(hash);
  1888. }
  1889. PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str)
  1890. {
  1891. zend_string *hash_str;
  1892. char *passwd;
  1893. zend_long memlimit;
  1894. zend_long opslimit;
  1895. size_t passwd_len;
  1896. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sll",
  1897. &passwd, &passwd_len,
  1898. &opslimit, &memlimit) == FAILURE) {
  1899. sodium_remove_param_values_from_backtrace(EG(exception));
  1900. return;
  1901. }
  1902. if (opslimit <= 0) {
  1903. zend_throw_exception(sodium_exception_ce, "ops limit must be greater than 0", 0);
  1904. return;
  1905. }
  1906. if (memlimit <= 0 || memlimit > SIZE_MAX) {
  1907. zend_throw_exception(sodium_exception_ce, "memory limit must be greater than 0", 0);
  1908. return;
  1909. }
  1910. if (passwd_len <= 0) {
  1911. zend_error(E_WARNING, "empty password");
  1912. }
  1913. if (opslimit < crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE) {
  1914. zend_throw_exception(sodium_exception_ce,
  1915. "number of operations for the scrypt function is too low", 0);
  1916. }
  1917. if (memlimit < crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) {
  1918. zend_throw_exception(sodium_exception_ce,
  1919. "maximum memory for the scrypt function is too low", 0);
  1920. }
  1921. hash_str = zend_string_alloc
  1922. (crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1, 0);
  1923. if (crypto_pwhash_scryptsalsa208sha256_str
  1924. (ZSTR_VAL(hash_str), passwd, (unsigned long long) passwd_len,
  1925. (unsigned long long) opslimit, (size_t) memlimit) != 0) {
  1926. zend_string_efree(hash_str);
  1927. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  1928. return;
  1929. }
  1930. ZSTR_VAL(hash_str)[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1] = 0;
  1931. RETURN_NEW_STR(hash_str);
  1932. }
  1933. PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str_verify)
  1934. {
  1935. char *hash_str;
  1936. char *passwd;
  1937. size_t hash_str_len;
  1938. size_t passwd_len;
  1939. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  1940. &hash_str, &hash_str_len,
  1941. &passwd, &passwd_len) == FAILURE) {
  1942. sodium_remove_param_values_from_backtrace(EG(exception));
  1943. return;
  1944. }
  1945. if (passwd_len <= 0) {
  1946. zend_error(E_WARNING, "empty password");
  1947. }
  1948. if (hash_str_len != crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1) {
  1949. zend_error(E_WARNING, "wrong size for the hashed password");
  1950. RETURN_FALSE;
  1951. }
  1952. if (crypto_pwhash_scryptsalsa208sha256_str_verify
  1953. (hash_str, passwd, (unsigned long long) passwd_len) == 0) {
  1954. RETURN_TRUE;
  1955. }
  1956. RETURN_FALSE;
  1957. }
  1958. #endif
  1959. PHP_FUNCTION(sodium_crypto_aead_aes256gcm_is_available)
  1960. {
  1961. if (zend_parse_parameters_none() == FAILURE) {
  1962. return;
  1963. }
  1964. #ifdef HAVE_AESGCM
  1965. RETURN_BOOL(crypto_aead_aes256gcm_is_available());
  1966. #else
  1967. RETURN_FALSE;
  1968. #endif
  1969. }
  1970. #ifdef HAVE_AESGCM
  1971. PHP_FUNCTION(sodium_crypto_aead_aes256gcm_encrypt)
  1972. {
  1973. zend_string *ciphertext;
  1974. unsigned char *ad;
  1975. unsigned char *msg;
  1976. unsigned char *npub;
  1977. unsigned char *secretkey;
  1978. unsigned long long ciphertext_real_len;
  1979. size_t ad_len;
  1980. size_t ciphertext_len;
  1981. size_t msg_len;
  1982. size_t npub_len;
  1983. size_t secretkey_len;
  1984. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  1985. &msg, &msg_len,
  1986. &ad, &ad_len,
  1987. &npub, &npub_len,
  1988. &secretkey, &secretkey_len) == FAILURE) {
  1989. sodium_remove_param_values_from_backtrace(EG(exception));
  1990. return;
  1991. }
  1992. if (npub_len != crypto_aead_aes256gcm_NPUBBYTES) {
  1993. zend_throw_exception(sodium_exception_ce,
  1994. "public nonce size should be "
  1995. "SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES bytes",
  1996. 0);
  1997. return;
  1998. }
  1999. if (secretkey_len != crypto_aead_aes256gcm_KEYBYTES) {
  2000. zend_throw_exception(sodium_exception_ce,
  2001. "secret key size should be "
  2002. "SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES bytes",
  2003. 0);
  2004. return;
  2005. }
  2006. if (SIZE_MAX - msg_len <= crypto_aead_aes256gcm_ABYTES) {
  2007. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2008. return;
  2009. }
  2010. if ((unsigned long long) msg_len > (16ULL * ((1ULL << 32) - 2ULL)) - crypto_aead_aes256gcm_ABYTES) {
  2011. zend_throw_exception(sodium_exception_ce, "message too long for a single key", 0);
  2012. return;
  2013. }
  2014. ciphertext_len = msg_len + crypto_aead_aes256gcm_ABYTES;
  2015. ciphertext = zend_string_alloc((size_t) ciphertext_len, 0);
  2016. if (crypto_aead_aes256gcm_encrypt
  2017. ((unsigned char *) ZSTR_VAL(ciphertext), &ciphertext_real_len, msg,
  2018. (unsigned long long) msg_len,
  2019. ad, (unsigned long long) ad_len, NULL, npub, secretkey) != 0) {
  2020. zend_string_efree(ciphertext);
  2021. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2022. return;
  2023. }
  2024. if (ciphertext_real_len <= 0U || ciphertext_real_len >= SIZE_MAX ||
  2025. ciphertext_real_len > ciphertext_len) {
  2026. zend_string_efree(ciphertext);
  2027. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2028. return;
  2029. }
  2030. PHP_SODIUM_ZSTR_TRUNCATE(ciphertext, (size_t) ciphertext_real_len);
  2031. ZSTR_VAL(ciphertext)[ciphertext_real_len] = 0;
  2032. RETURN_NEW_STR(ciphertext);
  2033. }
  2034. PHP_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt)
  2035. {
  2036. zend_string *msg;
  2037. unsigned char *ad;
  2038. unsigned char *ciphertext;
  2039. unsigned char *npub;
  2040. unsigned char *secretkey;
  2041. unsigned long long msg_real_len;
  2042. size_t ad_len;
  2043. size_t ciphertext_len;
  2044. size_t msg_len;
  2045. size_t npub_len;
  2046. size_t secretkey_len;
  2047. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2048. &ciphertext, &ciphertext_len,
  2049. &ad, &ad_len,
  2050. &npub, &npub_len,
  2051. &secretkey, &secretkey_len) == FAILURE) {
  2052. sodium_remove_param_values_from_backtrace(EG(exception));
  2053. return;
  2054. }
  2055. if (npub_len != crypto_aead_aes256gcm_NPUBBYTES) {
  2056. zend_throw_exception(sodium_exception_ce,
  2057. "public nonce size should be "
  2058. "SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES bytes",
  2059. 0);
  2060. return;
  2061. }
  2062. if (secretkey_len != crypto_aead_aes256gcm_KEYBYTES) {
  2063. zend_throw_exception(sodium_exception_ce,
  2064. "secret key size should be "
  2065. "SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES bytes",
  2066. 0);
  2067. return;
  2068. }
  2069. if (ciphertext_len < crypto_aead_aes256gcm_ABYTES) {
  2070. RETURN_FALSE;
  2071. }
  2072. if (ciphertext_len - crypto_aead_aes256gcm_ABYTES > 16ULL * ((1ULL << 32) - 2ULL)) {
  2073. zend_throw_exception(sodium_exception_ce, "message too long for a single key", 0);
  2074. return;
  2075. }
  2076. msg_len = ciphertext_len;
  2077. if (msg_len >= SIZE_MAX) {
  2078. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2079. return;
  2080. }
  2081. msg = zend_string_alloc((size_t) msg_len, 0);
  2082. if (crypto_aead_aes256gcm_decrypt
  2083. ((unsigned char *) ZSTR_VAL(msg), &msg_real_len, NULL,
  2084. ciphertext, (unsigned long long) ciphertext_len,
  2085. ad, (unsigned long long) ad_len, npub, secretkey) != 0) {
  2086. zend_string_efree(msg);
  2087. RETURN_FALSE;
  2088. }
  2089. if (msg_real_len >= SIZE_MAX || msg_real_len > msg_len) {
  2090. zend_string_efree(msg);
  2091. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2092. return;
  2093. }
  2094. PHP_SODIUM_ZSTR_TRUNCATE(msg, (size_t) msg_real_len);
  2095. ZSTR_VAL(msg)[msg_real_len] = 0;
  2096. RETURN_NEW_STR(msg);
  2097. }
  2098. #endif
  2099. PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_encrypt)
  2100. {
  2101. zend_string *ciphertext;
  2102. unsigned char *ad;
  2103. unsigned char *msg;
  2104. unsigned char *npub;
  2105. unsigned char *secretkey;
  2106. unsigned long long ciphertext_real_len;
  2107. size_t ad_len;
  2108. size_t ciphertext_len;
  2109. size_t msg_len;
  2110. size_t npub_len;
  2111. size_t secretkey_len;
  2112. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2113. &msg, &msg_len,
  2114. &ad, &ad_len,
  2115. &npub, &npub_len,
  2116. &secretkey, &secretkey_len) == FAILURE) {
  2117. sodium_remove_param_values_from_backtrace(EG(exception));
  2118. return;
  2119. }
  2120. if (npub_len != crypto_aead_chacha20poly1305_NPUBBYTES) {
  2121. zend_throw_exception(sodium_exception_ce,
  2122. "public nonce size should be "
  2123. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES bytes",
  2124. 0);
  2125. return;
  2126. }
  2127. if (secretkey_len != crypto_aead_chacha20poly1305_KEYBYTES) {
  2128. zend_throw_exception(sodium_exception_ce,
  2129. "secret key size should be "
  2130. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES bytes",
  2131. 0);
  2132. return;
  2133. }
  2134. if (SIZE_MAX - msg_len <= crypto_aead_chacha20poly1305_ABYTES) {
  2135. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2136. return;
  2137. }
  2138. ciphertext_len = msg_len + crypto_aead_chacha20poly1305_ABYTES;
  2139. ciphertext = zend_string_alloc((size_t) ciphertext_len, 0);
  2140. if (crypto_aead_chacha20poly1305_encrypt
  2141. ((unsigned char *) ZSTR_VAL(ciphertext), &ciphertext_real_len, msg,
  2142. (unsigned long long) msg_len,
  2143. ad, (unsigned long long) ad_len, NULL, npub, secretkey) != 0) {
  2144. zend_string_efree(ciphertext);
  2145. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2146. return;
  2147. }
  2148. if (ciphertext_real_len <= 0U || ciphertext_real_len >= SIZE_MAX ||
  2149. ciphertext_real_len > ciphertext_len) {
  2150. zend_string_efree(ciphertext);
  2151. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2152. return;
  2153. }
  2154. PHP_SODIUM_ZSTR_TRUNCATE(ciphertext, (size_t) ciphertext_real_len);
  2155. ZSTR_VAL(ciphertext)[ciphertext_real_len] = 0;
  2156. RETURN_NEW_STR(ciphertext);
  2157. }
  2158. PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_decrypt)
  2159. {
  2160. zend_string *msg;
  2161. unsigned char *ad;
  2162. unsigned char *ciphertext;
  2163. unsigned char *npub;
  2164. unsigned char *secretkey;
  2165. unsigned long long msg_real_len;
  2166. size_t ad_len;
  2167. size_t ciphertext_len;
  2168. size_t msg_len;
  2169. size_t npub_len;
  2170. size_t secretkey_len;
  2171. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2172. &ciphertext, &ciphertext_len,
  2173. &ad, &ad_len,
  2174. &npub, &npub_len,
  2175. &secretkey, &secretkey_len) == FAILURE) {
  2176. sodium_remove_param_values_from_backtrace(EG(exception));
  2177. return;
  2178. }
  2179. if (npub_len != crypto_aead_chacha20poly1305_NPUBBYTES) {
  2180. zend_throw_exception(sodium_exception_ce,
  2181. "public nonce size should be "
  2182. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES bytes",
  2183. 0);
  2184. return;
  2185. }
  2186. if (secretkey_len != crypto_aead_chacha20poly1305_KEYBYTES) {
  2187. zend_throw_exception(sodium_exception_ce,
  2188. "secret key size should be "
  2189. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES bytes",
  2190. 0);
  2191. return;
  2192. }
  2193. if (ciphertext_len < crypto_aead_chacha20poly1305_ABYTES) {
  2194. RETURN_FALSE;
  2195. }
  2196. msg_len = ciphertext_len;
  2197. if (msg_len >= SIZE_MAX) {
  2198. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2199. return;
  2200. }
  2201. msg = zend_string_alloc((size_t) msg_len, 0);
  2202. if (crypto_aead_chacha20poly1305_decrypt
  2203. ((unsigned char *) ZSTR_VAL(msg), &msg_real_len, NULL,
  2204. ciphertext, (unsigned long long) ciphertext_len,
  2205. ad, (unsigned long long) ad_len, npub, secretkey) != 0) {
  2206. zend_string_efree(msg);
  2207. RETURN_FALSE;
  2208. }
  2209. if (msg_real_len >= SIZE_MAX || msg_real_len > msg_len) {
  2210. zend_string_efree(msg);
  2211. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2212. return;
  2213. }
  2214. PHP_SODIUM_ZSTR_TRUNCATE(msg, (size_t) msg_real_len);
  2215. ZSTR_VAL(msg)[msg_real_len] = 0;
  2216. RETURN_NEW_STR(msg);
  2217. }
  2218. PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_ietf_encrypt)
  2219. {
  2220. zend_string *ciphertext;
  2221. unsigned char *ad;
  2222. unsigned char *msg;
  2223. unsigned char *npub;
  2224. unsigned char *secretkey;
  2225. unsigned long long ciphertext_real_len;
  2226. size_t ad_len;
  2227. size_t ciphertext_len;
  2228. size_t msg_len;
  2229. size_t npub_len;
  2230. size_t secretkey_len;
  2231. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2232. &msg, &msg_len,
  2233. &ad, &ad_len,
  2234. &npub, &npub_len,
  2235. &secretkey, &secretkey_len) == FAILURE) {
  2236. sodium_remove_param_values_from_backtrace(EG(exception));
  2237. return;
  2238. }
  2239. if (npub_len != crypto_aead_chacha20poly1305_IETF_NPUBBYTES) {
  2240. zend_throw_exception(sodium_exception_ce,
  2241. "public nonce size should be "
  2242. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES bytes",
  2243. 0);
  2244. return;
  2245. }
  2246. if (secretkey_len != crypto_aead_chacha20poly1305_IETF_KEYBYTES) {
  2247. zend_throw_exception(sodium_exception_ce,
  2248. "secret key size should be "
  2249. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES bytes",
  2250. 0);
  2251. return;
  2252. }
  2253. if (SIZE_MAX - msg_len <= crypto_aead_chacha20poly1305_IETF_ABYTES) {
  2254. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2255. return;
  2256. }
  2257. if ((unsigned long long) msg_len > 64ULL * (1ULL << 32) - 64ULL) {
  2258. zend_throw_exception(sodium_exception_ce, "message too long for a single key", 0);
  2259. return;
  2260. }
  2261. ciphertext_len = msg_len + crypto_aead_chacha20poly1305_IETF_ABYTES;
  2262. ciphertext = zend_string_alloc((size_t) ciphertext_len, 0);
  2263. if (crypto_aead_chacha20poly1305_ietf_encrypt
  2264. ((unsigned char *) ZSTR_VAL(ciphertext), &ciphertext_real_len, msg,
  2265. (unsigned long long) msg_len,
  2266. ad, (unsigned long long) ad_len, NULL, npub, secretkey) != 0) {
  2267. zend_string_efree(ciphertext);
  2268. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2269. return;
  2270. }
  2271. if (ciphertext_real_len <= 0U || ciphertext_real_len >= SIZE_MAX ||
  2272. ciphertext_real_len > ciphertext_len) {
  2273. zend_string_efree(ciphertext);
  2274. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2275. return;
  2276. }
  2277. PHP_SODIUM_ZSTR_TRUNCATE(ciphertext, (size_t) ciphertext_real_len);
  2278. ZSTR_VAL(ciphertext)[ciphertext_real_len] = 0;
  2279. RETURN_NEW_STR(ciphertext);
  2280. }
  2281. PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_ietf_decrypt)
  2282. {
  2283. zend_string *msg;
  2284. unsigned char *ad;
  2285. unsigned char *ciphertext;
  2286. unsigned char *npub;
  2287. unsigned char *secretkey;
  2288. unsigned long long msg_real_len;
  2289. size_t ad_len;
  2290. size_t ciphertext_len;
  2291. size_t msg_len;
  2292. size_t npub_len;
  2293. size_t secretkey_len;
  2294. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2295. &ciphertext, &ciphertext_len,
  2296. &ad, &ad_len,
  2297. &npub, &npub_len,
  2298. &secretkey, &secretkey_len) == FAILURE) {
  2299. sodium_remove_param_values_from_backtrace(EG(exception));
  2300. return;
  2301. }
  2302. if (npub_len != crypto_aead_chacha20poly1305_IETF_NPUBBYTES) {
  2303. zend_throw_exception(sodium_exception_ce,
  2304. "public nonce size should be "
  2305. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES bytes",
  2306. 0);
  2307. return;
  2308. }
  2309. if (secretkey_len != crypto_aead_chacha20poly1305_IETF_KEYBYTES) {
  2310. zend_throw_exception(sodium_exception_ce,
  2311. "secret key size should be "
  2312. "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES bytes",
  2313. 0);
  2314. return;
  2315. }
  2316. msg_len = ciphertext_len;
  2317. if (msg_len >= SIZE_MAX) {
  2318. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2319. return;
  2320. }
  2321. if (ciphertext_len < crypto_aead_chacha20poly1305_IETF_ABYTES) {
  2322. RETURN_FALSE;
  2323. }
  2324. if ((unsigned long long) ciphertext_len -
  2325. crypto_aead_chacha20poly1305_IETF_ABYTES > 64ULL * (1ULL << 32) - 64ULL) {
  2326. zend_throw_exception(sodium_exception_ce, "message too long for a single key", 0);
  2327. return;
  2328. }
  2329. msg = zend_string_alloc((size_t) msg_len, 0);
  2330. if (crypto_aead_chacha20poly1305_ietf_decrypt
  2331. ((unsigned char *) ZSTR_VAL(msg), &msg_real_len, NULL,
  2332. ciphertext, (unsigned long long) ciphertext_len,
  2333. ad, (unsigned long long) ad_len, npub, secretkey) != 0) {
  2334. zend_string_efree(msg);
  2335. RETURN_FALSE;
  2336. }
  2337. if (msg_real_len >= SIZE_MAX || msg_real_len > msg_len) {
  2338. zend_string_efree(msg);
  2339. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2340. return;
  2341. }
  2342. PHP_SODIUM_ZSTR_TRUNCATE(msg, (size_t) msg_real_len);
  2343. ZSTR_VAL(msg)[msg_real_len] = 0;
  2344. RETURN_NEW_STR(msg);
  2345. }
  2346. #ifdef crypto_aead_xchacha20poly1305_IETF_NPUBBYTES
  2347. PHP_FUNCTION(sodium_crypto_aead_xchacha20poly1305_ietf_encrypt)
  2348. {
  2349. zend_string *ciphertext;
  2350. unsigned char *ad;
  2351. unsigned char *msg;
  2352. unsigned char *npub;
  2353. unsigned char *secretkey;
  2354. unsigned long long ciphertext_real_len;
  2355. size_t ad_len;
  2356. size_t ciphertext_len;
  2357. size_t msg_len;
  2358. size_t npub_len;
  2359. size_t secretkey_len;
  2360. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2361. &msg, &msg_len,
  2362. &ad, &ad_len,
  2363. &npub, &npub_len,
  2364. &secretkey, &secretkey_len) == FAILURE) {
  2365. sodium_remove_param_values_from_backtrace(EG(exception));
  2366. return;
  2367. }
  2368. if (npub_len != crypto_aead_xchacha20poly1305_IETF_NPUBBYTES) {
  2369. zend_throw_exception(sodium_exception_ce,
  2370. "public nonce size should be "
  2371. "SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES bytes",
  2372. 0);
  2373. return;
  2374. }
  2375. if (secretkey_len != crypto_aead_xchacha20poly1305_IETF_KEYBYTES) {
  2376. zend_throw_exception(sodium_exception_ce,
  2377. "secret key size should be "
  2378. "SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES bytes",
  2379. 0);
  2380. return;
  2381. }
  2382. if (SIZE_MAX - msg_len <= crypto_aead_xchacha20poly1305_IETF_ABYTES) {
  2383. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2384. return;
  2385. }
  2386. ciphertext_len = msg_len + crypto_aead_xchacha20poly1305_IETF_ABYTES;
  2387. ciphertext = zend_string_alloc((size_t) ciphertext_len, 0);
  2388. if (crypto_aead_xchacha20poly1305_ietf_encrypt
  2389. ((unsigned char *) ZSTR_VAL(ciphertext), &ciphertext_real_len, msg,
  2390. (unsigned long long) msg_len,
  2391. ad, (unsigned long long) ad_len, NULL, npub, secretkey) != 0) {
  2392. zend_string_efree(ciphertext);
  2393. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2394. return;
  2395. }
  2396. if (ciphertext_real_len <= 0U || ciphertext_real_len >= SIZE_MAX ||
  2397. ciphertext_real_len > ciphertext_len) {
  2398. zend_string_efree(ciphertext);
  2399. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2400. return;
  2401. }
  2402. PHP_SODIUM_ZSTR_TRUNCATE(ciphertext, (size_t) ciphertext_real_len);
  2403. ZSTR_VAL(ciphertext)[ciphertext_real_len] = 0;
  2404. RETURN_NEW_STR(ciphertext);
  2405. }
  2406. PHP_FUNCTION(sodium_crypto_aead_xchacha20poly1305_ietf_decrypt)
  2407. {
  2408. zend_string *msg;
  2409. unsigned char *ad;
  2410. unsigned char *ciphertext;
  2411. unsigned char *npub;
  2412. unsigned char *secretkey;
  2413. unsigned long long msg_real_len;
  2414. size_t ad_len;
  2415. size_t ciphertext_len;
  2416. size_t msg_len;
  2417. size_t npub_len;
  2418. size_t secretkey_len;
  2419. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ssss",
  2420. &ciphertext, &ciphertext_len,
  2421. &ad, &ad_len,
  2422. &npub, &npub_len,
  2423. &secretkey, &secretkey_len) == FAILURE) {
  2424. sodium_remove_param_values_from_backtrace(EG(exception));
  2425. return;
  2426. }
  2427. if (npub_len != crypto_aead_xchacha20poly1305_IETF_NPUBBYTES) {
  2428. zend_throw_exception(sodium_exception_ce,
  2429. "public nonce size should be "
  2430. "SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES bytes",
  2431. 0);
  2432. return;
  2433. }
  2434. if (secretkey_len != crypto_aead_xchacha20poly1305_IETF_KEYBYTES) {
  2435. zend_throw_exception(sodium_exception_ce,
  2436. "secret key size should be "
  2437. "SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES bytes",
  2438. 0);
  2439. return;
  2440. }
  2441. if (ciphertext_len < crypto_aead_xchacha20poly1305_IETF_ABYTES) {
  2442. RETURN_FALSE;
  2443. }
  2444. msg_len = ciphertext_len;
  2445. if (msg_len - crypto_aead_xchacha20poly1305_IETF_ABYTES >= SIZE_MAX) {
  2446. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2447. return;
  2448. }
  2449. if ((unsigned long long) ciphertext_len -
  2450. crypto_aead_xchacha20poly1305_IETF_ABYTES > 64ULL * (1ULL << 32) - 64ULL) {
  2451. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2452. return;
  2453. }
  2454. msg = zend_string_alloc((size_t) msg_len, 0);
  2455. if (crypto_aead_xchacha20poly1305_ietf_decrypt
  2456. ((unsigned char *) ZSTR_VAL(msg), &msg_real_len, NULL,
  2457. ciphertext, (unsigned long long) ciphertext_len,
  2458. ad, (unsigned long long) ad_len, npub, secretkey) != 0) {
  2459. zend_string_efree(msg);
  2460. RETURN_FALSE;
  2461. }
  2462. if (msg_real_len >= SIZE_MAX || msg_real_len > msg_len) {
  2463. zend_string_efree(msg);
  2464. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2465. return;
  2466. }
  2467. PHP_SODIUM_ZSTR_TRUNCATE(msg, (size_t) msg_real_len);
  2468. ZSTR_VAL(msg)[msg_real_len] = 0;
  2469. RETURN_NEW_STR(msg);
  2470. }
  2471. #endif
  2472. PHP_FUNCTION(sodium_bin2hex)
  2473. {
  2474. zend_string *hex;
  2475. unsigned char *bin;
  2476. size_t bin_len;
  2477. size_t hex_len;
  2478. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  2479. &bin, &bin_len) == FAILURE) {
  2480. sodium_remove_param_values_from_backtrace(EG(exception));
  2481. return;
  2482. }
  2483. if (bin_len >= SIZE_MAX / 2U) {
  2484. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2485. return;
  2486. }
  2487. hex_len = bin_len * 2U;
  2488. hex = zend_string_alloc((size_t) hex_len, 0);
  2489. sodium_bin2hex(ZSTR_VAL(hex), hex_len + 1U, bin, bin_len);
  2490. ZSTR_VAL(hex)[hex_len] = 0;
  2491. RETURN_STR(hex);
  2492. }
  2493. PHP_FUNCTION(sodium_hex2bin)
  2494. {
  2495. zend_string *bin;
  2496. const char *end;
  2497. char *hex;
  2498. char *ignore = NULL;
  2499. size_t bin_real_len;
  2500. size_t bin_len;
  2501. size_t hex_len;
  2502. size_t ignore_len = 0;
  2503. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s|s",
  2504. &hex, &hex_len,
  2505. &ignore, &ignore_len) == FAILURE) {
  2506. sodium_remove_param_values_from_backtrace(EG(exception));
  2507. return;
  2508. }
  2509. bin_len = hex_len / 2;
  2510. bin = zend_string_alloc(bin_len, 0);
  2511. if (sodium_hex2bin((unsigned char *) ZSTR_VAL(bin), bin_len, hex, hex_len,
  2512. ignore, &bin_real_len, &end) != 0 ||
  2513. end != hex + hex_len) {
  2514. zend_string_efree(bin);
  2515. zend_throw_exception(sodium_exception_ce, "invalid hex string", 0);
  2516. return;
  2517. }
  2518. if (bin_real_len >= SIZE_MAX || bin_real_len > bin_len) {
  2519. zend_string_efree(bin);
  2520. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2521. return;
  2522. }
  2523. PHP_SODIUM_ZSTR_TRUNCATE(bin, (size_t) bin_real_len);
  2524. ZSTR_VAL(bin)[bin_real_len] = 0;
  2525. RETURN_NEW_STR(bin);
  2526. }
  2527. #ifdef sodium_base64_VARIANT_ORIGINAL
  2528. PHP_FUNCTION(sodium_bin2base64)
  2529. {
  2530. zend_string *b64;
  2531. unsigned char *bin;
  2532. zend_long variant;
  2533. size_t bin_len;
  2534. size_t b64_len;
  2535. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sl",
  2536. &bin, &bin_len, &variant) == FAILURE) {
  2537. sodium_remove_param_values_from_backtrace(EG(exception));
  2538. return;
  2539. }
  2540. if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) {
  2541. zend_throw_exception(sodium_exception_ce,
  2542. "invalid base64 variant identifier", 0);
  2543. return;
  2544. }
  2545. if (bin_len >= SIZE_MAX / 4U * 3U - 3U - 1U) {
  2546. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2547. return;
  2548. }
  2549. b64_len = sodium_base64_ENCODED_LEN(bin_len, variant);
  2550. b64 = zend_string_alloc((size_t) b64_len - 1U, 0);
  2551. sodium_bin2base64(ZSTR_VAL(b64), b64_len, bin, bin_len, (int) variant);
  2552. RETURN_STR(b64);
  2553. }
  2554. PHP_FUNCTION(sodium_base642bin)
  2555. {
  2556. zend_string *bin;
  2557. char *b64;
  2558. const char *end;
  2559. char *ignore = NULL;
  2560. zend_long variant;
  2561. size_t bin_real_len;
  2562. size_t bin_len;
  2563. size_t b64_len;
  2564. size_t ignore_len = 0;
  2565. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sl|s",
  2566. &b64, &b64_len, &variant,
  2567. &ignore, &ignore_len) == FAILURE) {
  2568. sodium_remove_param_values_from_backtrace(EG(exception));
  2569. return;
  2570. }
  2571. if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) {
  2572. zend_throw_exception(sodium_exception_ce,
  2573. "invalid base64 variant identifier", 0);
  2574. return;
  2575. }
  2576. bin_len = b64_len / 4U * 3U + 2U;
  2577. bin = zend_string_alloc(bin_len, 0);
  2578. if (sodium_base642bin((unsigned char *) ZSTR_VAL(bin), bin_len,
  2579. b64, b64_len,
  2580. ignore, &bin_real_len, &end, (int) variant) != 0 ||
  2581. end != b64 + b64_len) {
  2582. zend_string_efree(bin);
  2583. zend_throw_exception(sodium_exception_ce, "invalid base64 string", 0);
  2584. return;
  2585. }
  2586. if (bin_real_len >= SIZE_MAX || bin_real_len > bin_len) {
  2587. zend_string_efree(bin);
  2588. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  2589. return;
  2590. }
  2591. PHP_SODIUM_ZSTR_TRUNCATE(bin, (size_t) bin_real_len);
  2592. ZSTR_VAL(bin)[bin_real_len] = 0;
  2593. RETURN_NEW_STR(bin);
  2594. }
  2595. #endif
  2596. PHP_FUNCTION(sodium_crypto_scalarmult)
  2597. {
  2598. zend_string *q;
  2599. unsigned char *n;
  2600. unsigned char *p;
  2601. size_t n_len;
  2602. size_t p_len;
  2603. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  2604. &n, &n_len, &p, &p_len) == FAILURE) {
  2605. sodium_remove_param_values_from_backtrace(EG(exception));
  2606. return;
  2607. }
  2608. if (n_len != crypto_scalarmult_SCALARBYTES ||
  2609. p_len != crypto_scalarmult_BYTES) {
  2610. zend_throw_exception(sodium_exception_ce, "scalar and point must be "
  2611. "SODIUM_CRYPTO_SCALARMULT_SCALARBYTES bytes",
  2612. 0);
  2613. return;
  2614. }
  2615. q = zend_string_alloc(crypto_scalarmult_BYTES, 0);
  2616. if (crypto_scalarmult((unsigned char *) ZSTR_VAL(q), n, p) != 0) {
  2617. zend_string_efree(q);
  2618. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2619. return;
  2620. }
  2621. ZSTR_VAL(q)[crypto_scalarmult_BYTES] = 0;
  2622. RETURN_NEW_STR(q);
  2623. }
  2624. PHP_FUNCTION(sodium_crypto_kx_seed_keypair)
  2625. {
  2626. unsigned char *sk;
  2627. unsigned char *pk;
  2628. unsigned char *seed;
  2629. size_t seed_len;
  2630. zend_string *keypair;
  2631. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  2632. &seed, &seed_len) == FAILURE) {
  2633. sodium_remove_param_values_from_backtrace(EG(exception));
  2634. return;
  2635. }
  2636. if (seed_len != crypto_kx_SEEDBYTES) {
  2637. zend_throw_exception(sodium_exception_ce, "seed must be SODIUM_CRYPTO_KX_SEEDBYTES bytes", 0);
  2638. return;
  2639. }
  2640. (void) sizeof(int[crypto_scalarmult_SCALARBYTES == crypto_kx_PUBLICKEYBYTES ? 1 : -1]);
  2641. (void) sizeof(int[crypto_scalarmult_SCALARBYTES == crypto_kx_SECRETKEYBYTES ? 1 : -1]);
  2642. keypair = zend_string_alloc(crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES, 0);
  2643. sk = (unsigned char *) ZSTR_VAL(keypair);
  2644. pk = sk + crypto_kx_SECRETKEYBYTES;
  2645. crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
  2646. seed, crypto_kx_SEEDBYTES, NULL, 0);
  2647. if (crypto_scalarmult_base(pk, sk) != 0) {
  2648. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2649. return;
  2650. }
  2651. ZSTR_VAL(keypair)[crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES] = 0;
  2652. RETURN_STR(keypair);
  2653. }
  2654. PHP_FUNCTION(sodium_crypto_kx_keypair)
  2655. {
  2656. unsigned char *sk;
  2657. unsigned char *pk;
  2658. zend_string *keypair;
  2659. if (zend_parse_parameters_none() == FAILURE) {
  2660. return;
  2661. }
  2662. keypair = zend_string_alloc(crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES, 0);
  2663. sk = (unsigned char *) ZSTR_VAL(keypair);
  2664. pk = sk + crypto_kx_SECRETKEYBYTES;
  2665. randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
  2666. if (crypto_scalarmult_base(pk, sk) != 0) {
  2667. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2668. return;
  2669. }
  2670. ZSTR_VAL(keypair)[crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES] = 0;
  2671. RETURN_STR(keypair);
  2672. }
  2673. PHP_FUNCTION(sodium_crypto_kx_secretkey)
  2674. {
  2675. zend_string *secretkey;
  2676. unsigned char *keypair;
  2677. size_t keypair_len;
  2678. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  2679. &keypair, &keypair_len) == FAILURE) {
  2680. sodium_remove_param_values_from_backtrace(EG(exception));
  2681. return;
  2682. }
  2683. if (keypair_len !=
  2684. crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES) {
  2685. zend_throw_exception(sodium_exception_ce,
  2686. "keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes",
  2687. 0);
  2688. return;
  2689. }
  2690. secretkey = zend_string_alloc(crypto_kx_SECRETKEYBYTES, 0);
  2691. memcpy(ZSTR_VAL(secretkey), keypair, crypto_kx_SECRETKEYBYTES);
  2692. ZSTR_VAL(secretkey)[crypto_kx_SECRETKEYBYTES] = 0;
  2693. RETURN_STR(secretkey);
  2694. }
  2695. PHP_FUNCTION(sodium_crypto_kx_publickey)
  2696. {
  2697. zend_string *publickey;
  2698. unsigned char *keypair;
  2699. size_t keypair_len;
  2700. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  2701. &keypair, &keypair_len) == FAILURE) {
  2702. sodium_remove_param_values_from_backtrace(EG(exception));
  2703. return;
  2704. }
  2705. if (keypair_len !=
  2706. crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES) {
  2707. zend_throw_exception(sodium_exception_ce,
  2708. "keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes",
  2709. 0);
  2710. return;
  2711. }
  2712. publickey = zend_string_alloc(crypto_kx_PUBLICKEYBYTES, 0);
  2713. memcpy(ZSTR_VAL(publickey), keypair + crypto_kx_SECRETKEYBYTES,
  2714. crypto_kx_PUBLICKEYBYTES);
  2715. ZSTR_VAL(publickey)[crypto_kx_PUBLICKEYBYTES] = 0;
  2716. RETURN_STR(publickey);
  2717. }
  2718. PHP_FUNCTION(sodium_crypto_kx_client_session_keys)
  2719. {
  2720. crypto_generichash_state h;
  2721. unsigned char q[crypto_scalarmult_BYTES];
  2722. unsigned char *keypair;
  2723. unsigned char *client_sk;
  2724. unsigned char *client_pk;
  2725. unsigned char *server_pk;
  2726. unsigned char session_keys[2 * crypto_kx_SESSIONKEYBYTES];
  2727. size_t keypair_len;
  2728. size_t server_pk_len;
  2729. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  2730. &keypair, &keypair_len,
  2731. &server_pk, &server_pk_len) == FAILURE) {
  2732. sodium_remove_param_values_from_backtrace(EG(exception));
  2733. return;
  2734. }
  2735. if (keypair_len != crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES) {
  2736. zend_throw_exception(sodium_exception_ce, "keypair must be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes", 0);
  2737. return;
  2738. }
  2739. if (server_pk_len != crypto_kx_PUBLICKEYBYTES) {
  2740. zend_throw_exception(sodium_exception_ce, "public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes", 0);
  2741. return;
  2742. }
  2743. client_sk = &keypair[0];
  2744. client_pk = &keypair[crypto_kx_SECRETKEYBYTES];
  2745. (void) sizeof(int[crypto_scalarmult_SCALARBYTES == crypto_kx_PUBLICKEYBYTES ? 1 : -1]);
  2746. (void) sizeof(int[crypto_scalarmult_SCALARBYTES == crypto_kx_SECRETKEYBYTES ? 1 : -1]);
  2747. if (crypto_scalarmult(q, client_sk, server_pk) != 0) {
  2748. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2749. return;
  2750. }
  2751. crypto_generichash_init(&h, NULL, 0U, 2 * crypto_kx_SESSIONKEYBYTES);
  2752. crypto_generichash_update(&h, q, sizeof q);
  2753. sodium_memzero(q, sizeof q);
  2754. crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
  2755. crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
  2756. crypto_generichash_final(&h, session_keys, 2 * crypto_kx_SESSIONKEYBYTES);
  2757. sodium_memzero(&h, sizeof h);
  2758. array_init(return_value);
  2759. add_next_index_stringl(return_value,
  2760. (const char *) session_keys,
  2761. crypto_kx_SESSIONKEYBYTES);
  2762. add_next_index_stringl(return_value,
  2763. (const char *) session_keys + crypto_kx_SESSIONKEYBYTES,
  2764. crypto_kx_SESSIONKEYBYTES);
  2765. }
  2766. PHP_FUNCTION(sodium_crypto_kx_server_session_keys)
  2767. {
  2768. crypto_generichash_state h;
  2769. unsigned char q[crypto_scalarmult_BYTES];
  2770. unsigned char *keypair;
  2771. unsigned char *server_sk;
  2772. unsigned char *server_pk;
  2773. unsigned char *client_pk;
  2774. unsigned char session_keys[2 * crypto_kx_SESSIONKEYBYTES];
  2775. size_t keypair_len;
  2776. size_t client_pk_len;
  2777. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  2778. &keypair, &keypair_len,
  2779. &client_pk, &client_pk_len) == FAILURE) {
  2780. sodium_remove_param_values_from_backtrace(EG(exception));
  2781. return;
  2782. }
  2783. if (keypair_len != crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES) {
  2784. zend_throw_exception(sodium_exception_ce, "keypair must be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes", 0);
  2785. return;
  2786. }
  2787. if (client_pk_len != crypto_kx_PUBLICKEYBYTES) {
  2788. zend_throw_exception(sodium_exception_ce, "public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes", 0);
  2789. return;
  2790. }
  2791. server_sk = &keypair[0];
  2792. server_pk = &keypair[crypto_kx_SECRETKEYBYTES];
  2793. (void) sizeof(int[crypto_scalarmult_SCALARBYTES == crypto_kx_PUBLICKEYBYTES ? 1 : -1]);
  2794. (void) sizeof(int[crypto_scalarmult_SCALARBYTES == crypto_kx_SECRETKEYBYTES ? 1 : -1]);
  2795. if (crypto_scalarmult(q, server_sk, client_pk) != 0) {
  2796. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2797. return;
  2798. }
  2799. crypto_generichash_init(&h, NULL, 0U, 2 * crypto_kx_SESSIONKEYBYTES);
  2800. crypto_generichash_update(&h, q, sizeof q);
  2801. sodium_memzero(q, sizeof q);
  2802. crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
  2803. crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
  2804. crypto_generichash_final(&h, session_keys, 2 * crypto_kx_SESSIONKEYBYTES);
  2805. sodium_memzero(&h, sizeof h);
  2806. array_init(return_value);
  2807. add_next_index_stringl(return_value,
  2808. (const char *) session_keys + crypto_kx_SESSIONKEYBYTES,
  2809. crypto_kx_SESSIONKEYBYTES);
  2810. add_next_index_stringl(return_value,
  2811. (const char *) session_keys,
  2812. crypto_kx_SESSIONKEYBYTES);
  2813. }
  2814. PHP_FUNCTION(sodium_crypto_auth)
  2815. {
  2816. zend_string *mac;
  2817. char *key;
  2818. char *msg;
  2819. size_t msg_len;
  2820. size_t key_len;
  2821. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  2822. &msg, &msg_len,
  2823. &key, &key_len) == FAILURE) {
  2824. sodium_remove_param_values_from_backtrace(EG(exception));
  2825. return;
  2826. }
  2827. if (key_len != crypto_auth_KEYBYTES) {
  2828. zend_throw_exception(sodium_exception_ce, "key must be SODIUM_CRYPTO_AUTH_KEYBYTES bytes", 0);
  2829. return;
  2830. }
  2831. mac = zend_string_alloc(crypto_auth_BYTES, 0);
  2832. if (crypto_auth((unsigned char *) ZSTR_VAL(mac),
  2833. (const unsigned char *) msg, msg_len,
  2834. (const unsigned char *) key) != 0) {
  2835. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  2836. return;
  2837. }
  2838. ZSTR_VAL(mac)[crypto_auth_BYTES] = 0;
  2839. RETURN_STR(mac);
  2840. }
  2841. PHP_FUNCTION(sodium_crypto_auth_verify)
  2842. {
  2843. char *mac;
  2844. char *key;
  2845. char *msg;
  2846. size_t mac_len;
  2847. size_t msg_len;
  2848. size_t key_len;
  2849. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sss",
  2850. &mac, &mac_len,
  2851. &msg, &msg_len,
  2852. &key, &key_len) == FAILURE) {
  2853. sodium_remove_param_values_from_backtrace(EG(exception));
  2854. return;
  2855. }
  2856. if (key_len != crypto_auth_KEYBYTES) {
  2857. zend_throw_exception(sodium_exception_ce, "key must be SODIUM_CRYPTO_AUTH_KEYBYTES bytes", 0);
  2858. return;
  2859. }
  2860. if (mac_len != crypto_auth_BYTES) {
  2861. zend_throw_exception(sodium_exception_ce, "authentication tag must be SODIUM_CRYPTO_AUTH_BYTES bytes", 0);
  2862. return;
  2863. }
  2864. if (crypto_auth_verify((const unsigned char *) mac,
  2865. (const unsigned char *) msg, msg_len,
  2866. (const unsigned char *) key) != 0) {
  2867. RETURN_FALSE;
  2868. }
  2869. RETURN_TRUE;
  2870. }
  2871. PHP_FUNCTION(sodium_crypto_sign_ed25519_sk_to_curve25519)
  2872. {
  2873. zend_string *ecdhkey;
  2874. char *eddsakey;
  2875. size_t eddsakey_len;
  2876. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  2877. &eddsakey, &eddsakey_len) == FAILURE) {
  2878. sodium_remove_param_values_from_backtrace(EG(exception));
  2879. return;
  2880. }
  2881. if (eddsakey_len != crypto_sign_SECRETKEYBYTES) {
  2882. zend_throw_exception(sodium_exception_ce,
  2883. "Ed25519 key should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes",
  2884. 0);
  2885. return;
  2886. }
  2887. ecdhkey = zend_string_alloc(crypto_box_SECRETKEYBYTES, 0);
  2888. if (crypto_sign_ed25519_sk_to_curve25519((unsigned char *) ZSTR_VAL(ecdhkey),
  2889. (const unsigned char *) eddsakey) != 0) {
  2890. zend_throw_exception(sodium_exception_ce, "conversion failed", 0);
  2891. return;
  2892. }
  2893. ZSTR_VAL(ecdhkey)[crypto_box_SECRETKEYBYTES] = 0;
  2894. RETURN_STR(ecdhkey);
  2895. }
  2896. PHP_FUNCTION(sodium_crypto_sign_ed25519_pk_to_curve25519)
  2897. {
  2898. zend_string *ecdhkey;
  2899. char *eddsakey;
  2900. size_t eddsakey_len;
  2901. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  2902. &eddsakey, &eddsakey_len) == FAILURE) {
  2903. sodium_remove_param_values_from_backtrace(EG(exception));
  2904. return;
  2905. }
  2906. if (eddsakey_len != crypto_sign_PUBLICKEYBYTES) {
  2907. zend_throw_exception(sodium_exception_ce,
  2908. "Ed25519 key should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes",
  2909. 0);
  2910. return;
  2911. }
  2912. ecdhkey = zend_string_alloc(crypto_sign_PUBLICKEYBYTES, 0);
  2913. if (crypto_sign_ed25519_pk_to_curve25519((unsigned char *) ZSTR_VAL(ecdhkey),
  2914. (const unsigned char *) eddsakey) != 0) {
  2915. zend_throw_exception(sodium_exception_ce, "conversion failed", 0);
  2916. return;
  2917. }
  2918. ZSTR_VAL(ecdhkey)[crypto_box_PUBLICKEYBYTES] = 0;
  2919. RETURN_STR(ecdhkey);
  2920. }
  2921. PHP_FUNCTION(sodium_compare)
  2922. {
  2923. char *buf1;
  2924. char *buf2;
  2925. size_t len1;
  2926. size_t len2;
  2927. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  2928. &buf1, &len1,
  2929. &buf2, &len2) == FAILURE) {
  2930. sodium_remove_param_values_from_backtrace(EG(exception));
  2931. return;
  2932. }
  2933. if (len1 != len2) {
  2934. zend_throw_exception(sodium_exception_ce, "arguments have different sizes", 0);
  2935. return;
  2936. } else {
  2937. RETURN_LONG(sodium_compare((const unsigned char *) buf1,
  2938. (const unsigned char *) buf2, (size_t) len1));
  2939. }
  2940. }
  2941. #ifdef HAVE_AESGCM
  2942. PHP_FUNCTION(sodium_crypto_aead_aes256gcm_keygen)
  2943. {
  2944. unsigned char key[crypto_aead_aes256gcm_KEYBYTES];
  2945. if (zend_parse_parameters_none() == FAILURE) {
  2946. return;
  2947. }
  2948. randombytes_buf(key, sizeof key);
  2949. RETURN_STRINGL((const char *) key, sizeof key);
  2950. }
  2951. #endif
  2952. PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_keygen)
  2953. {
  2954. unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES];
  2955. if (zend_parse_parameters_none() == FAILURE) {
  2956. return;
  2957. }
  2958. randombytes_buf(key, sizeof key);
  2959. RETURN_STRINGL((const char *) key, sizeof key);
  2960. }
  2961. PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_ietf_keygen)
  2962. {
  2963. unsigned char key[crypto_aead_chacha20poly1305_IETF_KEYBYTES];
  2964. if (zend_parse_parameters_none() == FAILURE) {
  2965. return;
  2966. }
  2967. randombytes_buf(key, sizeof key);
  2968. RETURN_STRINGL((const char *) key, sizeof key);
  2969. }
  2970. #ifdef crypto_aead_xchacha20poly1305_IETF_NPUBBYTES
  2971. PHP_FUNCTION(sodium_crypto_aead_xchacha20poly1305_ietf_keygen)
  2972. {
  2973. unsigned char key[crypto_aead_xchacha20poly1305_IETF_KEYBYTES];
  2974. if (zend_parse_parameters_none() == FAILURE) {
  2975. return;
  2976. }
  2977. randombytes_buf(key, sizeof key);
  2978. RETURN_STRINGL((const char *) key, sizeof key);
  2979. }
  2980. #endif
  2981. PHP_FUNCTION(sodium_crypto_auth_keygen)
  2982. {
  2983. unsigned char key[crypto_auth_KEYBYTES];
  2984. if (zend_parse_parameters_none() == FAILURE) {
  2985. return;
  2986. }
  2987. randombytes_buf(key, sizeof key);
  2988. RETURN_STRINGL((const char *) key, sizeof key);
  2989. }
  2990. PHP_FUNCTION(sodium_crypto_generichash_keygen)
  2991. {
  2992. unsigned char key[crypto_generichash_KEYBYTES];
  2993. if (zend_parse_parameters_none() == FAILURE) {
  2994. return;
  2995. }
  2996. randombytes_buf(key, sizeof key);
  2997. RETURN_STRINGL((const char *) key, sizeof key);
  2998. }
  2999. PHP_FUNCTION(sodium_crypto_kdf_keygen)
  3000. {
  3001. unsigned char key[crypto_kdf_KEYBYTES];
  3002. if (zend_parse_parameters_none() == FAILURE) {
  3003. return;
  3004. }
  3005. randombytes_buf(key, sizeof key);
  3006. RETURN_STRINGL((const char *) key, sizeof key);
  3007. }
  3008. PHP_FUNCTION(sodium_crypto_secretbox_keygen)
  3009. {
  3010. unsigned char key[crypto_secretbox_KEYBYTES];
  3011. if (zend_parse_parameters_none() == FAILURE) {
  3012. return;
  3013. }
  3014. randombytes_buf(key, sizeof key);
  3015. RETURN_STRINGL((const char *) key, sizeof key);
  3016. }
  3017. PHP_FUNCTION(sodium_crypto_shorthash_keygen)
  3018. {
  3019. unsigned char key[crypto_shorthash_KEYBYTES];
  3020. if (zend_parse_parameters_none() == FAILURE) {
  3021. return;
  3022. }
  3023. randombytes_buf(key, sizeof key);
  3024. RETURN_STRINGL((const char *) key, sizeof key);
  3025. }
  3026. PHP_FUNCTION(sodium_crypto_stream_keygen)
  3027. {
  3028. unsigned char key[crypto_stream_KEYBYTES];
  3029. if (zend_parse_parameters_none() == FAILURE) {
  3030. return;
  3031. }
  3032. randombytes_buf(key, sizeof key);
  3033. RETURN_STRINGL((const char *) key, sizeof key);
  3034. }
  3035. PHP_FUNCTION(sodium_crypto_kdf_derive_from_key)
  3036. {
  3037. unsigned char ctx_padded[crypto_generichash_blake2b_PERSONALBYTES];
  3038. #ifndef crypto_kdf_PRIMITIVE
  3039. unsigned char salt[crypto_generichash_blake2b_SALTBYTES];
  3040. #endif
  3041. char *ctx;
  3042. char *key;
  3043. zend_string *subkey;
  3044. zend_long subkey_id;
  3045. zend_long subkey_len;
  3046. size_t ctx_len;
  3047. size_t key_len;
  3048. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "llss",
  3049. &subkey_len,
  3050. &subkey_id,
  3051. &ctx, &ctx_len,
  3052. &key, &key_len) == FAILURE) {
  3053. sodium_remove_param_values_from_backtrace(EG(exception));
  3054. return;
  3055. }
  3056. if (subkey_len < crypto_kdf_BYTES_MIN) {
  3057. zend_throw_exception(sodium_exception_ce, "subkey cannot be smaller than SODIUM_CRYPTO_KDF_BYTES_MIN", 0);
  3058. return;
  3059. }
  3060. if (subkey_len > crypto_kdf_BYTES_MAX || subkey_len > SIZE_MAX) {
  3061. zend_throw_exception(sodium_exception_ce, "subkey cannot be larger than SODIUM_CRYPTO_KDF_BYTES_MAX", 0);
  3062. return;
  3063. }
  3064. if (subkey_id < 0) {
  3065. zend_throw_exception(sodium_exception_ce, "subkey_id cannot be negative", 0);
  3066. return;
  3067. }
  3068. if (ctx_len != crypto_kdf_CONTEXTBYTES) {
  3069. zend_throw_exception(sodium_exception_ce, "context should be SODIUM_CRYPTO_KDF_CONTEXTBYTES bytes", 0);
  3070. return;
  3071. }
  3072. if (key_len != crypto_kdf_KEYBYTES) {
  3073. zend_throw_exception(sodium_exception_ce, "key should be SODIUM_CRYPTO_KDF_KEYBYTES bytes", 0);
  3074. return;
  3075. }
  3076. memcpy(ctx_padded, ctx, crypto_kdf_CONTEXTBYTES);
  3077. memset(ctx_padded + crypto_kdf_CONTEXTBYTES, 0, sizeof ctx_padded - crypto_kdf_CONTEXTBYTES);
  3078. subkey = zend_string_alloc((size_t) subkey_len, 0);
  3079. #ifdef crypto_kdf_PRIMITIVE
  3080. crypto_kdf_derive_from_key((unsigned char *) ZSTR_VAL(subkey),
  3081. (size_t) subkey_len, (uint64_t) subkey_id,
  3082. ctx, (const unsigned char *) key);
  3083. #else
  3084. salt[0] = (unsigned char) (((uint64_t) subkey_id) );
  3085. salt[1] = (unsigned char) (((uint64_t) subkey_id) >> 8);
  3086. salt[2] = (unsigned char) (((uint64_t) subkey_id) >> 16);
  3087. salt[3] = (unsigned char) (((uint64_t) subkey_id) >> 24);
  3088. salt[4] = (unsigned char) (((uint64_t) subkey_id) >> 32);
  3089. salt[5] = (unsigned char) (((uint64_t) subkey_id) >> 40);
  3090. salt[6] = (unsigned char) (((uint64_t) subkey_id) >> 48);
  3091. salt[7] = (unsigned char) (((uint64_t) subkey_id) >> 56);
  3092. memset(salt + 8, 0, (sizeof salt) - 8);
  3093. crypto_generichash_blake2b_salt_personal((unsigned char *) ZSTR_VAL(subkey),
  3094. (size_t) subkey_len,
  3095. NULL, 0,
  3096. (const unsigned char *) key,
  3097. crypto_kdf_KEYBYTES,
  3098. salt, ctx_padded);
  3099. #endif
  3100. ZSTR_VAL(subkey)[subkey_len] = 0;
  3101. RETURN_STR(subkey);
  3102. }
  3103. PHP_FUNCTION(sodium_pad)
  3104. {
  3105. zend_string *padded;
  3106. char *unpadded;
  3107. zend_long blocksize;
  3108. volatile size_t st;
  3109. size_t i, j, k;
  3110. size_t unpadded_len;
  3111. size_t xpadlen;
  3112. size_t xpadded_len;
  3113. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sl",
  3114. &unpadded, &unpadded_len, &blocksize) == FAILURE) {
  3115. sodium_remove_param_values_from_backtrace(EG(exception));
  3116. return;
  3117. }
  3118. if (blocksize <= 0) {
  3119. zend_throw_exception(sodium_exception_ce, "block size cannot be less than 1", 0);
  3120. return;
  3121. }
  3122. if (blocksize > SIZE_MAX) {
  3123. zend_throw_exception(sodium_exception_ce, "block size is too large", 0);
  3124. return;
  3125. }
  3126. xpadlen = blocksize - 1U;
  3127. if ((blocksize & (blocksize - 1U)) == 0U) {
  3128. xpadlen -= unpadded_len & ((size_t) blocksize - 1U);
  3129. } else {
  3130. xpadlen -= unpadded_len % (size_t) blocksize;
  3131. }
  3132. if ((size_t) SIZE_MAX - unpadded_len <= xpadlen) {
  3133. zend_throw_exception(sodium_exception_ce, "input is too large", 0);
  3134. return;
  3135. }
  3136. xpadded_len = unpadded_len + xpadlen;
  3137. padded = zend_string_alloc(xpadded_len + 1U, 0);
  3138. if (unpadded_len > 0) {
  3139. st = 1U;
  3140. i = 0U;
  3141. k = unpadded_len;
  3142. for (j = 0U; j <= xpadded_len; j++) {
  3143. ZSTR_VAL(padded)[j] = unpadded[i];
  3144. k -= st;
  3145. st = (size_t) (~(((( (((uint64_t) k) >> 48) | (((uint64_t) k) >> 32) |
  3146. (k >> 16) | k) & 0xffff) - 1U) >> 16)) & 1U;
  3147. i += st;
  3148. }
  3149. }
  3150. #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6)
  3151. if (sodium_pad(NULL, (unsigned char *) ZSTR_VAL(padded), unpadded_len,
  3152. (size_t) blocksize, xpadded_len + 1U) != 0) {
  3153. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  3154. return;
  3155. }
  3156. #else
  3157. {
  3158. char *tail;
  3159. volatile unsigned char mask;
  3160. unsigned char barrier_mask;
  3161. tail = &ZSTR_VAL(padded)[xpadded_len];
  3162. mask = 0U;
  3163. for (i = 0; i < blocksize; i++) {
  3164. barrier_mask = (unsigned char)
  3165. (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT));
  3166. tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask);
  3167. mask |= barrier_mask;
  3168. }
  3169. }
  3170. #endif
  3171. ZSTR_VAL(padded)[xpadded_len + 1U] = 0;
  3172. RETURN_STR(padded);
  3173. }
  3174. PHP_FUNCTION(sodium_unpad)
  3175. {
  3176. zend_string *unpadded;
  3177. char *padded;
  3178. size_t padded_len;
  3179. size_t unpadded_len;
  3180. zend_long blocksize;
  3181. int ret;
  3182. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "sl",
  3183. &padded, &padded_len, &blocksize) == FAILURE) {
  3184. sodium_remove_param_values_from_backtrace(EG(exception));
  3185. return;
  3186. }
  3187. if (blocksize <= 0) {
  3188. zend_throw_exception(sodium_exception_ce, "block size cannot be less than 1", 0);
  3189. return;
  3190. }
  3191. if (blocksize > SIZE_MAX) {
  3192. zend_throw_exception(sodium_exception_ce, "block size is too large", 0);
  3193. return;
  3194. }
  3195. if (padded_len < blocksize) {
  3196. zend_throw_exception(sodium_exception_ce, "invalid padding", 0);
  3197. return;
  3198. }
  3199. #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6)
  3200. ret = sodium_unpad(&unpadded_len, (const unsigned char *) padded,
  3201. padded_len, (size_t) blocksize);
  3202. #else
  3203. {
  3204. const char *tail;
  3205. unsigned char acc = 0U;
  3206. unsigned char c;
  3207. unsigned char valid = 0U;
  3208. volatile size_t pad_len = 0U;
  3209. size_t i;
  3210. size_t is_barrier;
  3211. tail = &padded[padded_len - 1U];
  3212. for (i = 0U; i < (size_t) blocksize; i++) {
  3213. c = tail[-i];
  3214. is_barrier =
  3215. (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U;
  3216. acc |= c;
  3217. pad_len |= i & (1U + ~is_barrier);
  3218. valid |= (unsigned char) is_barrier;
  3219. }
  3220. unpadded_len = padded_len - 1U - pad_len;
  3221. ret = (int) (valid - 1U);
  3222. }
  3223. #endif
  3224. if (ret != 0 || unpadded_len > LONG_MAX) {
  3225. zend_throw_exception(sodium_exception_ce, "invalid padding", 0);
  3226. return;
  3227. }
  3228. unpadded = zend_string_init(padded, padded_len, 0);
  3229. PHP_SODIUM_ZSTR_TRUNCATE(unpadded, unpadded_len);
  3230. ZSTR_VAL(unpadded)[unpadded_len] = 0;
  3231. RETURN_STR(unpadded);
  3232. }
  3233. #ifdef crypto_secretstream_xchacha20poly1305_ABYTES
  3234. PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_keygen)
  3235. {
  3236. unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
  3237. if (zend_parse_parameters_none() == FAILURE) {
  3238. return;
  3239. }
  3240. randombytes_buf(key, sizeof key);
  3241. RETURN_STRINGL((const char *) key, sizeof key);
  3242. }
  3243. PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_init_push)
  3244. {
  3245. crypto_secretstream_xchacha20poly1305_state state;
  3246. unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
  3247. unsigned char *key;
  3248. size_t key_len;
  3249. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s",
  3250. &key, &key_len) == FAILURE) {
  3251. sodium_remove_param_values_from_backtrace(EG(exception));
  3252. return;
  3253. }
  3254. if (key_len != crypto_secretstream_xchacha20poly1305_KEYBYTES) {
  3255. zend_throw_exception(sodium_exception_ce,
  3256. "key size should be SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES bytes",
  3257. 0);
  3258. return;
  3259. }
  3260. if (crypto_secretstream_xchacha20poly1305_init_push(&state,
  3261. header, key) != 0) {
  3262. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  3263. return;
  3264. }
  3265. array_init(return_value);
  3266. add_next_index_stringl(return_value, (const char *) &state, sizeof state);
  3267. add_next_index_stringl(return_value, (const char *) header, sizeof header);
  3268. }
  3269. PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_push)
  3270. {
  3271. zval *state_zv;
  3272. zend_string *c;
  3273. unsigned char *ad = NULL;
  3274. unsigned char *msg;
  3275. unsigned char *state;
  3276. unsigned long long c_real_len;
  3277. zend_long tag = crypto_secretstream_xchacha20poly1305_TAG_MESSAGE;
  3278. size_t ad_len = (size_t) 0U;
  3279. size_t c_len;
  3280. size_t msg_len;
  3281. size_t state_len;
  3282. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zs|sl",
  3283. &state_zv,
  3284. &msg, &msg_len, &ad, &ad_len, &tag) == FAILURE) {
  3285. sodium_remove_param_values_from_backtrace(EG(exception));
  3286. return;
  3287. }
  3288. ZVAL_DEREF(state_zv);
  3289. if (Z_TYPE_P(state_zv) != IS_STRING) {
  3290. zend_throw_exception(sodium_exception_ce, "a reference to a state is required", 0);
  3291. return;
  3292. }
  3293. sodium_separate_string(state_zv);
  3294. state = (unsigned char *) Z_STRVAL(*state_zv);
  3295. state_len = Z_STRLEN(*state_zv);
  3296. if (state_len != sizeof (crypto_secretstream_xchacha20poly1305_state)) {
  3297. zend_throw_exception(sodium_exception_ce, "incorrect state length", 0);
  3298. return;
  3299. }
  3300. if (msg_len > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX ||
  3301. msg_len > SIZE_MAX - crypto_secretstream_xchacha20poly1305_ABYTES) {
  3302. zend_throw_exception(sodium_exception_ce, "message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes", 0);
  3303. return;
  3304. }
  3305. if (tag < 0 || tag > 255) {
  3306. zend_throw_exception(sodium_exception_ce, "unsupported value for the tag", 0);
  3307. return;
  3308. }
  3309. c_len = msg_len + crypto_secretstream_xchacha20poly1305_ABYTES;
  3310. c = zend_string_alloc((size_t) c_len, 0);
  3311. if (crypto_secretstream_xchacha20poly1305_push
  3312. ((void *) state, (unsigned char *) ZSTR_VAL(c), &c_real_len,
  3313. msg, (unsigned long long) msg_len, ad, (unsigned long long) ad_len,
  3314. (unsigned char) tag) != 0) {
  3315. zend_string_efree(c);
  3316. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  3317. return;
  3318. }
  3319. if (c_real_len <= 0U || c_real_len >= SIZE_MAX || c_real_len > c_len) {
  3320. zend_string_efree(c);
  3321. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  3322. return;
  3323. }
  3324. PHP_SODIUM_ZSTR_TRUNCATE(c, (size_t) c_real_len);
  3325. ZSTR_VAL(c)[c_real_len] = 0;
  3326. RETURN_NEW_STR(c);
  3327. }
  3328. PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_init_pull)
  3329. {
  3330. crypto_secretstream_xchacha20poly1305_state state;
  3331. unsigned char *header;
  3332. unsigned char *key;
  3333. size_t header_len;
  3334. size_t key_len;
  3335. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "ss",
  3336. &header, &header_len,
  3337. &key, &key_len) == FAILURE) {
  3338. sodium_remove_param_values_from_backtrace(EG(exception));
  3339. return;
  3340. }
  3341. if (header_len != crypto_secretstream_xchacha20poly1305_HEADERBYTES) {
  3342. zend_throw_exception(sodium_exception_ce,
  3343. "header size should be SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES bytes",
  3344. 0);
  3345. return;
  3346. }
  3347. if (key_len != crypto_secretstream_xchacha20poly1305_KEYBYTES) {
  3348. zend_throw_exception(sodium_exception_ce,
  3349. "key size should be SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES bytes",
  3350. 0);
  3351. return;
  3352. }
  3353. if (crypto_secretstream_xchacha20poly1305_init_pull(&state,
  3354. header, key) != 0) {
  3355. zend_throw_exception(sodium_exception_ce, "internal error", 0);
  3356. return;
  3357. }
  3358. RETURN_STRINGL((const char *) &state, sizeof state);
  3359. }
  3360. PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_pull)
  3361. {
  3362. zval *state_zv;
  3363. zend_string *msg;
  3364. unsigned char *ad = NULL;
  3365. unsigned char *c;
  3366. unsigned char *state;
  3367. unsigned long long msg_real_len;
  3368. size_t ad_len = (size_t) 0U;
  3369. size_t msg_len;
  3370. size_t c_len;
  3371. size_t state_len;
  3372. unsigned char tag;
  3373. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zs|s",
  3374. &state_zv,
  3375. &c, &c_len, &ad, &ad_len) == FAILURE) {
  3376. sodium_remove_param_values_from_backtrace(EG(exception));
  3377. return;
  3378. }
  3379. ZVAL_DEREF(state_zv);
  3380. if (Z_TYPE_P(state_zv) != IS_STRING) {
  3381. zend_throw_exception(sodium_exception_ce, "a reference to a state is required", 0);
  3382. return;
  3383. }
  3384. sodium_separate_string(state_zv);
  3385. state = (unsigned char *) Z_STRVAL(*state_zv);
  3386. state_len = Z_STRLEN(*state_zv);
  3387. if (state_len != sizeof (crypto_secretstream_xchacha20poly1305_state)) {
  3388. zend_throw_exception(sodium_exception_ce, "incorrect state length", 0);
  3389. return;
  3390. }
  3391. if (c_len < crypto_secretstream_xchacha20poly1305_ABYTES) {
  3392. RETURN_FALSE;
  3393. }
  3394. msg_len = c_len - crypto_secretstream_xchacha20poly1305_ABYTES;
  3395. msg = zend_string_alloc((size_t) msg_len, 0);
  3396. if (crypto_secretstream_xchacha20poly1305_pull
  3397. ((void *) state, (unsigned char *) ZSTR_VAL(msg), &msg_real_len, &tag,
  3398. c, (unsigned long long) c_len, ad, (unsigned long long) ad_len) != 0) {
  3399. zend_string_efree(msg);
  3400. RETURN_FALSE;
  3401. }
  3402. if (msg_real_len >= SIZE_MAX || msg_real_len > msg_len) {
  3403. zend_string_efree(msg);
  3404. zend_throw_exception(sodium_exception_ce, "arithmetic overflow", 0);
  3405. return;
  3406. }
  3407. PHP_SODIUM_ZSTR_TRUNCATE(msg, (size_t) msg_real_len);
  3408. ZSTR_VAL(msg)[msg_real_len] = 0;
  3409. array_init(return_value);
  3410. add_next_index_str(return_value, msg);
  3411. add_next_index_long(return_value, (long) tag);
  3412. }
  3413. PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_rekey)
  3414. {
  3415. zval *state_zv;
  3416. unsigned char *state;
  3417. size_t state_len;
  3418. if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "z", &state_zv) == FAILURE) {
  3419. sodium_remove_param_values_from_backtrace(EG(exception));
  3420. return;
  3421. }
  3422. ZVAL_DEREF(state_zv);
  3423. if (Z_TYPE_P(state_zv) != IS_STRING) {
  3424. zend_throw_exception(sodium_exception_ce, "a reference to a state is required", 0);
  3425. return;
  3426. }
  3427. sodium_separate_string(state_zv);
  3428. state = (unsigned char *) Z_STRVAL(*state_zv);
  3429. state_len = Z_STRLEN(*state_zv);
  3430. if (state_len != sizeof (crypto_secretstream_xchacha20poly1305_state)) {
  3431. zend_throw_exception(sodium_exception_ce, "incorrect state length", 0);
  3432. return;
  3433. }
  3434. crypto_secretstream_xchacha20poly1305_rekey((void *) state);
  3435. }
  3436. #endif
  3437. /*
  3438. * Local variables:
  3439. * tab-width: 4
  3440. * c-basic-offset: 4
  3441. * End:
  3442. * vim600: sw=4 ts=4 tw=78 fdm=marker
  3443. * vim<600: sw=4 ts=4 tw=78
  3444. */