quickassist_sync.c 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008
  1. /* quickassist_sync.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/types.h>
  25. #ifdef HAVE_INTEL_QA_SYNC
  26. #ifdef QAT_DEMO_MAIN
  27. #define QAT_DEBUG
  28. #endif
  29. #include <wolfssl/internal.h>
  30. #include <wolfssl/error-ssl.h>
  31. #include <wolfssl/wolfcrypt/error-crypt.h>
  32. #ifndef NO_AES
  33. #include <wolfssl/wolfcrypt/aes.h>
  34. #endif
  35. #include <wolfssl/wolfcrypt/cryptocb.h>
  36. #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
  37. #include "cpa.h"
  38. #include "cpa_cy_im.h"
  39. #include "cpa_cy_sym.h"
  40. #include "cpa_cy_rsa.h"
  41. #include "cpa_cy_ln.h"
  42. #include "cpa_cy_ecdh.h"
  43. #include "cpa_cy_ecdsa.h"
  44. #include "cpa_cy_dh.h"
  45. #include "cpa_cy_drbg.h"
  46. #include "cpa_cy_nrbg.h"
  47. #include "cpa_cy_prime.h"
  48. #include "icp_sal_user.h"
  49. #include "icp_sal_poll.h"
  50. #ifdef NO_INLINE
  51. #include <wolfssl/wolfcrypt/misc.h>
  52. #else
  53. #define WOLFSSL_MISC_INCLUDED
  54. #include <wolfcrypt/src/misc.c>
  55. #endif
  56. /* User space utils */
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <string.h>
  60. #include <errno.h>
  61. #if 0
  62. /* Optional feature for partial QAT hashing support */
  63. /* This will process updates through hardware instead of caching them */
  64. #define QAT_HASH_ENABLE_PARTIAL
  65. #endif
  66. #ifdef QAT_HASH_ENABLE_PARTIAL
  67. #define MAX_QAT_HASH_BUFFERS 2
  68. #endif
  69. /* Detect QAT driver version */
  70. #if defined(CPA_CY_API_VERSION_NUM_MAJOR) && CPA_CY_API_VERSION_NUM_MAJOR > 1
  71. #define QAT_V2
  72. #endif
  73. #ifdef QAT_V2
  74. /* quickassist/utilities/libusdm_drv/qae_mem.h */
  75. /* Provides user-space API's for accessing NUMA allocated memory through usdm_drv */
  76. #include "qae_mem.h"
  77. #include "linux/include/qae_mem_utils.h"
  78. #endif
  79. #ifdef QAT_USE_POLLING_THREAD
  80. #include <pthread.h>
  81. #endif
  82. /* Tunable parameters */
  83. #ifndef QAT_PROCESS_NAME
  84. #define QAT_PROCESS_NAME "SSL"
  85. #endif
  86. #ifndef QAT_LIMIT_DEV_ACCESS
  87. #define QAT_LIMIT_DEV_ACCESS CPA_FALSE
  88. #endif
  89. #ifndef QAT_MAX_DEVICES
  90. #define QAT_MAX_DEVICES (1) /* maximum number of QAT cards */
  91. #endif
  92. #ifndef QAT_RETRY_LIMIT
  93. #define QAT_RETRY_LIMIT (100)
  94. #endif
  95. #ifndef QAT_POLL_RESP_QUOTA
  96. #define QAT_POLL_RESP_QUOTA (0) /* all pending */
  97. #endif
  98. #if !defined(NO_AES) || !defined(NO_DES3)
  99. #define QAT_ENABLE_CRYPTO
  100. #endif
  101. /* Pre-declarations */
  102. struct IntelQaDev;
  103. struct wc_CryptoInfo;
  104. struct WC_BIGINT;
  105. struct WC_RNG;
  106. #if defined(QAT_ENABLE_HASH) || defined(QAT_ENABLE_CRYPTO)
  107. /* symmetric context */
  108. typedef struct IntelQaSymCtx {
  109. CpaCySymOpData opData;
  110. CpaCySymSessionCtx symCtxSrc;
  111. CpaCySymSessionCtx symCtx;
  112. word32 symCtxSize;
  113. /* flags */
  114. word32 isOpen:1;
  115. word32 isCopy:1;
  116. } IntelQaSymCtx;
  117. #endif
  118. typedef void (*IntelQaFreeFunc)(struct IntelQaDev*);
  119. /* QuickAssist device */
  120. typedef struct IntelQaDev {
  121. CpaInstanceHandle handle;
  122. int devId;
  123. void* heap;
  124. /* callback return info */
  125. int ret;
  126. byte* out;
  127. union {
  128. word32* outLenPtr;
  129. word32 outLen;
  130. };
  131. /* operations */
  132. IntelQaFreeFunc freeFunc;
  133. union {
  134. #ifdef QAT_ENABLE_CRYPTO
  135. struct {
  136. IntelQaSymCtx ctx;
  137. CpaBufferList bufferList;
  138. CpaFlatBuffer flatBuffer;
  139. byte* authTag;
  140. word32 authTagSz;
  141. } cipher;
  142. #endif
  143. } op;
  144. #ifdef QAT_USE_POLLING_THREAD
  145. pthread_t pollingThread;
  146. byte pollingCy;
  147. #endif
  148. } IntelQaDev;
  149. /* Interface */
  150. static int IntelQaHardwareStart(const char*, int);
  151. static void IntelQaHardwareStop(void);
  152. static int IntelQaInit(void*);
  153. static void IntelQaDeInit(int);
  154. static int IntelQaNumInstances(void);
  155. static int IntelQaOpen(IntelQaDev*, int);
  156. static void IntelQaClose(IntelQaDev*);
  157. static int IntelQaDevCopy(IntelQaDev*, IntelQaDev*);
  158. static int IntelQaPoll(IntelQaDev*);
  159. static int IntelQaGetCyInstanceCount(void);
  160. #ifndef NO_AES
  161. #ifdef HAVE_AES_CBC
  162. static int IntelQaSymAesCbcEncrypt(IntelQaDev*, byte*,
  163. const byte*, word32, const byte*, word32, const byte*, word32);
  164. #ifdef HAVE_AES_DECRYPT
  165. static int IntelQaSymAesCbcDecrypt(IntelQaDev*, byte*,
  166. const byte*, word32, const byte*, word32, const byte*, word32);
  167. #endif /* HAVE_AES_DECRYPT */
  168. #endif /* HAVE_AES_CBC */
  169. #ifdef HAVE_AESGCM
  170. static int IntelQaSymAesGcmEncrypt(IntelQaDev*, byte*,
  171. const byte*, word32, const byte*, word32, const byte*, word32,
  172. byte*, word32, const byte*, word32);
  173. #ifdef HAVE_AES_DECRYPT
  174. static int IntelQaSymAesGcmDecrypt(IntelQaDev*, byte*,
  175. const byte*, word32, const byte*, word32, const byte*, word32,
  176. const byte*, word32, const byte*, word32);
  177. #endif /* HAVE_AES_DECRYPT */
  178. #endif /* HAVE_AESGCM */
  179. #endif /* !NO_AES */
  180. #ifndef NO_DES3
  181. static int IntelQaSymDes3CbcEncrypt(IntelQaDev*, byte*,
  182. const byte*, word32, const byte*, word32, const byte* iv, word32);
  183. static int IntelQaSymDes3CbcDecrypt(IntelQaDev* dev, byte*,
  184. const byte*, word32, const byte*, word32, const byte* iv, word32);
  185. #endif /*! NO_DES3 */
  186. #ifdef WOLF_CRYPTO_CB
  187. static int IntelQaSymSync_CryptoDevCb(int, struct wc_CryptoInfo*,
  188. void*);
  189. #endif /* WOLF_CRYPTO_CB */
  190. #ifdef QAT_DEBUG
  191. #define QLOG(...) do { printf(__VA_ARGS__); } while (0)
  192. #else
  193. #define QLOG(...) WC_DO_NOTHING
  194. #endif
  195. #define OS_HOST_TO_NW_32(uData) ByteReverseWord32(uData)
  196. static CpaInstanceHandle* g_cyInstances = NULL;
  197. static CpaInstanceInfo2* g_cyInstanceInfo = NULL;
  198. static Cpa32U* g_cyInstMap = NULL;
  199. static Cpa16U g_numInstances = 0;
  200. static Cpa16U g_instCounter = 0;
  201. static CpaBoolean g_cyServiceStarted = CPA_FALSE;
  202. #ifdef QAT_USE_POLLING_CHECK
  203. static CpaBoolean* g_cyPolling = NULL;
  204. static pthread_mutex_t* g_PollLock;
  205. #endif
  206. static volatile int g_initCount = 0;
  207. static pthread_mutex_t g_Hwlock = PTHREAD_MUTEX_INITIALIZER;
  208. typedef struct qatCapabilities {
  209. /* capabilities */
  210. word32 supPartial:1;
  211. word32 supSha3:1;
  212. } qatCapabilities_t;
  213. static qatCapabilities_t g_qatCapabilities = {0};
  214. #if defined(QAT_ENABLE_CRYPTO)
  215. static int IntelQaSymClose(IntelQaDev* dev, int doFree);
  216. #endif
  217. extern Cpa32U osalLogLevelSet(Cpa32U level);
  218. static IntelQaDev qaDev;
  219. /* -------------------------------------------------------------------------- */
  220. /* Polling */
  221. /* -------------------------------------------------------------------------- */
  222. static WC_INLINE int SyncSleep(word32 ms)
  223. {
  224. int ret = 0;
  225. struct timespec resTime, remTime;
  226. resTime.tv_sec = ms/1000;
  227. resTime.tv_nsec = (ms%1000)*1000000;
  228. do {
  229. ret = nanosleep(&resTime, &remTime);
  230. resTime = remTime;
  231. } while ((ret!=0) && (errno == EINTR));
  232. if (ret != 0) {
  233. QLOG("nanoSleep failed with code %d\n", ret);
  234. return BAD_FUNC_ARG;
  235. }
  236. return ret;
  237. }
  238. #ifdef QAT_USE_POLLING_THREAD
  239. static void* IntelQaPollingThread(void* context)
  240. {
  241. IntelQaDev* dev = (IntelQaDev*)context;
  242. QLOG("Polling Thread Start\n");
  243. while (dev->pollingCy) {
  244. icp_sal_CyPollInstance(dev->handle, QAT_POLL_RESP_QUOTA);
  245. SyncSleep(10);
  246. }
  247. QLOG("Polling Thread Exit\n");
  248. pthread_exit(NULL);
  249. }
  250. static CpaStatus IntelQaStartPollingThread(IntelQaDev* dev)
  251. {
  252. if (dev->pollingCy == 0) {
  253. dev->pollingCy = 1;
  254. QLOG("Polling Thread Created\n");
  255. if (pthread_create(&dev->pollingThread, NULL, IntelQaPollingThread,
  256. (void*)dev) != 0) {
  257. QLOG("Failed create polling thread!\n");
  258. return CPA_STATUS_FAIL;
  259. }
  260. }
  261. return CPA_STATUS_SUCCESS;
  262. }
  263. static void IntelQaStopPollingThread(IntelQaDev* dev)
  264. {
  265. dev->pollingCy = 0;
  266. pthread_join(dev->pollingThread, 0);
  267. }
  268. #endif /* QAT_USE_POLLING_THREAD */
  269. /* -------------------------------------------------------------------------- */
  270. /* Device */
  271. /* -------------------------------------------------------------------------- */
  272. void IntelQaHardwareStop(void)
  273. {
  274. int i;
  275. CpaStatus status;
  276. g_initCount--; /* track de-init count */
  277. if (g_initCount != 0) {
  278. return;
  279. }
  280. if (g_cyServiceStarted == CPA_TRUE) {
  281. g_cyServiceStarted = CPA_FALSE;
  282. for (i=0; i<g_numInstances; i++) {
  283. status = cpaCyStopInstance(g_cyInstances[i]);
  284. if (status != CPA_STATUS_SUCCESS) {
  285. QLOG("IntelQA: Could not stop instance: %d\n"
  286. "\tInternal error has occur which probably can only be"
  287. "fixed by a reboot\n", i);
  288. }
  289. }
  290. }
  291. status = icp_sal_userStop();
  292. if (status != CPA_STATUS_SUCCESS) {
  293. QLOG("IntelQA: Could not stop sal for user space (status %d)\n",
  294. status);
  295. }
  296. if (g_cyInstMap) {
  297. XFREE(g_cyInstMap, NULL, DYNAMIC_TYPE_ASYNC);
  298. g_cyInstMap = NULL;
  299. }
  300. if (g_cyInstanceInfo) {
  301. XFREE(g_cyInstanceInfo, NULL, DYNAMIC_TYPE_ASYNC);
  302. g_cyInstanceInfo = NULL;
  303. }
  304. #ifdef QAT_USE_POLLING_CHECK
  305. if (g_cyPolling) {
  306. XFREE(g_cyPolling, NULL, DYNAMIC_TYPE_ASYNC);
  307. g_cyPolling = NULL;
  308. }
  309. if (g_PollLock) {
  310. for (i=0; i<g_numInstances; i++) {
  311. pthread_mutex_destroy(&g_PollLock[i]);
  312. }
  313. XFREE(g_PollLock, NULL, DYNAMIC_TYPE_ASYNC);
  314. g_PollLock = NULL;
  315. }
  316. #endif
  317. if (g_cyInstances) {
  318. XFREE(g_cyInstances, NULL, DYNAMIC_TYPE_ASYNC);
  319. g_cyInstances = NULL;
  320. g_numInstances = 0;
  321. }
  322. qaeMemDestroy();
  323. QLOG("IntelQA: Stop\n");
  324. }
  325. int IntelQaHardwareStart(const char* process_name, int limitDevAccess)
  326. {
  327. int ret = 0, i;
  328. CpaStatus status;
  329. g_initCount++;
  330. if (g_initCount > 1) {
  331. return 0;
  332. }
  333. status = qaeMemInit();
  334. if (status != CPA_STATUS_SUCCESS) {
  335. QLOG("IntelQA: Could not start qae mem for user space (status %d)\n"
  336. "\tHas the qaeMemDrv.ko module been loaded?\n",
  337. status);
  338. return ASYNC_INIT_E;
  339. }
  340. status = icp_sal_userStartMultiProcess(process_name,
  341. limitDevAccess ? CPA_TRUE : CPA_FALSE);
  342. if (status != CPA_STATUS_SUCCESS) {
  343. QLOG("IntelQA: Could not start sal for user space! status %d\n",
  344. status);
  345. ret = ASYNC_INIT_E; goto error;
  346. }
  347. #ifdef QAT_DEBUG
  348. /* optionally enable debugging */
  349. //osalLogLevelSet(8);
  350. #endif
  351. status = cpaCyGetNumInstances(&g_numInstances);
  352. if (status != CPA_STATUS_SUCCESS || g_numInstances == 0) {
  353. QLOG("IntelQA: Failed to get num of instances! status %d\n", status);
  354. ret = INVALID_DEVID; goto error;
  355. }
  356. /* Get handles / info */
  357. g_cyInstances = (CpaInstanceHandle*)XMALLOC(
  358. sizeof(CpaInstanceHandle) * g_numInstances, NULL, DYNAMIC_TYPE_ASYNC);
  359. if (g_cyInstances == NULL) {
  360. QLOG("IntelQA: Failed to allocate instances\n");
  361. ret = INVALID_DEVID; goto error;
  362. }
  363. #ifdef QAT_USE_POLLING_CHECK
  364. g_cyPolling = (CpaBoolean*)XMALLOC(sizeof(CpaBoolean) * g_numInstances, NULL,
  365. DYNAMIC_TYPE_ASYNC);
  366. if (g_cyPolling == NULL) {
  367. QLOG("IntelQA: Failed to allocate polling status\n");
  368. ret = INVALID_DEVID; goto error;
  369. }
  370. g_PollLock = (pthread_mutex_t*)XMALLOC(sizeof(pthread_mutex_t) *
  371. g_numInstances, NULL, DYNAMIC_TYPE_ASYNC);
  372. if (g_PollLock == NULL) {
  373. QLOG("IntelQA: Failed to allocate polling locks\n");
  374. ret = INVALID_DEVID; goto error;
  375. }
  376. for (i=0; i<g_numInstances; i++) {
  377. pthread_mutex_init(&g_PollLock[i], NULL);
  378. }
  379. #endif
  380. g_cyInstanceInfo = (CpaInstanceInfo2*)XMALLOC(
  381. sizeof(CpaInstanceInfo2) * g_numInstances, NULL, DYNAMIC_TYPE_ASYNC);
  382. if (g_cyInstanceInfo == NULL) {
  383. QLOG("IntelQA: Failed to allocate instance info\n");
  384. ret = INVALID_DEVID; goto error;
  385. }
  386. g_cyInstMap = (Cpa32U*)XMALLOC(
  387. sizeof(Cpa32U) * g_numInstances, NULL, DYNAMIC_TYPE_ASYNC);
  388. if (g_cyInstMap == NULL) {
  389. QLOG("IntelQA: Failed to allocate instance map\n");
  390. ret = INVALID_DEVID; goto error;
  391. }
  392. status = cpaCyGetInstances(g_numInstances, g_cyInstances);
  393. if (status != CPA_STATUS_SUCCESS) {
  394. QLOG("IntelQA: Failed to get IntelQA instances\n");
  395. ret = INVALID_DEVID; goto error;
  396. }
  397. /* start all instances */
  398. g_cyServiceStarted = CPA_TRUE;
  399. for (i=0; i<g_numInstances; i++) {
  400. Cpa32U coreAffinity = 0;
  401. CpaCySymCapabilitiesInfo capabilities;
  402. int j;
  403. XMEMSET(&capabilities, 0, sizeof(capabilities));
  404. status = cpaCyInstanceGetInfo2(g_cyInstances[i],
  405. &g_cyInstanceInfo[i]);
  406. if (status != CPA_STATUS_SUCCESS) {
  407. QLOG("IntelQA: Error getting instance info for %d\n", i);
  408. ret = INVALID_DEVID; goto error;
  409. }
  410. /* loop of the instanceInfo coreAffinity bitmask to find the core */
  411. for (j=0; j<CPA_MAX_CORES; j++) {
  412. if (CPA_BITMAP_BIT_TEST(g_cyInstanceInfo[i].coreAffinity, j)) {
  413. coreAffinity = i;
  414. break;
  415. }
  416. }
  417. g_cyInstMap[i] = coreAffinity;
  418. /* capabilities */
  419. status = cpaCySymQueryCapabilities(g_cyInstances[i], &capabilities);
  420. if (status == CPA_STATUS_SUCCESS) {
  421. g_qatCapabilities.supPartial = capabilities.partialPacketSupported;
  422. if (capabilities.partialPacketSupported != CPA_TRUE) {
  423. QLOG("Warning: QAT does not support partial packets!\n");
  424. }
  425. }
  426. QLOG("Inst %d, Node: %d, Affin: %u, Dev: %u, Accel %u, "
  427. "EE %u, BDF %02X:%02X:%02X, isPolled %d\n",
  428. i, g_cyInstanceInfo[i].nodeAffinity, coreAffinity,
  429. g_cyInstanceInfo[i].physInstId.packageId,
  430. g_cyInstanceInfo[i].physInstId.acceleratorId,
  431. g_cyInstanceInfo[i].physInstId.executionEngineId,
  432. (Cpa8U)((g_cyInstanceInfo[i].physInstId.busAddress) >> 8),
  433. (Cpa8U)((g_cyInstanceInfo[i].physInstId.busAddress)
  434. & 0xFF) >> 3,
  435. (Cpa8U)((g_cyInstanceInfo[i].physInstId.busAddress) & 3),
  436. g_cyInstanceInfo[i].isPolled);
  437. status = cpaCySetAddressTranslation(g_cyInstances[i],
  438. qaeVirtToPhysNUMA);
  439. if (status != CPA_STATUS_SUCCESS) {
  440. QLOG("IntelQA: Error setting memory config for inst %d\n", i);
  441. ret = INVALID_DEVID; goto error;
  442. }
  443. status = cpaCyStartInstance(g_cyInstances[i]);
  444. if (status != CPA_STATUS_SUCCESS) {
  445. QLOG("IntelQA: Error starting crypto instance %d\n", i);
  446. ret = INVALID_DEVID; goto error;
  447. }
  448. }
  449. QLOG("IntelQA: Instances %d\n", g_numInstances);
  450. return ret;
  451. error:
  452. IntelQaHardwareStop();
  453. return ret;
  454. }
  455. int IntelQaInit(void* threadId)
  456. {
  457. int ret;
  458. int devId;
  459. (void)threadId;
  460. ret = pthread_mutex_lock(&g_Hwlock);
  461. if (ret != 0) {
  462. QLOG("IntelQaInit: mutex lock failed! %d\n", ret);
  463. return BAD_MUTEX_E;
  464. }
  465. ret = IntelQaHardwareStart(QAT_PROCESS_NAME, QAT_LIMIT_DEV_ACCESS);
  466. if (ret != 0) {
  467. pthread_mutex_unlock(&g_Hwlock);
  468. return ret;
  469. }
  470. if (g_numInstances <= 0) {
  471. pthread_mutex_unlock(&g_Hwlock);
  472. return ASYNC_INIT_E;
  473. }
  474. /* assign device id */
  475. devId = (g_instCounter % g_numInstances);
  476. g_instCounter++;
  477. pthread_mutex_unlock(&g_Hwlock);
  478. return devId;
  479. }
  480. int IntelQaNumInstances(void)
  481. {
  482. return g_numInstances;
  483. }
  484. int IntelQaOpen(IntelQaDev* dev, int devId)
  485. {
  486. if (dev == NULL) {
  487. return BAD_FUNC_ARG;
  488. }
  489. /* clear device info */
  490. XMEMSET(dev, 0, sizeof(IntelQaDev));
  491. if (g_cyInstances == NULL) {
  492. QLOG("IntelQA not initialized\n");
  493. return ASYNC_INIT_E;
  494. }
  495. dev->devId = devId;
  496. dev->handle = g_cyInstances[devId];
  497. #ifdef QAT_USE_POLLING_THREAD
  498. /* start polling thread */
  499. IntelQaStartPollingThread(dev);
  500. #endif
  501. return 0;
  502. }
  503. #if defined(QAT_ENABLE_CRYPTO)
  504. static IntelQaSymCtx* IntelQaGetSymCtx(IntelQaDev* dev)
  505. {
  506. return &dev->op.cipher.ctx;
  507. }
  508. #endif
  509. void IntelQaClose(IntelQaDev* dev)
  510. {
  511. if (dev) {
  512. QLOG("IntelQaClose %p\n", dev);
  513. /* close any active session */
  514. IntelQaSymClose(dev, 1);
  515. #ifdef QAT_USE_POLLING_THREAD
  516. IntelQaStopPollingThread(dev);
  517. #endif
  518. dev->handle = NULL;
  519. }
  520. }
  521. void IntelQaDeInit(int devId)
  522. {
  523. (void)devId;
  524. if (pthread_mutex_lock(&g_Hwlock) == 0) {
  525. IntelQaHardwareStop();
  526. pthread_mutex_unlock(&g_Hwlock);
  527. }
  528. }
  529. int IntelQaPoll(IntelQaDev* dev)
  530. {
  531. int ret = 0;
  532. CpaStatus status;
  533. #ifdef QAT_USE_POLLING_CHECK
  534. pthread_mutex_t* lock = &g_PollLock[dev->qat.devId];
  535. if (pthread_mutex_lock(lock) == 0) {
  536. /* test if any other threads are polling */
  537. if (g_cyPolling[dev->qat.devId]) {
  538. pthread_mutex_unlock(lock);
  539. /* return success even though its busy, caller will treat as WC_PENDING_E */
  540. return 0;
  541. }
  542. g_cyPolling[dev->qat.devId] = 1;
  543. pthread_mutex_unlock(lock);
  544. }
  545. #endif
  546. status = icp_sal_CyPollInstance(dev->handle, QAT_POLL_RESP_QUOTA);
  547. if (status != CPA_STATUS_SUCCESS && status != CPA_STATUS_RETRY) {
  548. QLOG("IntelQa: Poll failure %d\n", status);
  549. ret = -1;
  550. }
  551. {
  552. if (dev->ret != WC_PENDING_E) {
  553. /* perform cleanup */
  554. IntelQaFreeFunc freeFunc = dev->freeFunc;
  555. QLOG("IntelQaOpFree: Dev %p, FreeFunc %p\n", dev, freeFunc);
  556. if (freeFunc) {
  557. dev->freeFunc = NULL;
  558. freeFunc(dev);
  559. }
  560. }
  561. }
  562. #ifdef QAT_USE_POLLING_CHECK
  563. /* indicate we are done polling */
  564. if (pthread_mutex_lock(lock) == 0) {
  565. g_cyPolling[dev->qat.devId] = 0;
  566. pthread_mutex_unlock(lock);
  567. }
  568. #endif
  569. return ret;
  570. }
  571. static int IntelQaPollBlockRet(IntelQaDev* dev, int ret_wait)
  572. {
  573. int ret;
  574. do {
  575. ret = IntelQaPoll(dev);
  576. if (dev->ret != ret_wait) {
  577. break;
  578. }
  579. } while (1);
  580. ret = dev->ret;
  581. return ret;
  582. }
  583. int IntelQaGetCyInstanceCount(void)
  584. {
  585. return g_numInstances;
  586. }
  587. static WC_INLINE int IntelQaHandleCpaStatus(IntelQaDev* dev, CpaStatus status,
  588. int* ret, byte isAsync, void* callback, int* retryCount)
  589. {
  590. int retry = 0;
  591. if (status == CPA_STATUS_SUCCESS) {
  592. if (isAsync && callback) {
  593. *ret = WC_PENDING_E;
  594. }
  595. else {
  596. *ret = IntelQaPollBlockRet(dev, WC_PENDING_E);
  597. }
  598. }
  599. else if (status == CPA_STATUS_RETRY) {
  600. (*retryCount)++;
  601. if ((*retryCount % (QAT_RETRY_LIMIT + 1)) == QAT_RETRY_LIMIT) {
  602. SyncSleep(10);
  603. }
  604. retry = 1;
  605. }
  606. else {
  607. *ret = ASYNC_OP_E;
  608. }
  609. return retry;
  610. }
  611. static WC_INLINE void IntelQaOpInit(IntelQaDev* dev, IntelQaFreeFunc freeFunc)
  612. {
  613. dev->ret = WC_PENDING_E;
  614. dev->freeFunc = freeFunc;
  615. }
  616. /* -------------------------------------------------------------------------- */
  617. /* Symmetric Algos */
  618. /* -------------------------------------------------------------------------- */
  619. #if defined(QAT_ENABLE_CRYPTO)
  620. static int IntelQaSymOpen(IntelQaDev* dev, CpaCySymSessionSetupData* setup,
  621. CpaCySymCbFunc callback)
  622. {
  623. int ret = 0;
  624. CpaStatus status = CPA_STATUS_SUCCESS;
  625. Cpa32U sessionCtxSize = 0;
  626. IntelQaSymCtx* ctx;
  627. /* arg check */
  628. if (dev == NULL || setup == NULL) {
  629. return BAD_FUNC_ARG;
  630. }
  631. ctx = IntelQaGetSymCtx(dev);
  632. /* Determine size of session context to allocate - use max size */
  633. status = cpaCySymSessionCtxGetSize(dev->handle, setup, &sessionCtxSize);
  634. if (ctx->symCtxSize > 0 && ctx->symCtxSize > sessionCtxSize) {
  635. QLOG("Symmetric context size error! Buf %d, Exp %d\n",
  636. ctx->symCtxSize, sessionCtxSize);
  637. return ASYNC_OP_E;
  638. }
  639. /* make sure session context is allocated */
  640. if (ctx->symCtx == NULL) {
  641. /* Allocate session context */
  642. ctx->symCtx = XMALLOC(sessionCtxSize, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA64);
  643. if (ctx->symCtx == NULL) {
  644. return MEMORY_E;
  645. }
  646. }
  647. ctx->symCtxSize = sessionCtxSize;
  648. if (!ctx->isOpen) {
  649. ctx->isOpen = 1;
  650. QLOG("IntelQaSymOpen: InitSession dev %p, symCtx %p\n",
  651. dev, ctx->symCtx);
  652. /* open symmetric session */
  653. status = cpaCySymInitSession(dev->handle, callback, setup, ctx->symCtx);
  654. if (status != CPA_STATUS_SUCCESS) {
  655. QLOG("cpaCySymInitSession failed! dev %p, status %d\n",
  656. dev, status);
  657. XFREE(ctx->symCtx, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA64);
  658. ctx->symCtx = NULL;
  659. return ASYNC_INIT_E;
  660. }
  661. }
  662. if (ctx->symCtxSrc == NULL) {
  663. ctx->symCtxSrc = ctx->symCtx;
  664. }
  665. QLOG("IntelQaSymOpen: dev %p, symCtx %p (src %p), "
  666. "symCtxSize %d, isCopy %d, isOpen %d\n",
  667. dev, ctx->symCtx, ctx->symCtxSrc, ctx->symCtxSize,
  668. ctx->isCopy, ctx->isOpen);
  669. return ret;
  670. }
  671. static int IntelQaSymClose(IntelQaDev* dev, int doFree)
  672. {
  673. int ret = 0;
  674. CpaStatus status = CPA_STATUS_SUCCESS;
  675. IntelQaSymCtx* ctx;
  676. if (dev == NULL) {
  677. return BAD_FUNC_ARG;
  678. }
  679. ctx = IntelQaGetSymCtx(dev);
  680. QLOG("IntelQaSymClose: dev %p, ctx %p, symCtx %p (src %p), "
  681. "symCtxSize %d, isCopy %d, isOpen %d, doFree %d\n",
  682. dev, ctx, ctx->symCtx, ctx->symCtxSrc, ctx->symCtxSize,
  683. ctx->isCopy, ctx->isOpen, doFree);
  684. if (ctx->symCtx == ctx->symCtxSrc && ctx->symCtx != NULL) {
  685. if (ctx->isOpen) {
  686. ctx->isOpen = 0;
  687. QLOG("IntelQaSymClose: RemoveSession dev %p, symCtx %p\n",
  688. dev, ctx->symCtx);
  689. status = cpaCySymRemoveSession(dev->handle, ctx->symCtx);
  690. if (status == CPA_STATUS_RETRY) {
  691. QLOG("cpaCySymRemoveSession retry!\n");
  692. /* treat this as error, since session should not be active */
  693. ret = ASYNC_OP_E;
  694. }
  695. else if (status != CPA_STATUS_SUCCESS) {
  696. QLOG("cpaCySymRemoveSession failed! status %d\n", status);
  697. ret = ASYNC_OP_E;
  698. }
  699. }
  700. }
  701. if (doFree) {
  702. XFREE(ctx->symCtx, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA64);
  703. ctx->symCtx = NULL;
  704. ctx->symCtxSrc = NULL;
  705. ctx->symCtxSize = 0;
  706. }
  707. return ret;
  708. }
  709. #endif /* QAT_ENABLE_CRYPTO */
  710. /* -------------------------------------------------------------------------- */
  711. /* AES/DES Algo */
  712. /* -------------------------------------------------------------------------- */
  713. #ifdef QAT_ENABLE_CRYPTO
  714. static void IntelQaSymCipherFree(IntelQaDev* dev)
  715. {
  716. IntelQaSymCtx* ctx = &dev->op.cipher.ctx;
  717. CpaCySymOpData* opData = &ctx->opData;
  718. CpaBufferList* pDstBuffer = &dev->op.cipher.bufferList;
  719. if (opData) {
  720. if (opData->pAdditionalAuthData) {
  721. XFREE(opData->pAdditionalAuthData, dev->heap,
  722. DYNAMIC_TYPE_ASYNC_NUMA);
  723. opData->pAdditionalAuthData = NULL;
  724. }
  725. if (opData->pIv) {
  726. XFREE(opData->pIv, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
  727. opData->pIv = NULL;
  728. }
  729. XMEMSET(opData, 0, sizeof(CpaCySymOpData));
  730. }
  731. if (pDstBuffer) {
  732. if (pDstBuffer->pBuffers) {
  733. if (pDstBuffer->pBuffers->pData) {
  734. XFREE(pDstBuffer->pBuffers->pData, dev->heap,
  735. DYNAMIC_TYPE_ASYNC_NUMA);
  736. pDstBuffer->pBuffers->pData = NULL;
  737. }
  738. XMEMSET(pDstBuffer->pBuffers, 0, sizeof(CpaFlatBuffer));
  739. }
  740. if (pDstBuffer->pPrivateMetaData) {
  741. XFREE(pDstBuffer->pPrivateMetaData, dev->heap,
  742. DYNAMIC_TYPE_ASYNC_NUMA);
  743. pDstBuffer->pPrivateMetaData = NULL;
  744. }
  745. XMEMSET(pDstBuffer, 0, sizeof(CpaBufferList));
  746. }
  747. /* close and free sym context */
  748. IntelQaSymClose(dev, 1);
  749. /* clear temp pointers */
  750. dev->out = NULL;
  751. dev->outLen = 0;
  752. #ifndef NO_AES
  753. if (dev->op.cipher.authTag != NULL) {
  754. XMEMSET(dev->op.cipher.authTag, 0, dev->op.cipher.authTagSz);
  755. XFREE(dev->op.cipher.authTag, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
  756. dev->op.cipher.authTag = NULL;
  757. }
  758. dev->op.cipher.authTagSz = 0;
  759. #endif
  760. }
  761. static int IntelQaSymCipher(IntelQaDev* dev, byte* out, const byte* in,
  762. word32 inOutSz, const byte* key, word32 keySz, const byte* iv, word32 ivSz,
  763. CpaCySymOp symOperation, CpaCySymCipherAlgorithm cipherAlgorithm,
  764. CpaCySymCipherDirection cipherDirection,
  765. /* for auth ciphers (CCM or GCM) */
  766. CpaCySymHashAlgorithm hashAlgorithm,
  767. byte* authTag, word32 authTagSz,
  768. const byte* authIn, word32 authInSz)
  769. {
  770. int ret;
  771. CpaStatus status = CPA_STATUS_SUCCESS;
  772. CpaCySymOpData* opData = NULL;
  773. CpaCySymSessionSetupData setup;
  774. const Cpa32U numBuffers = 1;
  775. CpaBufferList* bufferList = NULL;
  776. CpaFlatBuffer* flatBuffer = NULL;
  777. Cpa8U* ivBuf = NULL;
  778. Cpa8U* dataBuf = NULL;
  779. Cpa32U dataLen = inOutSz;
  780. Cpa8U* metaBuf = NULL;
  781. Cpa32U metaSize = 0;
  782. Cpa8U* authInBuf = NULL;
  783. Cpa32U authInSzAligned = authInSz;
  784. Cpa8U* authTagBuf = NULL;
  785. IntelQaSymCtx* ctx;
  786. CpaBoolean verifyResult = CPA_FALSE;
  787. QLOG("IntelQaSymCipher: dev %p, out %p, in %p, inOutSz %d, op %d, "
  788. "algo %d, dir %d, hash %d\n",
  789. dev, out, in, inOutSz, symOperation, cipherAlgorithm,
  790. cipherDirection, hashAlgorithm);
  791. /* check args */
  792. if (out == NULL || in == NULL || inOutSz == 0 ||
  793. key == NULL || keySz == 0 || iv == NULL || ivSz == 0) {
  794. return BAD_FUNC_ARG;
  795. }
  796. if (hashAlgorithm != CPA_CY_SYM_HASH_NONE &&
  797. (authTag == NULL || authTagSz == 0)) {
  798. return BAD_FUNC_ARG;
  799. }
  800. /* get meta size */
  801. status = cpaCyBufferListGetMetaSize(dev->handle, numBuffers, &metaSize);
  802. if (status != CPA_STATUS_SUCCESS && metaSize <= 0) {
  803. ret = BUFFER_E; goto exit;
  804. }
  805. /* if authtag provided then it will be appended to end of input */
  806. if (authTag && authTagSz > 0) {
  807. dataLen += authTagSz;
  808. }
  809. /* allocate buffers */
  810. ctx = &dev->op.cipher.ctx;
  811. opData = &ctx->opData;
  812. bufferList = &dev->op.cipher.bufferList;
  813. flatBuffer = &dev->op.cipher.flatBuffer;
  814. metaBuf = XMALLOC(metaSize, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
  815. dataBuf = XMALLOC(dataLen, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
  816. XMEMCPY(dataBuf, in, inOutSz);
  817. ivBuf = XMALLOC(AES_BLOCK_SIZE, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
  818. XMEMCPY(ivBuf, iv, ivSz);
  819. authTagBuf = XMALLOC(authTagSz, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
  820. /* check allocations */
  821. if (ivBuf == NULL || metaBuf == NULL || dataBuf == NULL ||
  822. authTagBuf == NULL) {
  823. ret = MEMORY_E; goto exit;
  824. }
  825. /* AAD */
  826. if (authIn && authInSz > 0) {
  827. /* make sure AAD is block aligned */
  828. if (authInSzAligned % AES_BLOCK_SIZE) {
  829. authInSzAligned += AES_BLOCK_SIZE -
  830. (authInSzAligned % AES_BLOCK_SIZE);
  831. }
  832. authInBuf = XMALLOC(authInSzAligned, dev->heap,
  833. DYNAMIC_TYPE_ASYNC_NUMA);
  834. XMEMCPY(authInBuf, authIn, authInSz);
  835. if (authInBuf == NULL) {
  836. ret = MEMORY_E; goto exit;
  837. }
  838. /* clear remainder */
  839. XMEMSET(authInBuf + authInSz, 0, authInSzAligned - authInSz);
  840. }
  841. /* init buffers */
  842. XMEMSET(&setup, 0, sizeof(CpaCySymSessionSetupData));
  843. XMEMSET(opData, 0, sizeof(CpaCySymOpData));
  844. XMEMSET(bufferList, 0, sizeof(CpaBufferList));
  845. XMEMSET(flatBuffer, 0, sizeof(CpaFlatBuffer));
  846. XMEMSET(metaBuf, 0, metaSize);
  847. bufferList->pBuffers = flatBuffer;
  848. bufferList->numBuffers = numBuffers;
  849. bufferList->pPrivateMetaData = metaBuf;
  850. flatBuffer->dataLenInBytes = dataLen;
  851. flatBuffer->pData = dataBuf;
  852. /* setup */
  853. setup.sessionPriority = CPA_CY_PRIORITY_NORMAL;
  854. setup.symOperation = symOperation;
  855. setup.cipherSetupData.cipherAlgorithm = cipherAlgorithm;
  856. setup.cipherSetupData.cipherKeyLenInBytes = keySz;
  857. setup.cipherSetupData.pCipherKey = (byte*)key;
  858. setup.cipherSetupData.cipherDirection = cipherDirection;
  859. /* setup auth ciphers */
  860. if (hashAlgorithm != CPA_CY_SYM_HASH_NONE) {
  861. setup.algChainOrder =
  862. (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) ?
  863. CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH :
  864. CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  865. setup.hashSetupData.hashAlgorithm = hashAlgorithm;
  866. setup.hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  867. setup.hashSetupData.digestResultLenInBytes = authTagSz;
  868. setup.hashSetupData.authModeSetupData.aadLenInBytes = authInSz;
  869. if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT)
  870. setup.digestIsAppended = CPA_TRUE;
  871. else
  872. setup.digestIsAppended = CPA_FALSE;
  873. }
  874. /* open session */
  875. ret = IntelQaSymOpen(dev, &setup, NULL);
  876. if (ret != 0) {
  877. goto exit;
  878. }
  879. /* operation data */
  880. opData->sessionCtx = ctx->symCtx;
  881. opData->packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  882. opData->pIv = ivBuf;
  883. opData->ivLenInBytes = ivSz;
  884. opData->cryptoStartSrcOffsetInBytes = 0;
  885. opData->messageLenToCipherInBytes = inOutSz;
  886. if (authIn && authInSz > 0) {
  887. opData->pAdditionalAuthData = authInBuf;
  888. }
  889. if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT) {
  890. if (authTag && authTagSz > 0) {
  891. /* append digest to end of data buffer */
  892. XMEMCPY(flatBuffer->pData + inOutSz, authTag, authTagSz);
  893. }
  894. }
  895. else {
  896. if (authTag && authTagSz > 0) {
  897. XMEMCPY(authTagBuf, authTag, authTagSz);
  898. }
  899. }
  900. /* store info needed for output */
  901. dev->out = out;
  902. dev->outLen = inOutSz;
  903. if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) {
  904. dev->op.cipher.authTag = authTagBuf;
  905. dev->op.cipher.authTagSz = authTagSz;
  906. opData->pDigestResult = authTagBuf;
  907. }
  908. else {
  909. dev->op.cipher.authTag = NULL;
  910. dev->op.cipher.authTagSz = 0;
  911. }
  912. IntelQaOpInit(dev, IntelQaSymCipherFree);
  913. /* perform symmetric AES operation async */
  914. /* use same buffer list for in-place operation */
  915. status = cpaCySymPerformOp(dev->handle, dev, opData,
  916. bufferList, bufferList, &verifyResult);
  917. if (symOperation == CPA_CY_SYM_OP_ALGORITHM_CHAINING &&
  918. cipherAlgorithm == CPA_CY_SYM_CIPHER_AES_GCM &&
  919. cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT &&
  920. hashAlgorithm == CPA_CY_SYM_HASH_AES_GCM) {
  921. if (verifyResult == CPA_FALSE) {
  922. ret = AES_GCM_AUTH_E;
  923. }
  924. }
  925. exit:
  926. if (ret != 0) {
  927. QLOG("cpaCySymPerformOp Cipher failed! dev %p, status %d, ret %d\n",
  928. dev, status, ret);
  929. }
  930. /* Capture the inline decrypt into the output. */
  931. XMEMCPY(out, dataBuf, inOutSz);
  932. if (cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) {
  933. if (authTag != NULL && authTagSz > 0) {
  934. XMEMCPY(authTag, authTagBuf, authTagSz);
  935. }
  936. }
  937. /* handle cleanup */
  938. IntelQaSymCipherFree(dev);
  939. return ret;
  940. }
  941. #ifdef HAVE_AES_CBC
  942. int IntelQaSymAesCbcEncrypt(IntelQaDev* dev,
  943. byte* out, const byte* in, word32 sz,
  944. const byte* key, word32 keySz,
  945. const byte* iv, word32 ivSz)
  946. {
  947. int ret = IntelQaSymCipher(dev, out, in, sz,
  948. key, keySz, iv, ivSz,
  949. CPA_CY_SYM_OP_CIPHER, CPA_CY_SYM_CIPHER_AES_CBC,
  950. CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT,
  951. CPA_CY_SYM_HASH_NONE, NULL, 0, NULL, 0);
  952. XMEMCPY((byte*)iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
  953. return ret;
  954. }
  955. #ifdef HAVE_AES_DECRYPT
  956. int IntelQaSymAesCbcDecrypt(IntelQaDev* dev,
  957. byte* out, const byte* in, word32 sz,
  958. const byte* key, word32 keySz,
  959. const byte* iv, word32 ivSz)
  960. {
  961. byte nextIv[AES_BLOCK_SIZE];
  962. int ret;
  963. XMEMCPY(nextIv, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
  964. ret = IntelQaSymCipher(dev, out, in, sz,
  965. key, keySz, iv, ivSz,
  966. CPA_CY_SYM_OP_CIPHER, CPA_CY_SYM_CIPHER_AES_CBC,
  967. CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT,
  968. CPA_CY_SYM_HASH_NONE, NULL, 0, NULL, 0);
  969. XMEMCPY((byte*)iv, nextIv, AES_BLOCK_SIZE);
  970. return ret;
  971. }
  972. #endif /* HAVE_AES_DECRYPT */
  973. #endif /* HAVE_AES_CBC */
  974. #ifdef HAVE_AESGCM
  975. int IntelQaSymAesGcmEncrypt(IntelQaDev* dev,
  976. byte* out, const byte* in, word32 sz,
  977. const byte* key, word32 keySz,
  978. const byte* iv, word32 ivSz,
  979. byte* authTag, word32 authTagSz,
  980. const byte* authIn, word32 authInSz)
  981. {
  982. return IntelQaSymCipher(dev, out, in, sz,
  983. key, keySz, iv, ivSz,
  984. CPA_CY_SYM_OP_ALGORITHM_CHAINING, CPA_CY_SYM_CIPHER_AES_GCM,
  985. CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT,
  986. CPA_CY_SYM_HASH_AES_GCM, authTag, authTagSz, authIn, authInSz);
  987. }
  988. #ifdef HAVE_AES_DECRYPT
  989. int IntelQaSymAesGcmDecrypt(IntelQaDev* dev,
  990. byte* out, const byte* in, word32 sz,
  991. const byte* key, word32 keySz,
  992. const byte* iv, word32 ivSz,
  993. const byte* authTag, word32 authTagSz,
  994. const byte* authIn, word32 authInSz)
  995. {
  996. return IntelQaSymCipher(dev, out, in, sz,
  997. key, keySz, iv, ivSz,
  998. CPA_CY_SYM_OP_ALGORITHM_CHAINING, CPA_CY_SYM_CIPHER_AES_GCM,
  999. CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT,
  1000. CPA_CY_SYM_HASH_AES_GCM, (byte*)authTag, authTagSz, authIn, authInSz);
  1001. }
  1002. #endif /* HAVE_AES_DECRYPT */
  1003. #endif /* HAVE_AESGCM */
  1004. #ifndef NO_DES3
  1005. int IntelQaSymDes3CbcEncrypt(IntelQaDev* dev,
  1006. byte* out, const byte* in, word32 sz,
  1007. const byte* key, word32 keySz,
  1008. const byte* iv, word32 ivSz)
  1009. {
  1010. return IntelQaSymCipher(dev, out, in, sz,
  1011. key, keySz, iv, ivSz,
  1012. CPA_CY_SYM_OP_CIPHER, CPA_CY_SYM_CIPHER_3DES_CBC,
  1013. CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT,
  1014. CPA_CY_SYM_HASH_NONE, NULL, 0, NULL, 0);
  1015. }
  1016. int IntelQaSymDes3CbcDecrypt(IntelQaDev* dev,
  1017. byte* out, const byte* in, word32 sz,
  1018. const byte* key, word32 keySz,
  1019. const byte* iv, word32 ivSz)
  1020. {
  1021. return IntelQaSymCipher(dev, out, in, sz,
  1022. key, keySz, iv, ivSz,
  1023. CPA_CY_SYM_OP_CIPHER, CPA_CY_SYM_CIPHER_3DES_CBC,
  1024. CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT,
  1025. CPA_CY_SYM_HASH_NONE, NULL, 0, NULL, 0);
  1026. }
  1027. #endif /* !NO_DES3 */
  1028. #endif /* QAT_ENABLE_CRYPTO */
  1029. #ifdef WOLF_CRYPTO_CB
  1030. int IntelQaSymSync_CryptoDevCb(int devId, struct wc_CryptoInfo* info, void* ctx)
  1031. {
  1032. int rc = NOT_COMPILED_IN; /* return this to bypass HW and use SW */
  1033. IntelQaDev* dev;
  1034. if (info == NULL || ctx == NULL)
  1035. return BAD_FUNC_ARG;
  1036. (void)devId;
  1037. dev = (IntelQaDev*)ctx;
  1038. #ifdef QAT_ENABLE_CRYPTO
  1039. if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
  1040. QLOG("CryptoDevCb Cipher: Type %d\n", info->cipher.type);
  1041. #ifndef NO_AES
  1042. if (info->cipher.type == WC_CIPHER_AES_CBC) {
  1043. Aes* aes = info->cipher.aescbc.aes;
  1044. if (aes == NULL)
  1045. return BAD_FUNC_ARG;
  1046. if (info->cipher.enc) {
  1047. rc = IntelQaSymAesCbcEncrypt(dev,
  1048. info->cipher.aescbc.out,
  1049. info->cipher.aescbc.in,
  1050. info->cipher.aescbc.sz,
  1051. (byte*)aes->devKey, aes->keylen,
  1052. (byte*)aes->reg, AES_BLOCK_SIZE);
  1053. }
  1054. else {
  1055. rc = IntelQaSymAesCbcDecrypt(dev,
  1056. info->cipher.aescbc.out,
  1057. info->cipher.aescbc.in,
  1058. info->cipher.aescbc.sz,
  1059. (byte*)aes->devKey, aes->keylen,
  1060. (byte*)aes->reg, AES_BLOCK_SIZE);
  1061. }
  1062. }
  1063. #endif /* !NO_AES */
  1064. #ifdef HAVE_AESGCM
  1065. if (info->cipher.type == WC_CIPHER_AES_GCM) {
  1066. if (info->cipher.enc) {
  1067. Aes* aes = info->cipher.aesgcm_enc.aes;
  1068. if (aes == NULL)
  1069. return BAD_FUNC_ARG;
  1070. rc = IntelQaSymAesGcmEncrypt(dev,
  1071. info->cipher.aesgcm_enc.out,
  1072. info->cipher.aesgcm_enc.in,
  1073. info->cipher.aesgcm_enc.sz,
  1074. (const byte*)aes->devKey, aes->keylen,
  1075. info->cipher.aesgcm_enc.iv,
  1076. info->cipher.aesgcm_enc.ivSz,
  1077. info->cipher.aesgcm_enc.authTag,
  1078. info->cipher.aesgcm_enc.authTagSz,
  1079. info->cipher.aesgcm_enc.authIn,
  1080. info->cipher.aesgcm_enc.authInSz);
  1081. }
  1082. else {
  1083. Aes* aes = info->cipher.aesgcm_dec.aes;
  1084. if (aes == NULL)
  1085. return BAD_FUNC_ARG;
  1086. rc = IntelQaSymAesGcmDecrypt(dev,
  1087. info->cipher.aesgcm_dec.out,
  1088. info->cipher.aesgcm_dec.in,
  1089. info->cipher.aesgcm_dec.sz,
  1090. (const byte*)aes->devKey, aes->keylen,
  1091. info->cipher.aesgcm_dec.iv,
  1092. info->cipher.aesgcm_dec.ivSz,
  1093. info->cipher.aesgcm_dec.authTag,
  1094. info->cipher.aesgcm_dec.authTagSz,
  1095. info->cipher.aesgcm_dec.authIn,
  1096. info->cipher.aesgcm_dec.authInSz);
  1097. }
  1098. }
  1099. #endif /* HAVE_AESGCM */
  1100. #ifndef NO_DES3
  1101. if (info->cipher.type == WC_CIPHER_DES3) {
  1102. Des3* des = info->cipher.des3.des;
  1103. if (des == NULL)
  1104. return BAD_FUNC_ARG;
  1105. if (info->cipher.enc) {
  1106. rc = IntelQaSymDes3CbcEncrypt(dev,
  1107. info->cipher.des3.out,
  1108. info->cipher.des3.in,
  1109. info->cipher.des3.sz,
  1110. (byte*)des->devKey, DES3_KEYLEN,
  1111. (byte*)des->reg, DES_BLOCK_SIZE);
  1112. }
  1113. else {
  1114. rc = IntelQaSymDes3CbcDecrypt(dev,
  1115. info->cipher.des3.out,
  1116. info->cipher.des3.in,
  1117. info->cipher.des3.sz,
  1118. (byte*)des->devKey, DES3_KEYLEN,
  1119. (byte*)des->reg, DES_BLOCK_SIZE);
  1120. }
  1121. }
  1122. #endif /* !NO_DES3 */
  1123. }
  1124. #endif /* QAT_ENABLE_CRYPTO */
  1125. return rc;
  1126. }
  1127. /* -------------------------------------------------------------------------- */
  1128. /* Public API */
  1129. /* -------------------------------------------------------------------------- */
  1130. int wc_CryptoCb_InitIntelQa(void)
  1131. {
  1132. int devId, rc;
  1133. devId = IntelQaInit(NULL);
  1134. if (devId < 0) {
  1135. QLOG("Couldn't init the Intel QA\n");
  1136. devId = INVALID_DEVID;
  1137. }
  1138. else {
  1139. rc = IntelQaOpen(&qaDev, devId);
  1140. if (rc != 0) {
  1141. QLOG("Couldn't open the device\n");
  1142. IntelQaDeInit(devId);
  1143. devId = INVALID_DEVID;
  1144. }
  1145. else {
  1146. rc = wc_CryptoCb_RegisterDevice(devId,
  1147. IntelQaSymSync_CryptoDevCb, &qaDev);
  1148. if (rc != 0) {
  1149. QLOG("Couldn't register the device\n");
  1150. IntelQaClose(&qaDev);
  1151. IntelQaDeInit(devId);
  1152. devId = INVALID_DEVID;
  1153. }
  1154. }
  1155. }
  1156. return devId;
  1157. }
  1158. void wc_CryptoCb_CleanupIntelQa(int* id)
  1159. {
  1160. if (INVALID_DEVID != *id) {
  1161. wc_CryptoCb_UnRegisterDevice(*id);
  1162. IntelQaClose(&qaDev);
  1163. IntelQaDeInit(*id);
  1164. *id = INVALID_DEVID;
  1165. }
  1166. }
  1167. #endif /* WOLF_CRYPTO_CB */
  1168. /* -------------------------------------------------------------------------- */
  1169. /* Memory allocator and deallocator */
  1170. /* -------------------------------------------------------------------------- */
  1171. #include <stdio.h>
  1172. #include <stdlib.h>
  1173. #include <string.h>
  1174. /* use thread local for QAE variables (removing mutex requirement) */
  1175. #ifdef USE_QAE_THREAD_LS
  1176. #include <pthread.h> /* for threadId tracking */
  1177. #define QAE_THREAD_LS THREAD_LS_T
  1178. #else
  1179. #define QAE_THREAD_LS
  1180. #endif
  1181. /* these are used to align memory to a byte boundary */
  1182. #define ALIGNMENT_BASE (16ul)
  1183. #define ALIGNMENT_HW (64ul)
  1184. #define WOLF_MAGIC_NUM 0xA576F6C6641736EBUL /* (0xA)WolfAsyn(0xB) */
  1185. #define WOLF_HEADER_ALIGN ALIGNMENT_BASE
  1186. #define QAE_NOT_NUMA_PAGE 0xFFFF
  1187. typedef struct qaeMemHeader {
  1188. #ifdef WOLFSSL_TRACK_MEMORY
  1189. struct qaeMemHeader* next;
  1190. struct qaeMemHeader* prev;
  1191. #ifdef WOLFSSL_DEBUG_MEMORY
  1192. const char* func;
  1193. unsigned int line;
  1194. #endif
  1195. #endif
  1196. uint64_t magic;
  1197. void* heap;
  1198. #ifdef USE_QAE_THREAD_LS
  1199. pthread_t threadId;
  1200. #endif
  1201. size_t size;
  1202. word16 count;
  1203. word16 isNuma:1;
  1204. word16 reservedBits:15; /* use for future bits */
  1205. word16 type;
  1206. word16 numa_page_offset; /* use QAE_NOT_NUMA_PAGE if not NUMA */
  1207. } ALIGN16 qaeMemHeader;
  1208. #ifdef WOLFSSL_TRACK_MEMORY
  1209. typedef struct qaeMemStats {
  1210. long totalAllocs; /* number of allocations */
  1211. long totalDeallocs; /* number of deallocations */
  1212. long totalBytes; /* total number of bytes allocated */
  1213. long peakBytes; /* concurrent max bytes */
  1214. long currentBytes; /* total current bytes in use */
  1215. } qaeMemStats;
  1216. /* track allocations and report at end */
  1217. typedef struct qaeMemList {
  1218. qaeMemHeader* head;
  1219. qaeMemHeader* tail;
  1220. uint32_t count;
  1221. } qaeMemList;
  1222. #endif /* WOLFSSL_TRACK_MEMORY */
  1223. /* local variables */
  1224. #ifndef USE_QAE_THREAD_LS
  1225. static pthread_mutex_t g_memLock = PTHREAD_MUTEX_INITIALIZER;
  1226. #endif
  1227. #ifdef WOLFSSL_TRACK_MEMORY
  1228. static qaeMemStats g_memStats;
  1229. static qaeMemList g_memList;
  1230. static pthread_mutex_t g_memStatLock = PTHREAD_MUTEX_INITIALIZER;
  1231. #endif
  1232. static WC_INLINE int qaeMemTypeIsNuma(int type)
  1233. {
  1234. int isNuma = 0;
  1235. switch (type) {
  1236. case DYNAMIC_TYPE_ASYNC_NUMA:
  1237. case DYNAMIC_TYPE_ASYNC_NUMA64:
  1238. case DYNAMIC_TYPE_WOLF_BIGINT:
  1239. case DYNAMIC_TYPE_PRIVATE_KEY:
  1240. case DYNAMIC_TYPE_PUBLIC_KEY:
  1241. case DYNAMIC_TYPE_AES_BUFFER:
  1242. case DYNAMIC_TYPE_RSA_BUFFER:
  1243. case DYNAMIC_TYPE_ECC_BUFFER:
  1244. case DYNAMIC_TYPE_SIGNATURE:
  1245. case DYNAMIC_TYPE_DIGEST:
  1246. case DYNAMIC_TYPE_SECRET:
  1247. case DYNAMIC_TYPE_SEED:
  1248. case DYNAMIC_TYPE_SALT:
  1249. {
  1250. isNuma = 1;
  1251. break;
  1252. }
  1253. case DYNAMIC_TYPE_OUT_BUFFER:
  1254. case DYNAMIC_TYPE_IN_BUFFER:
  1255. {
  1256. #if !defined(WC_ASYNC_NO_CRYPT) && !defined(WC_ASYNC_NO_HASH)
  1257. isNuma = 1;
  1258. #else
  1259. isNuma = 0;
  1260. #endif
  1261. break;
  1262. }
  1263. default:
  1264. isNuma = 0;
  1265. break;
  1266. }
  1267. return isNuma;
  1268. }
  1269. static void _qaeMemFree(void *ptr, void* heap, int type
  1270. #ifdef WOLFSSL_DEBUG_MEMORY
  1271. , const char* func, unsigned int line
  1272. #endif
  1273. )
  1274. {
  1275. qaeMemHeader* header = NULL;
  1276. size_t size;
  1277. void* origPtr = ptr;
  1278. if (ptr == NULL)
  1279. return;
  1280. /* adjust for header and align */
  1281. ptr = (byte*)(((size_t)ptr - ((size_t)ptr % WOLF_HEADER_ALIGN)) -
  1282. sizeof(qaeMemHeader));
  1283. header = (qaeMemHeader*)ptr;
  1284. /* check for header magic */
  1285. if (header->magic != WOLF_MAGIC_NUM) {
  1286. printf("Free: Header magic not found! %p\n", ptr);
  1287. return;
  1288. }
  1289. /* cache values for later */
  1290. size = header->size;
  1291. #ifdef WOLFSSL_DEBUG_MEMORY
  1292. #ifdef WOLFSSL_DEBUG_MEMORY_PRINT
  1293. printf("Free: %p (%u) at %s:%u, heap %p, type %d, count %d\n",
  1294. origPtr, (unsigned int)size, func, line, heap, type, header->count);
  1295. #else
  1296. (void)func;
  1297. (void)line;
  1298. #endif
  1299. #endif
  1300. (void)type;
  1301. /* adjust free count */
  1302. header->count--;
  1303. /* check header count */
  1304. if (header->count > 0) {
  1305. /* go ahead and return if still in use */
  1306. return;
  1307. }
  1308. #ifdef WOLFSSL_TRACK_MEMORY
  1309. if (pthread_mutex_lock(&g_memStatLock) == 0) {
  1310. g_memStats.currentBytes -= size;
  1311. g_memStats.totalDeallocs++;
  1312. if (header == g_memList.head && header == g_memList.tail) {
  1313. g_memList.head = NULL;
  1314. g_memList.tail = NULL;
  1315. }
  1316. else if (header == g_memList.head) {
  1317. g_memList.head = header->next;
  1318. g_memList.head->prev = NULL;
  1319. }
  1320. else if (header == g_memList.tail) {
  1321. g_memList.tail = header->prev;
  1322. g_memList.tail->next = NULL;
  1323. }
  1324. else {
  1325. qaeMemHeader* next = header->next;
  1326. qaeMemHeader* prev = header->prev;
  1327. if (next)
  1328. next->prev = prev;
  1329. if (prev)
  1330. prev->next = next;
  1331. }
  1332. g_memList.count--;
  1333. pthread_mutex_unlock(&g_memStatLock);
  1334. }
  1335. #endif
  1336. (void)heap;
  1337. (void)size;
  1338. (void)origPtr;
  1339. #ifdef WOLFSSL_DEBUG_MEMORY
  1340. /* make sure magic is gone */
  1341. header->magic = 0;
  1342. #endif
  1343. /* free type */
  1344. if (header->isNuma && header->numa_page_offset != QAE_NOT_NUMA_PAGE) {
  1345. qaeMemFreeNUMA(&ptr);
  1346. }
  1347. else {
  1348. free(ptr);
  1349. }
  1350. }
  1351. static void* _qaeMemAlloc(size_t size, void* heap, int type
  1352. #ifdef WOLFSSL_DEBUG_MEMORY
  1353. , const char* func, unsigned int line
  1354. #endif
  1355. )
  1356. {
  1357. void* ptr = NULL;
  1358. qaeMemHeader* header = NULL;
  1359. int isNuma;
  1360. int alignment = ALIGNMENT_BASE;
  1361. word16 page_offset = QAE_NOT_NUMA_PAGE;
  1362. /* make sure all allocations are aligned */
  1363. if ((size % WOLF_HEADER_ALIGN) != 0) {
  1364. size += (WOLF_HEADER_ALIGN - (size % WOLF_HEADER_ALIGN));
  1365. }
  1366. isNuma = qaeMemTypeIsNuma(type);
  1367. if (type == DYNAMIC_TYPE_ASYNC_NUMA64)
  1368. alignment = ALIGNMENT_HW;
  1369. /* allocate type */
  1370. if (isNuma) {
  1371. /* Node is typically 0 */
  1372. page_offset = 0;
  1373. ptr = qaeMemAllocNUMA((Cpa32U)(size + sizeof(qaeMemHeader)), 0,
  1374. alignment);
  1375. }
  1376. else {
  1377. isNuma = 0;
  1378. ptr = malloc(size + sizeof(qaeMemHeader));
  1379. }
  1380. /* add header */
  1381. if (ptr) {
  1382. header = (qaeMemHeader*)ptr;
  1383. ptr = (byte*)ptr + sizeof(qaeMemHeader);
  1384. header->magic = WOLF_MAGIC_NUM;
  1385. header->heap = heap;
  1386. header->size = size;
  1387. header->type = type;
  1388. header->count = 1;
  1389. header->isNuma = isNuma;
  1390. header->numa_page_offset = page_offset;
  1391. #ifdef USE_QAE_THREAD_LS
  1392. header->threadId = pthread_self();
  1393. #endif
  1394. #ifdef WOLFSSL_TRACK_MEMORY
  1395. if (pthread_mutex_lock(&g_memStatLock) == 0) {
  1396. g_memStats.totalAllocs++;
  1397. g_memStats.totalBytes += size;
  1398. g_memStats.currentBytes += size;
  1399. if (g_memStats.currentBytes > g_memStats.peakBytes)
  1400. g_memStats.peakBytes = g_memStats.currentBytes;
  1401. #ifdef WOLFSSL_DEBUG_MEMORY
  1402. header->func = func;
  1403. header->line = line;
  1404. #endif
  1405. /* Setup event */
  1406. header->next = NULL;
  1407. if (g_memList.tail == NULL) {
  1408. g_memList.head = header;
  1409. }
  1410. else {
  1411. g_memList.tail->next = header;
  1412. header->prev = g_memList.tail;
  1413. }
  1414. g_memList.tail = header; /* add to the end either way */
  1415. g_memList.count++;
  1416. pthread_mutex_unlock(&g_memStatLock);
  1417. }
  1418. #endif
  1419. }
  1420. #ifdef WOLFSSL_DEBUG_MEMORY
  1421. #ifdef WOLFSSL_DEBUG_MEMORY_PRINT
  1422. printf("Alloc: %p (%u) at %s:%u, heap %p, type %d\n",
  1423. ptr, (unsigned int)size, func, line, heap, type);
  1424. #else
  1425. (void)func;
  1426. (void)line;
  1427. #endif
  1428. #endif
  1429. (void)heap;
  1430. return ptr;
  1431. }
  1432. /* Public Functions */
  1433. void* wc_CryptoCb_IntelQaMalloc(size_t size, void* heap, int type
  1434. #ifdef WOLFSSL_DEBUG_MEMORY
  1435. , const char* func, unsigned int line
  1436. #endif
  1437. )
  1438. {
  1439. void* ptr;
  1440. #ifndef USE_QAE_THREAD_LS
  1441. int ret = pthread_mutex_lock(&g_memLock);
  1442. if (ret != 0) {
  1443. printf("Alloc: Error(%d) on mutex lock\n", ret);
  1444. return NULL;
  1445. }
  1446. #endif
  1447. ptr = _qaeMemAlloc(size, heap, type
  1448. #ifdef WOLFSSL_DEBUG_MEMORY
  1449. , func, line
  1450. #endif
  1451. );
  1452. #ifndef USE_QAE_THREAD_LS
  1453. pthread_mutex_unlock(&g_memLock);
  1454. #endif
  1455. return ptr;
  1456. }
  1457. void wc_CryptoCb_IntelQaFree(void *ptr, void* heap, int type
  1458. #ifdef WOLFSSL_DEBUG_MEMORY
  1459. , const char* func, unsigned int line
  1460. #endif
  1461. )
  1462. {
  1463. #ifndef USE_QAE_THREAD_LS
  1464. int ret = pthread_mutex_lock(&g_memLock);
  1465. if (ret != 0) {
  1466. printf("Free: Error(%d) on mutex lock\n", ret);
  1467. return;
  1468. }
  1469. #endif
  1470. _qaeMemFree(ptr, heap, type
  1471. #ifdef WOLFSSL_DEBUG_MEMORY
  1472. , func, line
  1473. #endif
  1474. );
  1475. #ifndef USE_QAE_THREAD_LS
  1476. pthread_mutex_unlock(&g_memLock);
  1477. #endif
  1478. }
  1479. void* wc_CryptoCb_IntelQaRealloc(void *ptr, size_t size, void* heap, int type
  1480. #ifdef WOLFSSL_DEBUG_MEMORY
  1481. , const char* func, unsigned int line
  1482. #endif
  1483. )
  1484. {
  1485. void* newPtr = NULL;
  1486. void* origPtr = ptr;
  1487. qaeMemHeader* header = NULL;
  1488. byte allocNew = 1;
  1489. int newIsNuma = -1, ptrIsNuma = -1;
  1490. size_t copySize = 0;
  1491. #ifndef USE_QAE_THREAD_LS
  1492. int ret = pthread_mutex_lock(&g_memLock);
  1493. if (ret != 0) {
  1494. printf("Realloc: Error(%d) on mutex lock\n", ret);
  1495. return NULL;
  1496. }
  1497. #endif
  1498. (void)heap;
  1499. if (ptr) {
  1500. /* get header pointer and align */
  1501. header = (qaeMemHeader*)(((size_t)ptr -
  1502. ((size_t)ptr % WOLF_HEADER_ALIGN)) - sizeof(qaeMemHeader));
  1503. if (header->magic == WOLF_MAGIC_NUM) {
  1504. newIsNuma = qaeMemTypeIsNuma(type);
  1505. ptrIsNuma = (header->numa_page_offset != QAE_NOT_NUMA_PAGE) ? 1 : 0;
  1506. /* for non-NUMA, treat as normal REALLOC */
  1507. if (newIsNuma == 0 && ptrIsNuma == 0) {
  1508. allocNew = 1;
  1509. }
  1510. /* confirm input is aligned, otherwise allocate new */
  1511. else if (((size_t)ptr % WOLF_HEADER_ALIGN) != 0) {
  1512. allocNew = 1;
  1513. }
  1514. /* if matching NUMA type and size fits, use existing */
  1515. else if (newIsNuma == ptrIsNuma && header->size >= size) {
  1516. #ifdef USE_QAE_THREAD_LS
  1517. if (header->threadId != pthread_self()) {
  1518. allocNew = 1;
  1519. #if 0
  1520. printf("Realloc %p from different thread! orig %lx this %lx\n",
  1521. origPtr, header->threadId, pthread_self());
  1522. #endif
  1523. }
  1524. else
  1525. #endif
  1526. {
  1527. /* use existing pointer and increment counter */
  1528. header->count++;
  1529. newPtr = origPtr;
  1530. allocNew = 0;
  1531. }
  1532. }
  1533. copySize = header->size;
  1534. }
  1535. else {
  1536. copySize = size;
  1537. }
  1538. }
  1539. if (allocNew) {
  1540. newPtr = _qaeMemAlloc(size, heap, type
  1541. #ifdef WOLFSSL_DEBUG_MEMORY
  1542. , func, line
  1543. #endif
  1544. );
  1545. if (newPtr && ptr) {
  1546. /* only copy min of new and old size to new pointer */
  1547. if (copySize > size)
  1548. copySize = size;
  1549. XMEMCPY(newPtr, ptr, copySize);
  1550. if (newIsNuma == 0 && ptrIsNuma == 0) {
  1551. /* for non-NUMA, treat as normal REALLOC and free old pointer */
  1552. _qaeMemFree(ptr, heap, type
  1553. #ifdef WOLFSSL_DEBUG_MEMORY
  1554. , func, line
  1555. #endif
  1556. );
  1557. }
  1558. }
  1559. }
  1560. #ifndef USE_QAE_THREAD_LS
  1561. pthread_mutex_unlock(&g_memLock);
  1562. #endif
  1563. #ifdef WOLFSSL_DEBUG_MEMORY
  1564. #ifdef WOLFSSL_DEBUG_MEMORY_PRINT
  1565. if (allocNew) {
  1566. printf("Realloc: New %p -> %p (%u) at %s:%u, heap %p, type %d\n",
  1567. origPtr, newPtr, (unsigned int)size, func, line, heap, type);
  1568. }
  1569. else {
  1570. printf("Realloc: Reuse %p (%u) at %s:%u, heap %p, type %d, count %d\n",
  1571. origPtr, (unsigned int)size, func, line, header->heap, header->type, header->count);
  1572. }
  1573. #else
  1574. (void)func;
  1575. (void)line;
  1576. #endif
  1577. #endif
  1578. return newPtr;
  1579. }
  1580. #ifdef WOLFSSL_TRACK_MEMORY
  1581. int InitMemoryTracker(void)
  1582. {
  1583. if (pthread_mutex_lock(&g_memStatLock) == 0) {
  1584. g_memStats.totalAllocs = 0;
  1585. g_memStats.totalDeallocs= 0;
  1586. g_memStats.totalBytes = 0;
  1587. g_memStats.peakBytes = 0;
  1588. g_memStats.currentBytes = 0;
  1589. XMEMSET(&g_memList, 0, sizeof(g_memList));
  1590. pthread_mutex_unlock(&g_memStatLock);
  1591. }
  1592. return 0;
  1593. }
  1594. void ShowMemoryTracker(void)
  1595. {
  1596. if (pthread_mutex_lock(&g_memStatLock) == 0) {
  1597. printf("total Allocs = %9ld\n", g_memStats.totalAllocs);
  1598. printf("total Deallocs = %9ld\n", g_memStats.totalDeallocs);
  1599. printf("total Bytes = %9ld\n", g_memStats.totalBytes);
  1600. printf("peak Bytes = %9ld\n", g_memStats.peakBytes);
  1601. printf("current Bytes = %9ld\n", g_memStats.currentBytes);
  1602. if (g_memList.count > 0) {
  1603. /* print list of allocations */
  1604. qaeMemHeader* header;
  1605. for (header = g_memList.head; header != NULL; header = header->next) {
  1606. printf("Leak: Ptr %p, Size %u, Type %d, Heap %p"
  1607. #ifdef WOLFSSL_DEBUG_MEMORY
  1608. ", Func %s, Line %d"
  1609. #endif
  1610. "\n",
  1611. (byte*)header + sizeof(qaeMemHeader), (unsigned int)header->size,
  1612. header->type, header->heap
  1613. #ifdef WOLFSSL_DEBUG_MEMORY
  1614. , header->func, header->line
  1615. #endif
  1616. );
  1617. }
  1618. }
  1619. pthread_mutex_unlock(&g_memStatLock);
  1620. /* cleanup lock */
  1621. pthread_mutex_destroy(&g_memStatLock);
  1622. }
  1623. }
  1624. #endif /* WOLFSSL_TRACK_MEMORY */
  1625. #ifdef QAT_DEMO_MAIN
  1626. /* AES GCM */
  1627. static const byte aesgcm_k[] = {
  1628. 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
  1629. 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
  1630. 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44,
  1631. 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22
  1632. };
  1633. static const byte aesgcm_iv[] = {
  1634. 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe,
  1635. 0xca, 0xfe, 0xca, 0xfe
  1636. };
  1637. static const byte aesgcm_a[] = {
  1638. 0xde, 0xad, 0xde, 0xad, 0xde, 0xad, 0xde, 0xad,
  1639. 0xde, 0xad, 0xde, 0xad, 0xde, 0xad, 0xde, 0xad,
  1640. 0xde, 0xad, 0xde, 0xad
  1641. };
  1642. static const byte aesgcm_p[] = {
  1643. 0x79, 0x84, 0x86, 0x44, 0x68, 0x45, 0x15, 0x61,
  1644. 0x86, 0x54, 0x66, 0x56, 0x54, 0x54, 0x31, 0x54,
  1645. 0x64, 0x64, 0x68, 0x45, 0x15, 0x15, 0x61, 0x61,
  1646. 0x51, 0x51, 0x51, 0x51, 0x51, 0x56, 0x14, 0x11,
  1647. 0x72, 0x13, 0x51, 0x82, 0x84, 0x56, 0x74, 0x53,
  1648. 0x45, 0x34, 0x65, 0x15, 0x46, 0x14, 0x67, 0x55,
  1649. 0x16, 0x14, 0x67, 0x54, 0x65, 0x47, 0x14, 0x67,
  1650. 0x46, 0x74, 0x65, 0x46
  1651. };
  1652. static const byte aesgcm_c[] = {
  1653. 0x59, 0x85, 0x02, 0x97, 0xE0, 0x4D, 0xFC, 0x5C,
  1654. 0x03, 0xCC, 0x83, 0x64, 0xCE, 0x28, 0x0B, 0x95,
  1655. 0x78, 0xEC, 0x93, 0x40, 0xA1, 0x8D, 0x21, 0xC5,
  1656. 0x48, 0x6A, 0x39, 0xBA, 0x4F, 0x4B, 0x8C, 0x95,
  1657. 0x6F, 0x8C, 0xF6, 0x9C, 0xD0, 0xA5, 0x8D, 0x67,
  1658. 0xA1, 0x32, 0x11, 0xE7, 0x2E, 0xF6, 0x63, 0xAF,
  1659. 0xDE, 0xD4, 0x7D, 0xEC, 0x15, 0x01, 0x58, 0xCB,
  1660. 0xE3, 0x7B, 0xC6, 0x94,
  1661. };
  1662. static byte aesgcm_t[] = {
  1663. 0x5D, 0x10, 0x3F, 0xC7, 0x22, 0xC7, 0x21, 0x29
  1664. };
  1665. /* simple example of using AES-GCM encrypt with Intel QA */
  1666. int main(int argc, char** argv)
  1667. {
  1668. #if !defined(NO_AES) && defined(HAVE_AESGCM)
  1669. int ret;
  1670. IntelQaDev dev;
  1671. byte out[256];
  1672. byte tmp[256];
  1673. word32 tmpLen;
  1674. #endif
  1675. #ifdef QAT_DEBUG
  1676. wolfSSL_Debugging_ON();
  1677. #endif
  1678. IntelQaInit(NULL);
  1679. #ifndef NO_AES
  1680. #ifdef HAVE_AESGCM
  1681. /* AES Test */
  1682. IntelQaOpen(&dev, 0);
  1683. dev.event.ret = WC_PENDING_E;
  1684. tmpLen = sizeof(aesgcm_t);
  1685. XMEMSET(out, 0, sizeof(out));
  1686. XMEMSET(tmp, 0, sizeof(tmp));
  1687. ret = IntelQaSymAesGcmEncrypt(&dev, out, aesgcm_p, sizeof(aesgcm_p),
  1688. aesgcm_k, sizeof(aesgcm_k), aesgcm_iv, sizeof(aesgcm_iv),
  1689. tmp, tmpLen, aesgcm_a, sizeof(aesgcm_a));
  1690. printf("AES GCM Encrypt: Ret=%d, Tag Len=%d\n", ret, tmpLen);
  1691. IntelQaClose(&dev);
  1692. #endif /* HAVE_AESGCM */
  1693. #endif /* NO_AES */
  1694. IntelQaDeInit(0);
  1695. return 0;
  1696. }
  1697. #endif
  1698. #endif /* HAVE_INTEL_QA_SYNC */