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