qcrypto_fips.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /* Qcrypto: FIPS 140-2 Selftests
  2. *
  3. * Copyright (c) 2014, The Linux Foundation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 and
  7. * only version 2 as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/interrupt.h>
  15. #include <linux/miscdevice.h>
  16. #include <crypto/hash.h>
  17. #include <crypto/ctr.h>
  18. #include <crypto/des.h>
  19. #include <crypto/aes.h>
  20. #include <crypto/sha.h>
  21. #include <crypto/hash.h>
  22. #include <crypto/algapi.h>
  23. #include <crypto/aead.h>
  24. #include <crypto/authenc.h>
  25. #include <crypto/scatterwalk.h>
  26. #include <crypto/internal/hash.h>
  27. #include <linux/platform_data/qcom_crypto_device.h>
  28. #include <mach/qcrypto.h>
  29. #include "qcryptoi.h"
  30. #include "qcrypto_fips.h"
  31. /*
  32. * Callback function
  33. */
  34. static void _fips_cb(struct crypto_async_request *crypto_async_req, int err)
  35. {
  36. struct _fips_completion *fips_completion = crypto_async_req->data;
  37. if (err == -EINPROGRESS)
  38. return;
  39. fips_completion->err = err;
  40. complete(&fips_completion->completion);
  41. }
  42. /*
  43. * Function to prefix if needed
  44. */
  45. static int _fips_get_alg_cra_name(char cra_name[],
  46. char *prefix, unsigned int size)
  47. {
  48. char new_cra_name[CRYPTO_MAX_ALG_NAME];
  49. strlcpy(new_cra_name, prefix, CRYPTO_MAX_ALG_NAME);
  50. if (CRYPTO_MAX_ALG_NAME < size + strlen(prefix))
  51. return -EINVAL;
  52. strlcat(new_cra_name, cra_name, CRYPTO_MAX_ALG_NAME);
  53. strlcpy(cra_name, new_cra_name, CRYPTO_MAX_ALG_NAME);
  54. return 0;
  55. }
  56. /*
  57. * Sha/HMAC self tests
  58. */
  59. int _fips_qcrypto_sha_selftest(struct fips_selftest_data *selftest_d)
  60. {
  61. int rc = 0, err, tv_index = 0, num_tv;
  62. char *k_out_buf = NULL;
  63. struct scatterlist fips_sg;
  64. struct crypto_ahash *tfm;
  65. struct ahash_request *ahash_req;
  66. struct _fips_completion fips_completion;
  67. struct _fips_test_vector_sha_hmac tv_sha_hmac;
  68. num_tv = (sizeof(fips_test_vector_sha_hmac)) /
  69. (sizeof(struct _fips_test_vector_sha_hmac));
  70. /* One-by-one testing */
  71. for (tv_index = 0; tv_index < num_tv; tv_index++) {
  72. memcpy(&tv_sha_hmac, &fips_test_vector_sha_hmac[tv_index],
  73. (sizeof(struct _fips_test_vector_sha_hmac)));
  74. k_out_buf = kzalloc(tv_sha_hmac.diglen, GFP_KERNEL);
  75. if (k_out_buf == NULL) {
  76. pr_err("qcrypto: Failed to allocate memory for k_out_buf %ld\n",
  77. PTR_ERR(k_out_buf));
  78. return -ENOMEM;
  79. }
  80. memset(k_out_buf, 0, tv_sha_hmac.diglen);
  81. init_completion(&fips_completion.completion);
  82. /* use_sw flags are set in dtsi file which makes
  83. default Linux API calls to go to s/w crypto instead
  84. of h/w crypto. This code makes sure that all selftests
  85. calls always go to h/w, independent of DTSI flags. */
  86. if (tv_sha_hmac.klen == 0) {
  87. if (selftest_d->prefix_ahash_algo)
  88. if (_fips_get_alg_cra_name(tv_sha_hmac
  89. .hash_alg, selftest_d->algo_prefix,
  90. strlen(tv_sha_hmac.hash_alg))) {
  91. rc = -1;
  92. pr_err("Algo Name is too long for tv %d\n",
  93. tv_index);
  94. goto clr_buf;
  95. }
  96. } else {
  97. if (selftest_d->prefix_hmac_algo)
  98. if (_fips_get_alg_cra_name(tv_sha_hmac
  99. .hash_alg, selftest_d->algo_prefix,
  100. strlen(tv_sha_hmac.hash_alg))) {
  101. rc = -1;
  102. pr_err("Algo Name is too long for tv %d\n",
  103. tv_index);
  104. goto clr_buf;
  105. }
  106. }
  107. tfm = crypto_alloc_ahash(tv_sha_hmac.hash_alg, 0, 0);
  108. if (IS_ERR(tfm)) {
  109. pr_err("qcrypto: %s algorithm not found\n",
  110. tv_sha_hmac.hash_alg);
  111. rc = PTR_ERR(tfm);
  112. goto clr_buf;
  113. }
  114. ahash_req = ahash_request_alloc(tfm, GFP_KERNEL);
  115. if (!ahash_req) {
  116. pr_err("qcrypto: ahash_request_alloc failed\n");
  117. rc = -ENOMEM;
  118. goto clr_tfm;
  119. }
  120. rc = qcrypto_ahash_set_device(ahash_req, selftest_d->ce_device);
  121. if (rc != 0) {
  122. pr_err("%s qcrypto_cipher_set_device failed with err %d\n",
  123. __func__, rc);
  124. goto clr_ahash_req;
  125. }
  126. ahash_request_set_callback(ahash_req,
  127. CRYPTO_TFM_REQ_MAY_BACKLOG,
  128. _fips_cb, &fips_completion);
  129. sg_init_one(&fips_sg, &tv_sha_hmac.input[0], tv_sha_hmac.ilen);
  130. crypto_ahash_clear_flags(tfm, ~0);
  131. if (tv_sha_hmac.klen != 0) {
  132. rc = crypto_ahash_setkey(tfm, tv_sha_hmac.key,
  133. tv_sha_hmac.klen);
  134. if (rc) {
  135. pr_err("qcrypto: crypto_ahash_setkey failed\n");
  136. goto clr_ahash_req;
  137. }
  138. }
  139. ahash_request_set_crypt(ahash_req, &fips_sg, k_out_buf,
  140. tv_sha_hmac.ilen);
  141. rc = crypto_ahash_digest(ahash_req);
  142. if (rc == -EINPROGRESS || rc == -EBUSY) {
  143. rc = wait_for_completion_interruptible(
  144. &fips_completion.completion);
  145. err = fips_completion.err;
  146. if (!rc && !err) {
  147. INIT_COMPLETION(fips_completion.completion);
  148. } else {
  149. pr_err("qcrypto:SHA: wait_for_completion failed\n");
  150. goto clr_ahash_req;
  151. }
  152. }
  153. if (memcmp(k_out_buf, tv_sha_hmac.digest,
  154. tv_sha_hmac.diglen))
  155. rc = -1;
  156. clr_ahash_req:
  157. ahash_request_free(ahash_req);
  158. clr_tfm:
  159. crypto_free_ahash(tfm);
  160. clr_buf:
  161. kzfree(k_out_buf);
  162. /* For any failure, return error */
  163. if (rc)
  164. return rc;
  165. }
  166. return rc;
  167. }
  168. /*
  169. * Cipher algorithm self tests
  170. */
  171. int _fips_qcrypto_cipher_selftest(struct fips_selftest_data *selftest_d)
  172. {
  173. int rc = 0, err, tv_index, num_tv;
  174. struct crypto_ablkcipher *tfm;
  175. struct ablkcipher_request *ablkcipher_req;
  176. struct _fips_completion fips_completion;
  177. char *k_align_src = NULL;
  178. struct scatterlist fips_sg;
  179. struct _fips_test_vector_cipher tv_cipher;
  180. num_tv = (sizeof(fips_test_vector_cipher)) /
  181. (sizeof(struct _fips_test_vector_cipher));
  182. /* One-by-one testing */
  183. for (tv_index = 0; tv_index < num_tv; tv_index++) {
  184. memcpy(&tv_cipher, &fips_test_vector_cipher[tv_index],
  185. (sizeof(struct _fips_test_vector_cipher)));
  186. /* Single buffer allocation for in place operation */
  187. k_align_src = kzalloc(tv_cipher.pln_txt_len, GFP_KERNEL);
  188. if (k_align_src == NULL) {
  189. pr_err("qcrypto:, Failed to allocate memory for k_align_src %ld\n",
  190. PTR_ERR(k_align_src));
  191. return -ENOMEM;
  192. }
  193. memcpy(&k_align_src[0], tv_cipher.pln_txt,
  194. tv_cipher.pln_txt_len);
  195. /* use_sw flags are set in dtsi file which makes
  196. default Linux API calls to go to s/w crypto instead
  197. of h/w crypto. This code makes sure that all selftests
  198. calls always go to h/w, independent of DTSI flags. */
  199. if (!strcmp(tv_cipher.mod_alg, "xts(aes)")) {
  200. if (selftest_d->prefix_aes_xts_algo)
  201. if (_fips_get_alg_cra_name(
  202. tv_cipher.mod_alg,
  203. selftest_d->algo_prefix,
  204. strlen(tv_cipher.mod_alg))) {
  205. rc = -1;
  206. pr_err("Algo Name is too long for tv %d\n",
  207. tv_index);
  208. goto clr_buf;
  209. }
  210. } else {
  211. if (selftest_d->prefix_aes_cbc_ecb_ctr_algo)
  212. if (_fips_get_alg_cra_name(
  213. tv_cipher.mod_alg,
  214. selftest_d->algo_prefix,
  215. strlen(tv_cipher.mod_alg))) {
  216. rc = -1;
  217. pr_err("Algo Name is too long for tv %d\n",
  218. tv_index);
  219. goto clr_buf;
  220. }
  221. }
  222. tfm = crypto_alloc_ablkcipher(tv_cipher.mod_alg, 0, 0);
  223. if (IS_ERR(tfm)) {
  224. pr_err("qcrypto: %s algorithm not found\n",
  225. tv_cipher.mod_alg);
  226. rc = -ENOMEM;
  227. goto clr_buf;
  228. }
  229. ablkcipher_req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
  230. if (!ablkcipher_req) {
  231. pr_err("qcrypto: ablkcipher_request_alloc failed\n");
  232. rc = -ENOMEM;
  233. goto clr_tfm;
  234. }
  235. rc = qcrypto_cipher_set_device(ablkcipher_req,
  236. selftest_d->ce_device);
  237. if (rc != 0) {
  238. pr_err("%s qcrypto_cipher_set_device failed with err %d\n",
  239. __func__, rc);
  240. goto clr_ablkcipher_req;
  241. }
  242. ablkcipher_request_set_callback(ablkcipher_req,
  243. CRYPTO_TFM_REQ_MAY_BACKLOG,
  244. _fips_cb, &fips_completion);
  245. crypto_ablkcipher_clear_flags(tfm, ~0);
  246. rc = crypto_ablkcipher_setkey(tfm, tv_cipher.key,
  247. tv_cipher.klen);
  248. if (rc) {
  249. pr_err("qcrypto: crypto_ablkcipher_setkey failed\n");
  250. goto clr_ablkcipher_req;
  251. }
  252. sg_set_buf(&fips_sg, k_align_src, tv_cipher.enc_txt_len);
  253. sg_mark_end(&fips_sg);
  254. ablkcipher_request_set_crypt(ablkcipher_req,
  255. &fips_sg, &fips_sg, tv_cipher.pln_txt_len,
  256. tv_cipher.iv);
  257. /**** Encryption Test ****/
  258. init_completion(&fips_completion.completion);
  259. rc = crypto_ablkcipher_encrypt(ablkcipher_req);
  260. if (rc == -EINPROGRESS || rc == -EBUSY) {
  261. rc = wait_for_completion_interruptible(
  262. &fips_completion.completion);
  263. err = fips_completion.err;
  264. if (!rc && !err) {
  265. INIT_COMPLETION(fips_completion.completion);
  266. } else {
  267. pr_err("qcrypto:cipher:ENC, wait_for_completion failed\n");
  268. goto clr_ablkcipher_req;
  269. }
  270. }
  271. if (memcmp(k_align_src, tv_cipher.enc_txt,
  272. tv_cipher.enc_txt_len)) {
  273. rc = -1;
  274. goto clr_ablkcipher_req;
  275. }
  276. /**** Decryption test ****/
  277. init_completion(&fips_completion.completion);
  278. rc = crypto_ablkcipher_decrypt(ablkcipher_req);
  279. if (rc == -EINPROGRESS || rc == -EBUSY) {
  280. rc = wait_for_completion_interruptible(
  281. &fips_completion.completion);
  282. err = fips_completion.err;
  283. if (!rc && !err) {
  284. INIT_COMPLETION(fips_completion.completion);
  285. } else {
  286. pr_err("qcrypto:cipher:DEC, wait_for_completion failed\n");
  287. goto clr_ablkcipher_req;
  288. }
  289. }
  290. if (memcmp(k_align_src, tv_cipher.pln_txt,
  291. tv_cipher.pln_txt_len))
  292. rc = -1;
  293. clr_ablkcipher_req:
  294. ablkcipher_request_free(ablkcipher_req);
  295. clr_tfm:
  296. crypto_free_ablkcipher(tfm);
  297. clr_buf:
  298. kzfree(k_align_src);
  299. if (rc)
  300. return rc;
  301. }
  302. return rc;
  303. }
  304. /*
  305. * AEAD algorithm self tests
  306. */
  307. int _fips_qcrypto_aead_selftest(struct fips_selftest_data *selftest_d)
  308. {
  309. int rc = 0, err, tv_index, num_tv, authsize, buf_length;
  310. struct crypto_aead *tfm;
  311. struct aead_request *aead_req;
  312. struct _fips_completion fips_completion;
  313. struct scatterlist fips_sg, fips_assoc_sg;
  314. char *k_align_src = NULL;
  315. struct _fips_test_vector_aead tv_aead;
  316. num_tv = (sizeof(fips_test_vector_aead)) /
  317. (sizeof(struct _fips_test_vector_aead));
  318. /* One-by-one testing */
  319. for (tv_index = 0; tv_index < num_tv; tv_index++) {
  320. memcpy(&tv_aead, &fips_test_vector_aead[tv_index],
  321. (sizeof(struct _fips_test_vector_aead)));
  322. if (tv_aead.pln_txt_len > tv_aead.enc_txt_len)
  323. buf_length = tv_aead.pln_txt_len;
  324. else
  325. buf_length = tv_aead.enc_txt_len;
  326. /* Single buffer allocation for in place operation */
  327. k_align_src = kzalloc(buf_length, GFP_KERNEL);
  328. if (k_align_src == NULL) {
  329. pr_err("qcrypto:, Failed to allocate memory for k_align_src %ld\n",
  330. PTR_ERR(k_align_src));
  331. return -ENOMEM;
  332. }
  333. memcpy(&k_align_src[0], tv_aead.pln_txt,
  334. tv_aead.pln_txt_len);
  335. /* use_sw flags are set in dtsi file which makes
  336. default Linux API calls to go to s/w crypto instead
  337. of h/w crypto. This code makes sure that all selftests
  338. calls always go to h/w, independent of DTSI flags. */
  339. if (selftest_d->prefix_aead_algo) {
  340. if (_fips_get_alg_cra_name(tv_aead.mod_alg,
  341. selftest_d->algo_prefix,
  342. strlen(tv_aead.mod_alg))) {
  343. rc = -1;
  344. pr_err("Algo Name is too long for tv %d\n",
  345. tv_index);
  346. goto clr_buf;
  347. }
  348. }
  349. tfm = crypto_alloc_aead(tv_aead.mod_alg, 0, 0);
  350. if (IS_ERR(tfm)) {
  351. pr_err("qcrypto: %s algorithm not found\n",
  352. tv_aead.mod_alg);
  353. rc = -ENOMEM;
  354. goto clr_buf;
  355. }
  356. aead_req = aead_request_alloc(tfm, GFP_KERNEL);
  357. if (!aead_req) {
  358. pr_err("qcrypto:aead_request_alloc failed\n");
  359. rc = -ENOMEM;
  360. goto clr_tfm;
  361. }
  362. rc = qcrypto_aead_set_device(aead_req, selftest_d->ce_device);
  363. if (rc != 0) {
  364. pr_err("%s qcrypto_cipher_set_device failed with err %d\n",
  365. __func__, rc);
  366. goto clr_aead_req;
  367. }
  368. init_completion(&fips_completion.completion);
  369. aead_request_set_callback(aead_req,
  370. CRYPTO_TFM_REQ_MAY_BACKLOG,
  371. _fips_cb, &fips_completion);
  372. crypto_aead_clear_flags(tfm, ~0);
  373. rc = crypto_aead_setkey(tfm, tv_aead.key, tv_aead.klen);
  374. if (rc) {
  375. pr_err("qcrypto:crypto_aead_setkey failed\n");
  376. goto clr_aead_req;
  377. }
  378. authsize = abs(tv_aead.enc_txt_len - tv_aead.pln_txt_len);
  379. rc = crypto_aead_setauthsize(tfm, authsize);
  380. if (rc) {
  381. pr_err("qcrypto:crypto_aead_setauthsize failed\n");
  382. goto clr_aead_req;
  383. }
  384. sg_init_one(&fips_sg, k_align_src,
  385. tv_aead.pln_txt_len + authsize);
  386. aead_request_set_crypt(aead_req, &fips_sg, &fips_sg,
  387. tv_aead.pln_txt_len , tv_aead.iv);
  388. sg_init_one(&fips_assoc_sg, tv_aead.assoc, tv_aead.alen);
  389. aead_request_set_assoc(aead_req, &fips_assoc_sg, tv_aead.alen);
  390. /**** Encryption test ****/
  391. rc = crypto_aead_encrypt(aead_req);
  392. if (rc == -EINPROGRESS || rc == -EBUSY) {
  393. rc = wait_for_completion_interruptible(
  394. &fips_completion.completion);
  395. err = fips_completion.err;
  396. if (!rc && !err) {
  397. INIT_COMPLETION(fips_completion.completion);
  398. } else {
  399. pr_err("qcrypto:aead:ENC, wait_for_completion failed\n");
  400. goto clr_aead_req;
  401. }
  402. }
  403. if (memcmp(k_align_src, tv_aead.enc_txt, tv_aead.enc_txt_len)) {
  404. rc = -1;
  405. goto clr_aead_req;
  406. }
  407. /** Decryption test **/
  408. init_completion(&fips_completion.completion);
  409. aead_request_set_callback(aead_req,
  410. CRYPTO_TFM_REQ_MAY_BACKLOG,
  411. _fips_cb, &fips_completion);
  412. crypto_aead_clear_flags(tfm, ~0);
  413. rc = crypto_aead_setkey(tfm, tv_aead.key, tv_aead.klen);
  414. if (rc) {
  415. pr_err("qcrypto:aead:DEC, crypto_aead_setkey failed\n");
  416. goto clr_aead_req;
  417. }
  418. authsize = abs(tv_aead.enc_txt_len - tv_aead.pln_txt_len);
  419. rc = crypto_aead_setauthsize(tfm, authsize);
  420. if (rc) {
  421. pr_err("qcrypto:aead:DEC, crypto_aead_setauthsize failed\n");
  422. goto clr_aead_req;
  423. }
  424. sg_init_one(&fips_sg, k_align_src,
  425. tv_aead.enc_txt_len + authsize);
  426. aead_request_set_crypt(aead_req, &fips_sg, &fips_sg,
  427. tv_aead.enc_txt_len, tv_aead.iv);
  428. sg_init_one(&fips_assoc_sg, tv_aead.assoc, tv_aead.alen);
  429. aead_request_set_assoc(aead_req, &fips_assoc_sg,
  430. tv_aead.alen);
  431. rc = crypto_aead_decrypt(aead_req);
  432. if (rc == -EINPROGRESS || rc == -EBUSY) {
  433. rc = wait_for_completion_interruptible(
  434. &fips_completion.completion);
  435. err = fips_completion.err;
  436. if (!rc && !err) {
  437. INIT_COMPLETION(fips_completion.completion);
  438. } else {
  439. pr_err("qcrypto:aead:DEC, wait_for_completion failed\n");
  440. goto clr_aead_req;
  441. }
  442. }
  443. if (memcmp(k_align_src, tv_aead.pln_txt, tv_aead.pln_txt_len)) {
  444. rc = -1;
  445. goto clr_aead_req;
  446. }
  447. clr_aead_req:
  448. aead_request_free(aead_req);
  449. clr_tfm:
  450. crypto_free_aead(tfm);
  451. clr_buf:
  452. kzfree(k_align_src);
  453. /* In case of any failure, return error */
  454. if (rc)
  455. return rc;
  456. }
  457. return rc;
  458. }