18c2ecf20Sopenharmony_ciCode Examples 28c2ecf20Sopenharmony_ci============= 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciCode Example For Symmetric Key Cipher Operation 58c2ecf20Sopenharmony_ci----------------------------------------------- 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciThis code encrypts some data with AES-256-XTS. For sake of example, 88c2ecf20Sopenharmony_ciall inputs are random bytes, the encryption is done in-place, and it's 98c2ecf20Sopenharmony_ciassumed the code is running in a context where it can sleep. 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci:: 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci static int test_skcipher(void) 148c2ecf20Sopenharmony_ci { 158c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = NULL; 168c2ecf20Sopenharmony_ci struct skcipher_request *req = NULL; 178c2ecf20Sopenharmony_ci u8 *data = NULL; 188c2ecf20Sopenharmony_ci const size_t datasize = 512; /* data size in bytes */ 198c2ecf20Sopenharmony_ci struct scatterlist sg; 208c2ecf20Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 218c2ecf20Sopenharmony_ci u8 iv[16]; /* AES-256-XTS takes a 16-byte IV */ 228c2ecf20Sopenharmony_ci u8 key[64]; /* AES-256-XTS takes a 64-byte key */ 238c2ecf20Sopenharmony_ci int err; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci /* 268c2ecf20Sopenharmony_ci * Allocate a tfm (a transformation object) and set the key. 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * In real-world use, a tfm and key are typically used for many 298c2ecf20Sopenharmony_ci * encryption/decryption operations. But in this example, we'll just do a 308c2ecf20Sopenharmony_ci * single encryption operation with it (which is not very efficient). 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci tfm = crypto_alloc_skcipher("xts(aes)", 0, 0); 348c2ecf20Sopenharmony_ci if (IS_ERR(tfm)) { 358c2ecf20Sopenharmony_ci pr_err("Error allocating xts(aes) handle: %ld\n", PTR_ERR(tfm)); 368c2ecf20Sopenharmony_ci return PTR_ERR(tfm); 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci get_random_bytes(key, sizeof(key)); 408c2ecf20Sopenharmony_ci err = crypto_skcipher_setkey(tfm, key, sizeof(key)); 418c2ecf20Sopenharmony_ci if (err) { 428c2ecf20Sopenharmony_ci pr_err("Error setting key: %d\n", err); 438c2ecf20Sopenharmony_ci goto out; 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci /* Allocate a request object */ 478c2ecf20Sopenharmony_ci req = skcipher_request_alloc(tfm, GFP_KERNEL); 488c2ecf20Sopenharmony_ci if (!req) { 498c2ecf20Sopenharmony_ci err = -ENOMEM; 508c2ecf20Sopenharmony_ci goto out; 518c2ecf20Sopenharmony_ci } 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* Prepare the input data */ 548c2ecf20Sopenharmony_ci data = kmalloc(datasize, GFP_KERNEL); 558c2ecf20Sopenharmony_ci if (!data) { 568c2ecf20Sopenharmony_ci err = -ENOMEM; 578c2ecf20Sopenharmony_ci goto out; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci get_random_bytes(data, datasize); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* Initialize the IV */ 628c2ecf20Sopenharmony_ci get_random_bytes(iv, sizeof(iv)); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* 658c2ecf20Sopenharmony_ci * Encrypt the data in-place. 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * For simplicity, in this example we wait for the request to complete 688c2ecf20Sopenharmony_ci * before proceeding, even if the underlying implementation is asynchronous. 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * To decrypt instead of encrypt, just change crypto_skcipher_encrypt() to 718c2ecf20Sopenharmony_ci * crypto_skcipher_decrypt(). 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci sg_init_one(&sg, data, datasize); 748c2ecf20Sopenharmony_ci skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | 758c2ecf20Sopenharmony_ci CRYPTO_TFM_REQ_MAY_SLEEP, 768c2ecf20Sopenharmony_ci crypto_req_done, &wait); 778c2ecf20Sopenharmony_ci skcipher_request_set_crypt(req, &sg, &sg, datasize, iv); 788c2ecf20Sopenharmony_ci err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 798c2ecf20Sopenharmony_ci if (err) { 808c2ecf20Sopenharmony_ci pr_err("Error encrypting data: %d\n", err); 818c2ecf20Sopenharmony_ci goto out; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci pr_debug("Encryption was successful\n"); 858c2ecf20Sopenharmony_ci out: 868c2ecf20Sopenharmony_ci crypto_free_skcipher(tfm); 878c2ecf20Sopenharmony_ci skcipher_request_free(req); 888c2ecf20Sopenharmony_ci kfree(data); 898c2ecf20Sopenharmony_ci return err; 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ciCode Example For Use of Operational State Memory With SHASH 948c2ecf20Sopenharmony_ci----------------------------------------------------------- 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci:: 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci struct sdesc { 1008c2ecf20Sopenharmony_ci struct shash_desc shash; 1018c2ecf20Sopenharmony_ci char ctx[]; 1028c2ecf20Sopenharmony_ci }; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci static struct sdesc *init_sdesc(struct crypto_shash *alg) 1058c2ecf20Sopenharmony_ci { 1068c2ecf20Sopenharmony_ci struct sdesc *sdesc; 1078c2ecf20Sopenharmony_ci int size; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); 1108c2ecf20Sopenharmony_ci sdesc = kmalloc(size, GFP_KERNEL); 1118c2ecf20Sopenharmony_ci if (!sdesc) 1128c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 1138c2ecf20Sopenharmony_ci sdesc->shash.tfm = alg; 1148c2ecf20Sopenharmony_ci return sdesc; 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci static int calc_hash(struct crypto_shash *alg, 1188c2ecf20Sopenharmony_ci const unsigned char *data, unsigned int datalen, 1198c2ecf20Sopenharmony_ci unsigned char *digest) 1208c2ecf20Sopenharmony_ci { 1218c2ecf20Sopenharmony_ci struct sdesc *sdesc; 1228c2ecf20Sopenharmony_ci int ret; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci sdesc = init_sdesc(alg); 1258c2ecf20Sopenharmony_ci if (IS_ERR(sdesc)) { 1268c2ecf20Sopenharmony_ci pr_info("can't alloc sdesc\n"); 1278c2ecf20Sopenharmony_ci return PTR_ERR(sdesc); 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); 1318c2ecf20Sopenharmony_ci kfree(sdesc); 1328c2ecf20Sopenharmony_ci return ret; 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci static int test_hash(const unsigned char *data, unsigned int datalen, 1368c2ecf20Sopenharmony_ci unsigned char *digest) 1378c2ecf20Sopenharmony_ci { 1388c2ecf20Sopenharmony_ci struct crypto_shash *alg; 1398c2ecf20Sopenharmony_ci char *hash_alg_name = "sha1-padlock-nano"; 1408c2ecf20Sopenharmony_ci int ret; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci alg = crypto_alloc_shash(hash_alg_name, 0, 0); 1438c2ecf20Sopenharmony_ci if (IS_ERR(alg)) { 1448c2ecf20Sopenharmony_ci pr_info("can't alloc alg %s\n", hash_alg_name); 1458c2ecf20Sopenharmony_ci return PTR_ERR(alg); 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci ret = calc_hash(alg, data, datalen, digest); 1488c2ecf20Sopenharmony_ci crypto_free_shash(alg); 1498c2ecf20Sopenharmony_ci return ret; 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ciCode Example For Random Number Generator Usage 1548c2ecf20Sopenharmony_ci---------------------------------------------- 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci:: 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci static int get_random_numbers(u8 *buf, unsigned int len) 1608c2ecf20Sopenharmony_ci { 1618c2ecf20Sopenharmony_ci struct crypto_rng *rng = NULL; 1628c2ecf20Sopenharmony_ci char *drbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */ 1638c2ecf20Sopenharmony_ci int ret; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci if (!buf || !len) { 1668c2ecf20Sopenharmony_ci pr_debug("No output buffer provided\n"); 1678c2ecf20Sopenharmony_ci return -EINVAL; 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci rng = crypto_alloc_rng(drbg, 0, 0); 1718c2ecf20Sopenharmony_ci if (IS_ERR(rng)) { 1728c2ecf20Sopenharmony_ci pr_debug("could not allocate RNG handle for %s\n", drbg); 1738c2ecf20Sopenharmony_ci return PTR_ERR(rng); 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci ret = crypto_rng_get_bytes(rng, buf, len); 1778c2ecf20Sopenharmony_ci if (ret < 0) 1788c2ecf20Sopenharmony_ci pr_debug("generation of random numbers failed\n"); 1798c2ecf20Sopenharmony_ci else if (ret == 0) 1808c2ecf20Sopenharmony_ci pr_debug("RNG returned no data"); 1818c2ecf20Sopenharmony_ci else 1828c2ecf20Sopenharmony_ci pr_debug("RNG returned %d bytes of data\n", ret); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci out: 1858c2ecf20Sopenharmony_ci crypto_free_rng(rng); 1868c2ecf20Sopenharmony_ci return ret; 1878c2ecf20Sopenharmony_ci } 188