1279264SdelphijCode Examples
2110010Smarkm=============
3110010Smarkm
4142429SnectarCode Example For Symmetric Key Cipher Operation
5110010Smarkm-----------------------------------------------
6110010Smarkm
7110010SmarkmThis code encrypts some data with AES-256-XTS.  For sake of example,
8110010Smarkmall inputs are random bytes, the encryption is done in-place, and it's
9110010Smarkmassumed the code is running in a context where it can sleep.
10110010Smarkm
11110010Smarkm::
12110010Smarkm
13110010Smarkm    static int test_skcipher(void)
14110010Smarkm    {
15110010Smarkm            struct crypto_skcipher *tfm = NULL;
16110010Smarkm            struct skcipher_request *req = NULL;
17110010Smarkm            u8 *data = NULL;
18110010Smarkm            const size_t datasize = 512; /* data size in bytes */
19110010Smarkm            struct scatterlist sg;
20215698Ssimon            DECLARE_CRYPTO_WAIT(wait);
21215698Ssimon            u8 iv[16];  /* AES-256-XTS takes a 16-byte IV */
22215698Ssimon            u8 key[64]; /* AES-256-XTS takes a 64-byte key */
23215698Ssimon            int err;
24215698Ssimon
25110010Smarkm            /*
26110010Smarkm             * Allocate a tfm (a transformation object) and set the key.
27110010Smarkm             *
28110010Smarkm             * In real-world use, a tfm and key are typically used for many
29110010Smarkm             * encryption/decryption operations.  But in this example, we'll just do a
30110010Smarkm             * single encryption operation with it (which is not very efficient).
31110010Smarkm             */
32110010Smarkm
33110010Smarkm            tfm = crypto_alloc_skcipher("xts(aes)", 0, 0);
34110010Smarkm            if (IS_ERR(tfm)) {
35110010Smarkm                    pr_err("Error allocating xts(aes) handle: %ld\n", PTR_ERR(tfm));
36110010Smarkm                    return PTR_ERR(tfm);
37110010Smarkm            }
38110010Smarkm
39110010Smarkm            get_random_bytes(key, sizeof(key));
40110010Smarkm            err = crypto_skcipher_setkey(tfm, key, sizeof(key));
41279264Sdelphij            if (err) {
42279264Sdelphij                    pr_err("Error setting key: %d\n", err);
43110010Smarkm                    goto out;
44110010Smarkm            }
45215698Ssimon
46215698Ssimon            /* Allocate a request object */
47215698Ssimon            req = skcipher_request_alloc(tfm, GFP_KERNEL);
48215698Ssimon            if (!req) {
49142429Snectar                    err = -ENOMEM;
50215698Ssimon                    goto out;
51142429Snectar            }
52142429Snectar
53279264Sdelphij            /* Prepare the input data */
54279264Sdelphij            data = kmalloc(datasize, GFP_KERNEL);
55279264Sdelphij            if (!data) {
56110010Smarkm                    err = -ENOMEM;
57279264Sdelphij                    goto out;
58279264Sdelphij            }
59279264Sdelphij            get_random_bytes(data, datasize);
60279264Sdelphij
61279264Sdelphij            /* Initialize the IV */
62279264Sdelphij            get_random_bytes(iv, sizeof(iv));
63215698Ssimon
64279264Sdelphij            /*
65279264Sdelphij             * Encrypt the data in-place.
66279264Sdelphij             *
67279264Sdelphij             * For simplicity, in this example we wait for the request to complete
68279264Sdelphij             * before proceeding, even if the underlying implementation is asynchronous.
69215698Ssimon             *
70279264Sdelphij             * To decrypt instead of encrypt, just change crypto_skcipher_encrypt() to
71110010Smarkm             * crypto_skcipher_decrypt().
72110010Smarkm             */
73110010Smarkm            sg_init_one(&sg, data, datasize);
74110010Smarkm            skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
75110010Smarkm                                               CRYPTO_TFM_REQ_MAY_SLEEP,
76110010Smarkm                                          crypto_req_done, &wait);
77110010Smarkm            skcipher_request_set_crypt(req, &sg, &sg, datasize, iv);
78110010Smarkm            err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
79110010Smarkm            if (err) {
80110010Smarkm                    pr_err("Error encrypting data: %d\n", err);
81110010Smarkm                    goto out;
82110010Smarkm            }
83110010Smarkm
84110010Smarkm            pr_debug("Encryption was successful\n");
85110010Smarkm    out:
86110010Smarkm            crypto_free_skcipher(tfm);
87110010Smarkm            skcipher_request_free(req);
88110010Smarkm            kfree(data);
89110010Smarkm            return err;
90110010Smarkm    }
91110010Smarkm
92110010Smarkm
93110010SmarkmCode Example For Use of Operational State Memory With SHASH
94110010Smarkm-----------------------------------------------------------
95110010Smarkm
96110010Smarkm::
97110010Smarkm
98110010Smarkm
99110010Smarkm    struct sdesc {
100110010Smarkm        struct shash_desc shash;
101110010Smarkm        char ctx[];
102110010Smarkm    };
103110010Smarkm
104110010Smarkm    static struct sdesc *init_sdesc(struct crypto_shash *alg)
105110010Smarkm    {
106110010Smarkm        struct sdesc *sdesc;
107110010Smarkm        int size;
108110010Smarkm
109110010Smarkm        size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
110110010Smarkm        sdesc = kmalloc(size, GFP_KERNEL);
111110010Smarkm        if (!sdesc)
112110010Smarkm            return ERR_PTR(-ENOMEM);
113110010Smarkm        sdesc->shash.tfm = alg;
114110010Smarkm        return sdesc;
115110010Smarkm    }
116110010Smarkm
117110010Smarkm    static int calc_hash(struct crypto_shash *alg,
118110010Smarkm                 const unsigned char *data, unsigned int datalen,
119110010Smarkm                 unsigned char *digest)
120110010Smarkm    {
121110010Smarkm        struct sdesc *sdesc;
122110010Smarkm        int ret;
123110010Smarkm
124110010Smarkm        sdesc = init_sdesc(alg);
125110010Smarkm        if (IS_ERR(sdesc)) {
126110010Smarkm            pr_info("can't alloc sdesc\n");
127110010Smarkm            return PTR_ERR(sdesc);
128110010Smarkm        }
129110010Smarkm
130110010Smarkm        ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
131110010Smarkm        kfree(sdesc);
132110010Smarkm        return ret;
133142429Snectar    }
134110010Smarkm
135110010Smarkm    static int test_hash(const unsigned char *data, unsigned int datalen,
136279264Sdelphij                 unsigned char *digest)
137215698Ssimon    {
138215698Ssimon        struct crypto_shash *alg;
139215698Ssimon        char *hash_alg_name = "sha1-padlock-nano";
140215698Ssimon        int ret;
141110010Smarkm
142110010Smarkm        alg = crypto_alloc_shash(hash_alg_name, 0, 0);
143110010Smarkm        if (IS_ERR(alg)) {
144110010Smarkm                pr_info("can't alloc alg %s\n", hash_alg_name);
145110010Smarkm                return PTR_ERR(alg);
146215698Ssimon        }
147215698Ssimon        ret = calc_hash(alg, data, datalen, digest);
148215698Ssimon        crypto_free_shash(alg);
149110010Smarkm        return ret;
150110010Smarkm    }
151110010Smarkm
152215698Ssimon
153110010SmarkmCode Example For Random Number Generator Usage
154110010Smarkm----------------------------------------------
155110010Smarkm
156110010Smarkm::
157110010Smarkm
158110010Smarkm
159279264Sdelphij    static int get_random_numbers(u8 *buf, unsigned int len)
160110010Smarkm    {
161110010Smarkm        struct crypto_rng *rng = NULL;
162110010Smarkm        char *drbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */
163110010Smarkm        int ret;
164110010Smarkm
165110010Smarkm        if (!buf || !len) {
166110010Smarkm            pr_debug("No output buffer provided\n");
167110010Smarkm            return -EINVAL;
168110010Smarkm        }
169110010Smarkm
170110010Smarkm        rng = crypto_alloc_rng(drbg, 0, 0);
171110010Smarkm        if (IS_ERR(rng)) {
172110010Smarkm            pr_debug("could not allocate RNG handle for %s\n", drbg);
173110010Smarkm            return PTR_ERR(rng);
174110010Smarkm        }
175110010Smarkm
176110010Smarkm        ret = crypto_rng_get_bytes(rng, buf, len);
177110010Smarkm        if (ret < 0)
178110010Smarkm            pr_debug("generation of random numbers failed\n");
179110010Smarkm        else if (ret == 0)
180110010Smarkm            pr_debug("RNG returned no data");
181110010Smarkm        else
182110010Smarkm            pr_debug("RNG returned %d bytes of data\n", ret);
183110010Smarkm
184110010Smarkm    out:
185142429Snectar        crypto_free_rng(rng);
186110010Smarkm        return ret;
187110010Smarkm    }
188110010Smarkm