^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) Code Examples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) =============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Code Example For Symmetric Key Cipher Operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) -----------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) This code encrypts some data with AES-256-XTS. For sake of example,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) all inputs are random bytes, the encryption is done in-place, and it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) assumed the code is running in a context where it can sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static int test_skcipher(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct crypto_skcipher *tfm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct skcipher_request *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) u8 *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) const size_t datasize = 512; /* data size in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct scatterlist sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) DECLARE_CRYPTO_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u8 iv[16]; /* AES-256-XTS takes a 16-byte IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u8 key[64]; /* AES-256-XTS takes a 64-byte key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Allocate a tfm (a transformation object) and set the key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * In real-world use, a tfm and key are typically used for many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * encryption/decryption operations. But in this example, we'll just do a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * single encryption operation with it (which is not very efficient).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) tfm = crypto_alloc_skcipher("xts(aes)", 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (IS_ERR(tfm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) pr_err("Error allocating xts(aes) handle: %ld\n", PTR_ERR(tfm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return PTR_ERR(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) get_random_bytes(key, sizeof(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) err = crypto_skcipher_setkey(tfm, key, sizeof(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) pr_err("Error setting key: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Allocate a request object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) req = skcipher_request_alloc(tfm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Prepare the input data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) data = kmalloc(datasize, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) get_random_bytes(data, datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Initialize the IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) get_random_bytes(iv, sizeof(iv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Encrypt the data in-place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * For simplicity, in this example we wait for the request to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * before proceeding, even if the underlying implementation is asynchronous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * To decrypt instead of encrypt, just change crypto_skcipher_encrypt() to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * crypto_skcipher_decrypt().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) sg_init_one(&sg, data, datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) CRYPTO_TFM_REQ_MAY_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) crypto_req_done, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) skcipher_request_set_crypt(req, &sg, &sg, datasize, iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) pr_err("Error encrypting data: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) pr_debug("Encryption was successful\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) crypto_free_skcipher(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) skcipher_request_free(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) Code Example For Use of Operational State Memory With SHASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) -----------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct sdesc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct shash_desc shash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) char ctx[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static struct sdesc *init_sdesc(struct crypto_shash *alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct sdesc *sdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) sdesc = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (!sdesc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) sdesc->shash.tfm = alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return sdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int calc_hash(struct crypto_shash *alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) const unsigned char *data, unsigned int datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned char *digest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct sdesc *sdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sdesc = init_sdesc(alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (IS_ERR(sdesc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) pr_info("can't alloc sdesc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return PTR_ERR(sdesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) kfree(sdesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int test_hash(const unsigned char *data, unsigned int datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned char *digest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct crypto_shash *alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) char *hash_alg_name = "sha1-padlock-nano";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) alg = crypto_alloc_shash(hash_alg_name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (IS_ERR(alg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pr_info("can't alloc alg %s\n", hash_alg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return PTR_ERR(alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = calc_hash(alg, data, datalen, digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) crypto_free_shash(alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) Code Example For Random Number Generator Usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ----------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int get_random_numbers(u8 *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct crypto_rng *rng = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) char *drbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!buf || !len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) pr_debug("No output buffer provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) rng = crypto_alloc_rng(drbg, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (IS_ERR(rng)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pr_debug("could not allocate RNG handle for %s\n", drbg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return PTR_ERR(rng);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = crypto_rng_get_bytes(rng, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) pr_debug("generation of random numbers failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) else if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pr_debug("RNG returned no data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pr_debug("RNG returned %d bytes of data\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) crypto_free_rng(rng);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }