api-samples.rst 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. Code Examples
  2. =============
  3. Code Example For Symmetric Key Cipher Operation
  4. -----------------------------------------------
  5. ::
  6. struct tcrypt_result {
  7. struct completion completion;
  8. int err;
  9. };
  10. /* tie all data structures together */
  11. struct skcipher_def {
  12. struct scatterlist sg;
  13. struct crypto_skcipher *tfm;
  14. struct skcipher_request *req;
  15. struct tcrypt_result result;
  16. };
  17. /* Callback function */
  18. static void test_skcipher_cb(struct crypto_async_request *req, int error)
  19. {
  20. struct tcrypt_result *result = req->data;
  21. if (error == -EINPROGRESS)
  22. return;
  23. result->err = error;
  24. complete(&result->completion);
  25. pr_info("Encryption finished successfully\n");
  26. }
  27. /* Perform cipher operation */
  28. static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
  29. int enc)
  30. {
  31. int rc = 0;
  32. if (enc)
  33. rc = crypto_skcipher_encrypt(sk->req);
  34. else
  35. rc = crypto_skcipher_decrypt(sk->req);
  36. switch (rc) {
  37. case 0:
  38. break;
  39. case -EINPROGRESS:
  40. case -EBUSY:
  41. rc = wait_for_completion_interruptible(
  42. &sk->result.completion);
  43. if (!rc && !sk->result.err) {
  44. reinit_completion(&sk->result.completion);
  45. break;
  46. }
  47. default:
  48. pr_info("skcipher encrypt returned with %d result %d\n",
  49. rc, sk->result.err);
  50. break;
  51. }
  52. init_completion(&sk->result.completion);
  53. return rc;
  54. }
  55. /* Initialize and trigger cipher operation */
  56. static int test_skcipher(void)
  57. {
  58. struct skcipher_def sk;
  59. struct crypto_skcipher *skcipher = NULL;
  60. struct skcipher_request *req = NULL;
  61. char *scratchpad = NULL;
  62. char *ivdata = NULL;
  63. unsigned char key[32];
  64. int ret = -EFAULT;
  65. skcipher = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0);
  66. if (IS_ERR(skcipher)) {
  67. pr_info("could not allocate skcipher handle\n");
  68. return PTR_ERR(skcipher);
  69. }
  70. req = skcipher_request_alloc(skcipher, GFP_KERNEL);
  71. if (!req) {
  72. pr_info("could not allocate skcipher request\n");
  73. ret = -ENOMEM;
  74. goto out;
  75. }
  76. skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
  77. test_skcipher_cb,
  78. &sk.result);
  79. /* AES 256 with random key */
  80. get_random_bytes(&key, 32);
  81. if (crypto_skcipher_setkey(skcipher, key, 32)) {
  82. pr_info("key could not be set\n");
  83. ret = -EAGAIN;
  84. goto out;
  85. }
  86. /* IV will be random */
  87. ivdata = kmalloc(16, GFP_KERNEL);
  88. if (!ivdata) {
  89. pr_info("could not allocate ivdata\n");
  90. goto out;
  91. }
  92. get_random_bytes(ivdata, 16);
  93. /* Input data will be random */
  94. scratchpad = kmalloc(16, GFP_KERNEL);
  95. if (!scratchpad) {
  96. pr_info("could not allocate scratchpad\n");
  97. goto out;
  98. }
  99. get_random_bytes(scratchpad, 16);
  100. sk.tfm = skcipher;
  101. sk.req = req;
  102. /* We encrypt one block */
  103. sg_init_one(&sk.sg, scratchpad, 16);
  104. skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
  105. init_completion(&sk.result.completion);
  106. /* encrypt data */
  107. ret = test_skcipher_encdec(&sk, 1);
  108. if (ret)
  109. goto out;
  110. pr_info("Encryption triggered successfully\n");
  111. out:
  112. if (skcipher)
  113. crypto_free_skcipher(skcipher);
  114. if (req)
  115. skcipher_request_free(req);
  116. if (ivdata)
  117. kfree(ivdata);
  118. if (scratchpad)
  119. kfree(scratchpad);
  120. return ret;
  121. }
  122. Code Example For Use of Operational State Memory With SHASH
  123. -----------------------------------------------------------
  124. ::
  125. struct sdesc {
  126. struct shash_desc shash;
  127. char ctx[];
  128. };
  129. static struct sdesc init_sdesc(struct crypto_shash *alg)
  130. {
  131. struct sdesc sdesc;
  132. int size;
  133. size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
  134. sdesc = kmalloc(size, GFP_KERNEL);
  135. if (!sdesc)
  136. return ERR_PTR(-ENOMEM);
  137. sdesc->shash.tfm = alg;
  138. sdesc->shash.flags = 0x0;
  139. return sdesc;
  140. }
  141. static int calc_hash(struct crypto_shashalg,
  142. const unsigned chardata, unsigned int datalen,
  143. unsigned chardigest) {
  144. struct sdesc sdesc;
  145. int ret;
  146. sdesc = init_sdesc(alg);
  147. if (IS_ERR(sdesc)) {
  148. pr_info("trusted_key: can't alloc %s\n", hash_alg);
  149. return PTR_ERR(sdesc);
  150. }
  151. ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
  152. kfree(sdesc);
  153. return ret;
  154. }
  155. Code Example For Random Number Generator Usage
  156. ----------------------------------------------
  157. ::
  158. static int get_random_numbers(u8 *buf, unsigned int len)
  159. {
  160. struct crypto_rngrng = NULL;
  161. chardrbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */
  162. int ret;
  163. if (!buf || !len) {
  164. pr_debug("No output buffer provided\n");
  165. return -EINVAL;
  166. }
  167. rng = crypto_alloc_rng(drbg, 0, 0);
  168. if (IS_ERR(rng)) {
  169. pr_debug("could not allocate RNG handle for %s\n", drbg);
  170. return -PTR_ERR(rng);
  171. }
  172. ret = crypto_rng_get_bytes(rng, buf, len);
  173. if (ret < 0)
  174. pr_debug("generation of random numbers failed\n");
  175. else if (ret == 0)
  176. pr_debug("RNG returned no data");
  177. else
  178. pr_debug("RNG returned %d bytes of data\n", ret);
  179. out:
  180. crypto_free_rng(rng);
  181. return ret;
  182. }