cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

api-samples.rst (5812B)


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