module_hooks.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. /* module_hooks.c -- module load/unload hooks for libwolfssl.ko
  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. #ifndef WOLFSSL_LICENSE
  22. #ifdef WOLFSSL_COMMERCIAL_LICENSE
  23. #define WOLFSSL_LICENSE "wolfSSL Commercial"
  24. #else
  25. #define WOLFSSL_LICENSE "GPL v2"
  26. #endif
  27. #endif
  28. #define FIPS_NO_WRAPPERS
  29. #define WOLFSSL_NEED_LINUX_CURRENT
  30. #ifdef HAVE_CONFIG_H
  31. #include <config.h>
  32. #endif
  33. #include <wolfssl/wolfcrypt/settings.h>
  34. #include <wolfssl/wolfcrypt/error-crypt.h>
  35. #ifdef WOLFCRYPT_ONLY
  36. #include <wolfssl/version.h>
  37. #else
  38. #include <wolfssl/ssl.h>
  39. #endif
  40. #ifdef HAVE_FIPS
  41. #include <wolfssl/wolfcrypt/fips_test.h>
  42. #endif
  43. #ifndef NO_CRYPT_TEST
  44. #include <wolfcrypt/test/test.h>
  45. #endif
  46. static int libwolfssl_cleanup(void) {
  47. int ret;
  48. #ifdef WOLFCRYPT_ONLY
  49. ret = wolfCrypt_Cleanup();
  50. if (ret != 0)
  51. pr_err("wolfCrypt_Cleanup() failed: %s\n", wc_GetErrorString(ret));
  52. else
  53. pr_info("wolfCrypt " LIBWOLFSSL_VERSION_STRING " cleanup complete.\n");
  54. #else
  55. ret = wolfSSL_Cleanup();
  56. if (ret != WOLFSSL_SUCCESS)
  57. pr_err("wolfSSL_Cleanup() failed: %s\n", wc_GetErrorString(ret));
  58. else
  59. pr_info("wolfSSL " LIBWOLFSSL_VERSION_STRING " cleanup complete.\n");
  60. #endif
  61. return ret;
  62. }
  63. #ifdef HAVE_LINUXKM_PIE_SUPPORT
  64. #ifdef DEBUG_LINUXKM_PIE_SUPPORT
  65. extern int wolfCrypt_PIE_first_function(void);
  66. extern int wolfCrypt_PIE_last_function(void);
  67. extern const unsigned int wolfCrypt_PIE_rodata_start[];
  68. extern const unsigned int wolfCrypt_PIE_rodata_end[];
  69. /* cheap portable ad-hoc hash function to confirm bitwise stability of the PIE
  70. * binary image.
  71. */
  72. static unsigned int hash_span(char *start, char *end) {
  73. unsigned int sum = 1;
  74. while (start < end) {
  75. unsigned int rotate_by;
  76. sum ^= *start++;
  77. rotate_by = (sum ^ (sum >> 5)) & 31;
  78. sum = (sum << rotate_by) | (sum >> (32 - rotate_by));
  79. }
  80. return sum;
  81. }
  82. #endif /* DEBUG_LINUXKM_PIE_SUPPORT */
  83. #ifdef USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE
  84. extern struct wolfssl_linuxkm_pie_redirect_table wolfssl_linuxkm_pie_redirect_table;
  85. static int set_up_wolfssl_linuxkm_pie_redirect_table(void);
  86. #endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
  87. #endif /* HAVE_LINUXKM_PIE_SUPPORT */
  88. #ifdef HAVE_FIPS
  89. static void lkmFipsCb(int ok, int err, const char* hash)
  90. {
  91. if ((! ok) || (err != 0))
  92. pr_err("libwolfssl FIPS error: %s\n", wc_GetErrorString(err));
  93. if (err == IN_CORE_FIPS_E) {
  94. pr_err("In-core integrity hash check failure.\n"
  95. "Update verifyCore[] in fips_test.c with new hash \"%s\" and rebuild.\n",
  96. hash ? hash : "<null>");
  97. }
  98. }
  99. #endif
  100. #ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
  101. #ifndef CONFIG_MODULE_SIG
  102. #error WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE requires a CONFIG_MODULE_SIG kernel.
  103. #endif
  104. static int updateFipsHash(void);
  105. #endif
  106. #ifdef WOLFSSL_LINUXKM_BENCHMARKS
  107. extern int wolfcrypt_benchmark_main(int argc, char** argv);
  108. #endif /* WOLFSSL_LINUXKM_BENCHMARKS */
  109. #ifdef LINUXKM_LKCAPI_REGISTER
  110. #include "linuxkm/lkcapi_glue.c"
  111. #endif
  112. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
  113. static int __init wolfssl_init(void)
  114. #else
  115. static int wolfssl_init(void)
  116. #endif
  117. {
  118. int ret;
  119. #ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
  120. if (THIS_MODULE->sig_ok == false) {
  121. pr_err("wolfSSL module load aborted -- bad or missing module signature with FIPS dynamic hash.\n");
  122. return -ECANCELED;
  123. }
  124. ret = updateFipsHash();
  125. if (ret < 0) {
  126. pr_err("wolfSSL module load aborted -- updateFipsHash: %s\n",wc_GetErrorString(ret));
  127. return -ECANCELED;
  128. }
  129. #endif
  130. #ifdef USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE
  131. ret = set_up_wolfssl_linuxkm_pie_redirect_table();
  132. if (ret < 0)
  133. return ret;
  134. #endif
  135. #if defined(HAVE_LINUXKM_PIE_SUPPORT) && defined(DEBUG_LINUXKM_PIE_SUPPORT)
  136. #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)
  137. /* see linux commit ac3b432839 */
  138. #define THIS_MODULE_TEXT_BASE (THIS_MODULE->mem[MOD_TEXT].base)
  139. #define THIS_MODULE_TEXT_SIZE (THIS_MODULE->mem[MOD_TEXT].size)
  140. #define THIS_MODULE_RO_BASE (THIS_MODULE->mem[MOD_RODATA].base)
  141. #define THIS_MODULE_RO_SIZE (THIS_MODULE->mem[MOD_RODATA].size)
  142. #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
  143. #define THIS_MODULE_TEXT_BASE (THIS_MODULE->core_layout.base)
  144. #define THIS_MODULE_TEXT_SIZE (THIS_MODULE->core_layout.text_size)
  145. #define THIS_MODULE_RO_BASE ((char *)THIS_MODULE->core_layout.base + THIS_MODULE->core_layout.text_size)
  146. #define THIS_MODULE_RO_SIZE (THIS_MODULE->core_layout.ro_size)
  147. #else
  148. #define THIS_MODULE_TEXT_BASE (THIS_MODULE->module_core)
  149. #define THIS_MODULE_TEXT_SIZE (THIS_MODULE->core_text_size)
  150. #define THIS_MODULE_RO_BASE ((char *)THIS_MODULE->module_core + THIS_MODULE->core_ro_size)
  151. #define THIS_MODULE_RO_SIZE (THIS_MODULE->core_ro_size)
  152. #endif
  153. {
  154. char *pie_text_start = (char *)wolfCrypt_PIE_first_function;
  155. char *pie_text_end = (char *)wolfCrypt_PIE_last_function;
  156. char *pie_rodata_start = (char *)wolfCrypt_PIE_rodata_start;
  157. char *pie_rodata_end = (char *)wolfCrypt_PIE_rodata_end;
  158. unsigned int text_hash, rodata_hash;
  159. if ((pie_text_start < pie_text_end) &&
  160. (pie_text_start >= (char *)THIS_MODULE_TEXT_BASE) &&
  161. (pie_text_end - (char *)THIS_MODULE_TEXT_BASE <= THIS_MODULE_TEXT_SIZE))
  162. {
  163. text_hash = hash_span(pie_text_start, pie_text_end);
  164. } else {
  165. pr_info("out-of-bounds PIE fenceposts! pie_text_start=%px pie_text_end=%px (span=%lu)"
  166. " core_layout.base=%px text_end=%px\n",
  167. pie_text_start,
  168. pie_text_end,
  169. pie_text_end-pie_text_start,
  170. THIS_MODULE_TEXT_BASE,
  171. (char *)THIS_MODULE_TEXT_BASE + THIS_MODULE_TEXT_SIZE);
  172. text_hash = 0;
  173. }
  174. if ((pie_rodata_start < pie_rodata_end) && // cppcheck-suppress comparePointers
  175. (pie_rodata_start >= (char *)THIS_MODULE_RO_BASE) &&
  176. (pie_rodata_end - (char *)THIS_MODULE_RO_BASE <= THIS_MODULE_RO_SIZE))
  177. {
  178. rodata_hash = hash_span(pie_rodata_start, pie_rodata_end);
  179. } else {
  180. pr_info("out-of-bounds PIE fenceposts! pie_rodata_start=%px pie_rodata_end=%px (span=%lu)"
  181. " core_layout.base+core_layout.text_size=%px rodata_end=%px\n",
  182. pie_rodata_start,
  183. pie_rodata_end,
  184. pie_rodata_end-pie_rodata_start,
  185. (char *)THIS_MODULE_RO_BASE,
  186. (char *)THIS_MODULE_RO_BASE + THIS_MODULE_RO_SIZE);
  187. rodata_hash = 0;
  188. }
  189. /* note, "%pK" conceals the actual layout information. "%px" exposes
  190. * the true module start address, which is potentially useful to an
  191. * attacker.
  192. */
  193. pr_info("wolfCrypt container hashes (spans): text 0x%x (%lu), rodata 0x%x (%lu)\n",
  194. text_hash, pie_text_end-pie_text_start,
  195. rodata_hash, pie_rodata_end-pie_rodata_start);
  196. }
  197. #endif /* HAVE_LINUXKM_PIE_SUPPORT && DEBUG_LINUXKM_PIE_SUPPORT */
  198. #ifdef HAVE_FIPS
  199. ret = wolfCrypt_SetCb_fips(lkmFipsCb);
  200. if (ret != 0) {
  201. pr_err("wolfCrypt_SetCb_fips() failed: %s\n", wc_GetErrorString(ret));
  202. return -ECANCELED;
  203. }
  204. fipsEntry();
  205. ret = wolfCrypt_GetStatus_fips();
  206. if (ret != 0) {
  207. pr_err("wolfCrypt_GetStatus_fips() failed: %s\n", wc_GetErrorString(ret));
  208. if (ret == IN_CORE_FIPS_E) {
  209. const char *newhash = wolfCrypt_GetCoreHash_fips();
  210. pr_err("Update verifyCore[] in fips_test.c with new hash \"%s\" and rebuild.\n",
  211. newhash ? newhash : "<null>");
  212. }
  213. return -ECANCELED;
  214. }
  215. pr_info("FIPS 140-3 wolfCrypt-fips v%d.%d.%d%s%s startup "
  216. "self-test succeeded.\n",
  217. #ifdef HAVE_FIPS_VERSION_MAJOR
  218. HAVE_FIPS_VERSION_MAJOR,
  219. #else
  220. HAVE_FIPS_VERSION,
  221. #endif
  222. #ifdef HAVE_FIPS_VERSION_MINOR
  223. HAVE_FIPS_VERSION_MINOR,
  224. #else
  225. 0,
  226. #endif
  227. #ifdef HAVE_FIPS_VERSION_PATCH
  228. HAVE_FIPS_VERSION_PATCH,
  229. #else
  230. 0,
  231. #endif
  232. #ifdef HAVE_FIPS_VERSION_PORT
  233. "-",
  234. HAVE_FIPS_VERSION_PORT
  235. #else
  236. "",
  237. ""
  238. #endif
  239. );
  240. #endif /* HAVE_FIPS */
  241. #ifdef WC_RNG_SEED_CB
  242. ret = wc_SetSeed_Cb(wc_GenerateSeed);
  243. if (ret < 0) {
  244. pr_err("wc_SetSeed_Cb() failed with return code %d.\n", ret);
  245. (void)libwolfssl_cleanup();
  246. msleep(10);
  247. return -ECANCELED;
  248. }
  249. #endif
  250. #ifdef WOLFCRYPT_ONLY
  251. ret = wolfCrypt_Init();
  252. if (ret != 0) {
  253. pr_err("wolfCrypt_Init() failed: %s\n", wc_GetErrorString(ret));
  254. return -ECANCELED;
  255. }
  256. #else
  257. ret = wolfSSL_Init();
  258. if (ret != WOLFSSL_SUCCESS) {
  259. pr_err("wolfSSL_Init() failed: %s\n", wc_GetErrorString(ret));
  260. return -ECANCELED;
  261. }
  262. #endif
  263. #ifndef NO_CRYPT_TEST
  264. ret = wolfcrypt_test(NULL);
  265. if (ret < 0) {
  266. pr_err("wolfcrypt self-test failed with return code %d.\n", ret);
  267. (void)libwolfssl_cleanup();
  268. msleep(10);
  269. return -ECANCELED;
  270. }
  271. pr_info("wolfCrypt self-test passed.\n");
  272. #else
  273. pr_info("skipping full wolfcrypt_test() "
  274. "(configure with --enable-crypttests to enable).\n");
  275. #endif
  276. #ifdef LINUXKM_LKCAPI_REGISTER
  277. ret = linuxkm_lkcapi_register();
  278. if (ret) {
  279. pr_err("linuxkm_lkcapi_register() failed with return code %d.\n", ret);
  280. linuxkm_lkcapi_unregister();
  281. (void)libwolfssl_cleanup();
  282. msleep(10);
  283. return -ECANCELED;
  284. }
  285. #endif
  286. #ifdef WOLFSSL_LINUXKM_BENCHMARKS
  287. wolfcrypt_benchmark_main(0, (char**)NULL);
  288. #endif
  289. #ifdef WOLFCRYPT_ONLY
  290. pr_info("wolfCrypt " LIBWOLFSSL_VERSION_STRING " loaded%s"
  291. ".\nSee https://www.wolfssl.com/ for more information.\n"
  292. "wolfCrypt Copyright (C) 2006-present wolfSSL Inc. Licensed under " WOLFSSL_LICENSE ".\n",
  293. #ifdef CONFIG_MODULE_SIG
  294. THIS_MODULE->sig_ok ? " with valid module signature" : " without valid module signature"
  295. #else
  296. ""
  297. #endif
  298. );
  299. #else
  300. pr_info("wolfSSL " LIBWOLFSSL_VERSION_STRING " loaded%s"
  301. ".\nSee https://www.wolfssl.com/ for more information.\n"
  302. "wolfSSL Copyright (C) 2006-present wolfSSL Inc. Licensed under " WOLFSSL_LICENSE ".\n",
  303. #ifdef CONFIG_MODULE_SIG
  304. THIS_MODULE->sig_ok ? " with valid module signature" : " without valid module signature"
  305. #else
  306. ""
  307. #endif
  308. );
  309. #endif
  310. return 0;
  311. }
  312. module_init(wolfssl_init);
  313. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
  314. static void __exit wolfssl_exit(void)
  315. #else
  316. static void wolfssl_exit(void)
  317. #endif
  318. {
  319. #ifdef LINUXKM_LKCAPI_REGISTER
  320. linuxkm_lkcapi_unregister();
  321. #endif
  322. (void)libwolfssl_cleanup();
  323. return;
  324. }
  325. module_exit(wolfssl_exit);
  326. MODULE_LICENSE(WOLFSSL_LICENSE);
  327. MODULE_AUTHOR("https://www.wolfssl.com/");
  328. MODULE_DESCRIPTION("libwolfssl cryptographic and protocol facilities");
  329. MODULE_VERSION(LIBWOLFSSL_VERSION_STRING);
  330. #ifdef USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE
  331. /* get_current() is an inline or macro, depending on the target -- sidestep the whole issue with a wrapper func. */
  332. static struct task_struct *my_get_current_thread(void) {
  333. return get_current();
  334. }
  335. /* ditto for preempt_count(). */
  336. static int my_preempt_count(void) {
  337. return preempt_count();
  338. }
  339. #if defined(WOLFSSL_LINUXKM_SIMD_X86) && defined(WOLFSSL_COMMERCIAL_LICENSE)
  340. /* ditto for fpregs_lock/fpregs_unlock */
  341. #ifdef WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS
  342. static void my_fpregs_lock(void) {
  343. fpregs_lock();
  344. }
  345. static void my_fpregs_unlock(void) {
  346. fpregs_unlock();
  347. }
  348. #endif /* WOLFSSL_LINUXKM_SIMD_X86 && WOLFSSL_COMMERCIAL_LICENSE */
  349. #endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
  350. static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
  351. memset(
  352. &wolfssl_linuxkm_pie_redirect_table,
  353. 0,
  354. sizeof wolfssl_linuxkm_pie_redirect_table);
  355. #ifndef __ARCH_MEMCMP_NO_REDIRECT
  356. wolfssl_linuxkm_pie_redirect_table.memcmp = memcmp;
  357. #endif
  358. #ifndef CONFIG_FORTIFY_SOURCE
  359. #ifndef __ARCH_MEMCPY_NO_REDIRECT
  360. wolfssl_linuxkm_pie_redirect_table.memcpy = memcpy;
  361. #endif
  362. #ifndef __ARCH_MEMSET_NO_REDIRECT
  363. wolfssl_linuxkm_pie_redirect_table.memset = memset;
  364. #endif
  365. #ifndef __ARCH_MEMMOVE_NO_REDIRECT
  366. wolfssl_linuxkm_pie_redirect_table.memmove = memmove;
  367. #endif
  368. #endif /* !CONFIG_FORTIFY_SOURCE */
  369. #ifndef __ARCH_STRCMP_NO_REDIRECT
  370. wolfssl_linuxkm_pie_redirect_table.strcmp = strcmp;
  371. #endif
  372. #ifndef __ARCH_STRNCMP_NO_REDIRECT
  373. wolfssl_linuxkm_pie_redirect_table.strncmp = strncmp;
  374. #endif
  375. #ifndef __ARCH_STRCASECMP_NO_REDIRECT
  376. wolfssl_linuxkm_pie_redirect_table.strcasecmp = strcasecmp;
  377. #endif
  378. #ifndef __ARCH_STRNCASECMP_NO_REDIRECT
  379. wolfssl_linuxkm_pie_redirect_table.strncasecmp = strncasecmp;
  380. #endif
  381. #ifndef __ARCH_STRLEN_NO_REDIRECT
  382. wolfssl_linuxkm_pie_redirect_table.strlen = strlen;
  383. #endif
  384. #ifndef __ARCH_STRSTR_NO_REDIRECT
  385. wolfssl_linuxkm_pie_redirect_table.strstr = strstr;
  386. #endif
  387. #ifndef __ARCH_STRNCPY_NO_REDIRECT
  388. wolfssl_linuxkm_pie_redirect_table.strncpy = strncpy;
  389. #endif
  390. #ifndef __ARCH_STRNCAT_NO_REDIRECT
  391. wolfssl_linuxkm_pie_redirect_table.strncat = strncat;
  392. #endif
  393. wolfssl_linuxkm_pie_redirect_table.kstrtoll = kstrtoll;
  394. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
  395. wolfssl_linuxkm_pie_redirect_table._printk = _printk;
  396. #else
  397. wolfssl_linuxkm_pie_redirect_table.printk = printk;
  398. #endif
  399. #ifdef CONFIG_FORTIFY_SOURCE
  400. wolfssl_linuxkm_pie_redirect_table.__warn_printk = __warn_printk;
  401. #endif
  402. wolfssl_linuxkm_pie_redirect_table.snprintf = snprintf;
  403. wolfssl_linuxkm_pie_redirect_table._ctype = _ctype;
  404. wolfssl_linuxkm_pie_redirect_table.kmalloc = kmalloc;
  405. wolfssl_linuxkm_pie_redirect_table.kfree = kfree;
  406. wolfssl_linuxkm_pie_redirect_table.ksize = ksize;
  407. wolfssl_linuxkm_pie_redirect_table.krealloc = krealloc;
  408. #ifdef HAVE_KVMALLOC
  409. wolfssl_linuxkm_pie_redirect_table.kvmalloc_node = kvmalloc_node;
  410. wolfssl_linuxkm_pie_redirect_table.kvfree = kvfree;
  411. #endif
  412. wolfssl_linuxkm_pie_redirect_table.is_vmalloc_addr = is_vmalloc_addr;
  413. #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
  414. wolfssl_linuxkm_pie_redirect_table.kmalloc_trace =
  415. kmalloc_trace;
  416. #else
  417. wolfssl_linuxkm_pie_redirect_table.kmem_cache_alloc_trace =
  418. kmem_cache_alloc_trace;
  419. wolfssl_linuxkm_pie_redirect_table.kmalloc_order_trace =
  420. kmalloc_order_trace;
  421. #endif
  422. wolfssl_linuxkm_pie_redirect_table.get_random_bytes = get_random_bytes;
  423. #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
  424. wolfssl_linuxkm_pie_redirect_table.getnstimeofday =
  425. getnstimeofday;
  426. #elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
  427. wolfssl_linuxkm_pie_redirect_table.current_kernel_time64 =
  428. current_kernel_time64;
  429. #else
  430. wolfssl_linuxkm_pie_redirect_table.ktime_get_coarse_real_ts64 =
  431. ktime_get_coarse_real_ts64;
  432. #endif
  433. wolfssl_linuxkm_pie_redirect_table.get_current = my_get_current_thread;
  434. wolfssl_linuxkm_pie_redirect_table.preempt_count = my_preempt_count;
  435. #ifdef WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS
  436. #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)
  437. wolfssl_linuxkm_pie_redirect_table.cpu_number = &cpu_number;
  438. #else
  439. wolfssl_linuxkm_pie_redirect_table.pcpu_hot = &pcpu_hot;
  440. #endif
  441. wolfssl_linuxkm_pie_redirect_table.nr_cpu_ids = &nr_cpu_ids;
  442. #if defined(CONFIG_SMP) && \
  443. (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) && \
  444. !defined(WOLFSSL_COMMERCIAL_LICENSE)
  445. wolfssl_linuxkm_pie_redirect_table.migrate_disable = &migrate_disable;
  446. wolfssl_linuxkm_pie_redirect_table.migrate_enable = &migrate_enable;
  447. #endif
  448. #ifdef WOLFSSL_LINUXKM_SIMD_X86
  449. wolfssl_linuxkm_pie_redirect_table.irq_fpu_usable = irq_fpu_usable;
  450. #ifdef WOLFSSL_COMMERCIAL_LICENSE
  451. wolfssl_linuxkm_pie_redirect_table.fpregs_lock = my_fpregs_lock;
  452. wolfssl_linuxkm_pie_redirect_table.fpregs_unlock = my_fpregs_unlock;
  453. #else /* !defined(WOLFSSL_COMMERCIAL_LICENSE) */
  454. #ifdef kernel_fpu_begin
  455. wolfssl_linuxkm_pie_redirect_table.kernel_fpu_begin_mask =
  456. kernel_fpu_begin_mask;
  457. #else
  458. wolfssl_linuxkm_pie_redirect_table.kernel_fpu_begin =
  459. kernel_fpu_begin;
  460. #endif
  461. wolfssl_linuxkm_pie_redirect_table.kernel_fpu_end = kernel_fpu_end;
  462. #endif /* !defined(WOLFSSL_COMMERCIAL_LICENSE) */
  463. #endif /* WOLFSSL_LINUXKM_SIMD_X86 */
  464. #endif /* WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS */
  465. wolfssl_linuxkm_pie_redirect_table.__mutex_init = __mutex_init;
  466. #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
  467. wolfssl_linuxkm_pie_redirect_table.mutex_lock_nested = mutex_lock_nested;
  468. #else
  469. wolfssl_linuxkm_pie_redirect_table.mutex_lock = mutex_lock;
  470. #endif
  471. wolfssl_linuxkm_pie_redirect_table.mutex_unlock = mutex_unlock;
  472. #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
  473. wolfssl_linuxkm_pie_redirect_table.mutex_destroy = mutex_destroy;
  474. #endif
  475. #ifdef HAVE_FIPS
  476. wolfssl_linuxkm_pie_redirect_table.wolfCrypt_FIPS_first =
  477. wolfCrypt_FIPS_first;
  478. wolfssl_linuxkm_pie_redirect_table.wolfCrypt_FIPS_last =
  479. wolfCrypt_FIPS_last;
  480. #endif
  481. #if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS)
  482. wolfssl_linuxkm_pie_redirect_table.GetCA = GetCA;
  483. #ifndef NO_SKID
  484. wolfssl_linuxkm_pie_redirect_table.GetCAByName = GetCAByName;
  485. #endif
  486. #endif
  487. /* runtime assert that the table has no null slots after initialization. */
  488. {
  489. unsigned long *i;
  490. static_assert(sizeof(unsigned long) == sizeof(void *),
  491. "unexpected pointer size");
  492. for (i = (unsigned long *)&wolfssl_linuxkm_pie_redirect_table;
  493. i < (unsigned long *)&wolfssl_linuxkm_pie_redirect_table._last_slot;
  494. ++i)
  495. if (*i == 0) {
  496. pr_err("wolfCrypt container redirect table initialization was "
  497. "incomplete [%lu].\n",
  498. i-(unsigned long *)&wolfssl_linuxkm_pie_redirect_table);
  499. return -EFAULT;
  500. }
  501. }
  502. return 0;
  503. }
  504. #endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
  505. #ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
  506. #include <wolfssl/wolfcrypt/coding.h>
  507. PRAGMA_GCC_DIAG_PUSH
  508. PRAGMA_GCC("GCC diagnostic ignored \"-Wnested-externs\"")
  509. PRAGMA_GCC("GCC diagnostic ignored \"-Wpointer-arith\"")
  510. #include <crypto/hash.h>
  511. PRAGMA_GCC_DIAG_POP
  512. extern char verifyCore[WC_SHA256_DIGEST_SIZE*2 + 1];
  513. extern const char coreKey[WC_SHA256_DIGEST_SIZE*2 + 1];
  514. extern const unsigned int wolfCrypt_FIPS_ro_start[];
  515. extern const unsigned int wolfCrypt_FIPS_ro_end[];
  516. #define FIPS_IN_CORE_KEY_SZ 32
  517. #define FIPS_IN_CORE_VERIFY_SZ FIPS_IN_CORE_KEY_SZ
  518. typedef int (*fips_address_function)(void);
  519. #define MAX_FIPS_DATA_SZ 100000
  520. #define MAX_FIPS_CODE_SZ 1000000
  521. extern int GenBase16_Hash(const byte* in, int length, char* out, int outSz);
  522. static int updateFipsHash(void)
  523. {
  524. struct crypto_shash *tfm = NULL;
  525. struct shash_desc *desc = NULL;
  526. word32 verifySz = FIPS_IN_CORE_VERIFY_SZ;
  527. word32 binCoreSz = FIPS_IN_CORE_KEY_SZ;
  528. int ret;
  529. byte *hash = NULL;
  530. char *base16_hash = NULL;
  531. byte *binCoreKey = NULL;
  532. byte *binVerify = NULL;
  533. fips_address_function first = wolfCrypt_FIPS_first;
  534. fips_address_function last = wolfCrypt_FIPS_last;
  535. char* start = (char*)wolfCrypt_FIPS_ro_start;
  536. char* end = (char*)wolfCrypt_FIPS_ro_end;
  537. unsigned long code_sz = (unsigned long)last - (unsigned long)first;
  538. unsigned long data_sz = (unsigned long)end - (unsigned long)start;
  539. if (data_sz == 0 || data_sz > MAX_FIPS_DATA_SZ)
  540. return BAD_FUNC_ARG; /* bad fips data size */
  541. if (code_sz == 0 || code_sz > MAX_FIPS_CODE_SZ)
  542. return BAD_FUNC_ARG; /* bad fips code size */
  543. hash = XMALLOC(WC_SHA256_DIGEST_SIZE, 0, DYNAMIC_TYPE_TMP_BUFFER);
  544. if (hash == NULL) {
  545. ret = MEMORY_E;
  546. goto out;
  547. }
  548. base16_hash = XMALLOC(WC_SHA256_DIGEST_SIZE*2 + 1, 0, DYNAMIC_TYPE_TMP_BUFFER);
  549. if (base16_hash == NULL) {
  550. ret = MEMORY_E;
  551. goto out;
  552. }
  553. binCoreKey = XMALLOC(binCoreSz, 0, DYNAMIC_TYPE_TMP_BUFFER);
  554. if (binCoreKey == NULL) {
  555. ret = MEMORY_E;
  556. goto out;
  557. }
  558. binVerify = XMALLOC(verifySz, 0, DYNAMIC_TYPE_TMP_BUFFER);
  559. if (binVerify == NULL) {
  560. ret = MEMORY_E;
  561. goto out;
  562. }
  563. {
  564. word32 base16_out_len = binCoreSz;
  565. ret = Base16_Decode((const byte *)coreKey, sizeof coreKey - 1, binCoreKey, &base16_out_len);
  566. if (ret != 0) {
  567. pr_err("Base16_Decode for coreKey: %s\n", wc_GetErrorString(ret));
  568. goto out;
  569. }
  570. if (base16_out_len != binCoreSz) {
  571. pr_err("unexpected output length %u for coreKey from Base16_Decode.\n",base16_out_len);
  572. ret = BAD_STATE_E;
  573. goto out;
  574. }
  575. }
  576. tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
  577. if (IS_ERR(tfm)) {
  578. if (PTR_ERR(tfm) == -ENOMEM) {
  579. pr_err("crypto_alloc_shash failed: out of memory\n");
  580. ret = MEMORY_E;
  581. } else if (PTR_ERR(tfm) == -ENOENT) {
  582. pr_err("crypto_alloc_shash failed: kernel is missing hmac(sha256) implementation\n");
  583. pr_err("check for CONFIG_CRYPTO_SHA256 and CONFIG_CRYPTO_HMAC.\n");
  584. ret = NOT_COMPILED_IN;
  585. } else {
  586. pr_err("crypto_alloc_shash failed with ret %ld\n",PTR_ERR(tfm));
  587. ret = HASH_TYPE_E;
  588. }
  589. tfm = NULL;
  590. goto out;
  591. }
  592. {
  593. size_t desc_size = crypto_shash_descsize(tfm) + sizeof *desc;
  594. desc = XMALLOC(desc_size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  595. if (desc == NULL) {
  596. pr_err("failed allocating desc.");
  597. ret = MEMORY_E;
  598. goto out;
  599. }
  600. XMEMSET(desc, 0, desc_size);
  601. }
  602. ret = crypto_shash_setkey(tfm, binCoreKey, binCoreSz);
  603. if (ret) {
  604. pr_err("crypto_ahash_setkey failed: err %d\n", ret);
  605. ret = BAD_STATE_E;
  606. goto out;
  607. }
  608. desc->tfm = tfm;
  609. ret = crypto_shash_init(desc);
  610. if (ret) {
  611. pr_err("crypto_shash_init failed: err %d\n", ret);
  612. ret = BAD_STATE_E;
  613. goto out;
  614. }
  615. ret = crypto_shash_update(desc, (byte *)(wc_ptr_t)first, (word32)code_sz);
  616. if (ret) {
  617. pr_err("crypto_shash_update failed: err %d\n", ret);
  618. ret = BAD_STATE_E;
  619. goto out;
  620. }
  621. /* don't hash verifyCore or changing verifyCore will change hash */
  622. if (verifyCore >= start && verifyCore < end) {
  623. data_sz = (unsigned long)verifyCore - (unsigned long)start;
  624. ret = crypto_shash_update(desc, (byte*)start, (word32)data_sz);
  625. if (ret) {
  626. pr_err("crypto_shash_update failed: err %d\n", ret);
  627. ret = BAD_STATE_E;
  628. goto out;
  629. }
  630. start = (char*)verifyCore + sizeof(verifyCore);
  631. data_sz = (unsigned long)end - (unsigned long)start;
  632. }
  633. ret = crypto_shash_update(desc, (byte*)start, (word32)data_sz);
  634. if (ret) {
  635. pr_err("crypto_shash_update failed: err %d\n", ret);
  636. ret = BAD_STATE_E;
  637. goto out;
  638. }
  639. ret = crypto_shash_final(desc, hash);
  640. if (ret) {
  641. pr_err("crypto_shash_final failed: err %d\n", ret);
  642. ret = BAD_STATE_E;
  643. goto out;
  644. }
  645. ret = GenBase16_Hash(hash, WC_SHA256_DIGEST_SIZE, base16_hash, WC_SHA256_DIGEST_SIZE*2 + 1);
  646. if (ret != 0) {
  647. pr_err("GenBase16_Hash failed: %s\n", wc_GetErrorString(ret));
  648. goto out;
  649. }
  650. {
  651. word32 base16_out_len = verifySz;
  652. ret = Base16_Decode((const byte *)verifyCore, sizeof verifyCore - 1, binVerify, &base16_out_len);
  653. if (ret != 0) {
  654. pr_err("Base16_Decode for verifyCore: %s\n", wc_GetErrorString(ret));
  655. goto out;
  656. }
  657. if (base16_out_len != binCoreSz) {
  658. pr_err("unexpected output length %u for verifyCore from Base16_Decode.\n",base16_out_len);
  659. ret = BAD_STATE_E;
  660. goto out;
  661. }
  662. }
  663. if (XMEMCMP(hash, binVerify, WC_SHA256_DIGEST_SIZE) == 0) {
  664. #if defined(DEBUG_LINUXKM_PIE_SUPPORT) || defined(WOLFSSL_LINUXKM_VERBOSE_DEBUG)
  665. pr_info("updateFipsHash: verifyCore already matches [%s]\n", verifyCore);
  666. #else
  667. pr_info("updateFipsHash: verifyCore already matches.\n");
  668. #endif
  669. } else {
  670. XMEMCPY(verifyCore, base16_hash, WC_SHA256_DIGEST_SIZE*2 + 1);
  671. #if defined(DEBUG_LINUXKM_PIE_SUPPORT) || defined(WOLFSSL_LINUXKM_VERBOSE_DEBUG)
  672. pr_info("updateFipsHash: verifyCore updated [%s].\n", base16_hash);
  673. #else
  674. pr_info("updateFipsHash: verifyCore updated.\n");
  675. #endif
  676. }
  677. ret = 0;
  678. out:
  679. if (tfm != NULL)
  680. crypto_free_shash(tfm);
  681. if (desc != NULL)
  682. XFREE(desc, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  683. if (hash != NULL)
  684. XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  685. if (base16_hash != NULL)
  686. XFREE(base16_hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  687. if (binCoreKey != NULL)
  688. XFREE(binCoreKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  689. if (binVerify != NULL)
  690. XFREE(binVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  691. return ret;
  692. }
  693. #endif /* WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE */