Skip to content

Commit

Permalink
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/herbert/crypto-2.6

Pull crypto updates from Herbert Xu:
 "Here is the crypto update for 5.3:

  API:
   - Test shash interface directly in testmgr
   - cra_driver_name is now mandatory

  Algorithms:
   - Replace arc4 crypto_cipher with library helper
   - Implement 5 way interleave for ECB, CBC and CTR on arm64
   - Add xxhash
   - Add continuous self-test on noise source to drbg
   - Update jitter RNG

  Drivers:
   - Add support for SHA204A random number generator
   - Add support for 7211 in iproc-rng200
   - Fix fuzz test failures in inside-secure
   - Fix fuzz test failures in talitos
   - Fix fuzz test failures in qat"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (143 commits)
  crypto: stm32/hash - remove interruptible condition for dma
  crypto: stm32/hash - Fix hmac issue more than 256 bytes
  crypto: stm32/crc32 - rename driver file
  crypto: amcc - remove memset after dma_alloc_coherent
  crypto: ccp - Switch to SPDX license identifiers
  crypto: ccp - Validate the the error value used to index error messages
  crypto: doc - Fix formatting of new crypto engine content
  crypto: doc - Add parameter documentation
  crypto: arm64/aes-ce - implement 5 way interleave for ECB, CBC and CTR
  crypto: arm64/aes-ce - add 5 way interleave routines
  crypto: talitos - drop icv_ool
  crypto: talitos - fix hash on SEC1.
  crypto: talitos - move struct talitos_edesc into talitos.h
  lib/scatterlist: Fix mapping iterator when sg->offset is greater than PAGE_SIZE
  crypto/NX: Set receive window credits to max number of CRBs in RxFIFO
  crypto: asymmetric_keys - select CRYPTO_HASH where needed
  crypto: serpent - mark __serpent_setkey_sbox noinline
  crypto: testmgr - dynamically allocate crypto_shash
  crypto: testmgr - dynamically allocate testvec_config
  crypto: talitos - eliminate unneeded 'done' functions at build time
  ...
  • Loading branch information
torvalds committed Jul 9, 2019
2 parents 8b68150 + f3880a2 commit 4d2fa8b
Show file tree
Hide file tree
Showing 168 changed files with 4,527 additions and 3,798 deletions.
176 changes: 77 additions & 99 deletions Documentation/crypto/api-samples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,111 +4,89 @@ Code Examples
Code Example For Symmetric Key Cipher Operation
-----------------------------------------------

::


/* tie all data structures together */
struct skcipher_def {
struct scatterlist sg;
struct crypto_skcipher *tfm;
struct skcipher_request *req;
struct crypto_wait wait;
};

/* Perform cipher operation */
static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
int enc)
{
int rc;

if (enc)
rc = crypto_wait_req(crypto_skcipher_encrypt(sk->req), &sk->wait);
else
rc = crypto_wait_req(crypto_skcipher_decrypt(sk->req), &sk->wait);

if (rc)
pr_info("skcipher encrypt returned with result %d\n", rc);
This code encrypts some data with AES-256-XTS. For sake of example,
all inputs are random bytes, the encryption is done in-place, and it's
assumed the code is running in a context where it can sleep.

return rc;
}
::

/* Initialize and trigger cipher operation */
static int test_skcipher(void)
{
struct skcipher_def sk;
struct crypto_skcipher *skcipher = NULL;
struct skcipher_request *req = NULL;
char *scratchpad = NULL;
char *ivdata = NULL;
unsigned char key[32];
int ret = -EFAULT;

skcipher = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0);
if (IS_ERR(skcipher)) {
pr_info("could not allocate skcipher handle\n");
return PTR_ERR(skcipher);
}

req = skcipher_request_alloc(skcipher, GFP_KERNEL);
if (!req) {
pr_info("could not allocate skcipher request\n");
ret = -ENOMEM;
goto out;
}

skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
crypto_req_done,
&sk.wait);

/* AES 256 with random key */
get_random_bytes(&key, 32);
if (crypto_skcipher_setkey(skcipher, key, 32)) {
pr_info("key could not be set\n");
ret = -EAGAIN;
goto out;
}

/* IV will be random */
ivdata = kmalloc(16, GFP_KERNEL);
if (!ivdata) {
pr_info("could not allocate ivdata\n");
goto out;
}
get_random_bytes(ivdata, 16);

/* Input data will be random */
scratchpad = kmalloc(16, GFP_KERNEL);
if (!scratchpad) {
pr_info("could not allocate scratchpad\n");
goto out;
}
get_random_bytes(scratchpad, 16);

sk.tfm = skcipher;
sk.req = req;

/* We encrypt one block */
sg_init_one(&sk.sg, scratchpad, 16);
skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
crypto_init_wait(&sk.wait);

/* encrypt data */
ret = test_skcipher_encdec(&sk, 1);
if (ret)
goto out;

pr_info("Encryption triggered successfully\n");

struct crypto_skcipher *tfm = NULL;
struct skcipher_request *req = NULL;
u8 *data = NULL;
const size_t datasize = 512; /* data size in bytes */
struct scatterlist sg;
DECLARE_CRYPTO_WAIT(wait);
u8 iv[16]; /* AES-256-XTS takes a 16-byte IV */
u8 key[64]; /* AES-256-XTS takes a 64-byte key */
int err;

/*
* Allocate a tfm (a transformation object) and set the key.
*
* In real-world use, a tfm and key are typically used for many
* encryption/decryption operations. But in this example, we'll just do a
* single encryption operation with it (which is not very efficient).
*/

tfm = crypto_alloc_skcipher("xts(aes)", 0, 0);
if (IS_ERR(tfm)) {
pr_err("Error allocating xts(aes) handle: %ld\n", PTR_ERR(tfm));
return PTR_ERR(tfm);
}

get_random_bytes(key, sizeof(key));
err = crypto_skcipher_setkey(tfm, key, sizeof(key));
if (err) {
pr_err("Error setting key: %d\n", err);
goto out;
}

/* Allocate a request object */
req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
err = -ENOMEM;
goto out;
}

/* Prepare the input data */
data = kmalloc(datasize, GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto out;
}
get_random_bytes(data, datasize);

/* Initialize the IV */
get_random_bytes(iv, sizeof(iv));

/*
* Encrypt the data in-place.
*
* For simplicity, in this example we wait for the request to complete
* before proceeding, even if the underlying implementation is asynchronous.
*
* To decrypt instead of encrypt, just change crypto_skcipher_encrypt() to
* crypto_skcipher_decrypt().
*/
sg_init_one(&sg, data, datasize);
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &wait);
skcipher_request_set_crypt(req, &sg, &sg, datasize, iv);
err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
if (err) {
pr_err("Error encrypting data: %d\n", err);
goto out;
}

pr_debug("Encryption was successful\n");
out:
if (skcipher)
crypto_free_skcipher(skcipher);
if (req)
crypto_free_skcipher(tfm);
skcipher_request_free(req);
if (ivdata)
kfree(ivdata);
if (scratchpad)
kfree(scratchpad);
return ret;
kfree(data);
return err;
}


Expand Down
2 changes: 1 addition & 1 deletion Documentation/crypto/api-skcipher.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Block Cipher Algorithm Definitions
:doc: Block Cipher Algorithm Definitions

.. kernel-doc:: include/linux/crypto.h
:functions: crypto_alg ablkcipher_alg blkcipher_alg cipher_alg
:functions: crypto_alg ablkcipher_alg blkcipher_alg cipher_alg compress_alg

Symmetric Key Cipher API
------------------------
Expand Down
4 changes: 1 addition & 3 deletions Documentation/crypto/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,7 @@ the aforementioned cipher types:
- CRYPTO_ALG_TYPE_KPP Key-agreement Protocol Primitive (KPP) such as
an ECDH or DH implementation

- CRYPTO_ALG_TYPE_DIGEST Raw message digest

- CRYPTO_ALG_TYPE_HASH Alias for CRYPTO_ALG_TYPE_DIGEST
- CRYPTO_ALG_TYPE_HASH Raw message digest

- CRYPTO_ALG_TYPE_SHASH Synchronous multi-block hash

Expand Down
111 changes: 73 additions & 38 deletions Documentation/crypto/crypto_engine.rst
Original file line number Diff line number Diff line change
@@ -1,50 +1,85 @@
=============
CRYPTO ENGINE
.. SPDX-License-Identifier: GPL-2.0
Crypto Engine
=============

Overview
--------
The crypto engine API (CE), is a crypto queue manager.
The crypto engine (CE) API is a crypto queue manager.

Requirement
-----------
You have to put at start of your tfm_ctx the struct crypto_engine_ctx::
You must put, at the start of your transform context your_tfm_ctx, the structure
crypto_engine:

::

struct your_tfm_ctx {
struct crypto_engine_ctx enginectx;
...
};
struct your_tfm_ctx {
struct crypto_engine engine;
...
};

Why: Since CE manage only crypto_async_request, it cannot know the underlying
request_type and so have access only on the TFM.
So using container_of for accessing __ctx is impossible.
Furthermore, the crypto engine cannot know the "struct your_tfm_ctx",
so it must assume that crypto_engine_ctx is at start of it.
The crypto engine only manages asynchronous requests in the form of
crypto_async_request. It cannot know the underlying request type and thus only
has access to the transform structure. It is not possible to access the context
using container_of. In addition, the engine knows nothing about your
structure "``struct your_tfm_ctx``". The engine assumes (requires) the placement
of the known member ``struct crypto_engine`` at the beginning.

Order of operations
-------------------
You have to obtain a struct crypto_engine via crypto_engine_alloc_init().
And start it via crypto_engine_start().

Before transferring any request, you have to fill the enginectx.
- prepare_request: (taking a function pointer) If you need to do some processing before doing the request
- unprepare_request: (taking a function pointer) Undoing what's done in prepare_request
- do_one_request: (taking a function pointer) Do encryption for current request

Note: that those three functions get the crypto_async_request associated with the received request.
So your need to get the original request via container_of(areq, struct yourrequesttype_request, base);

When your driver receive a crypto_request, you have to transfer it to
the cryptoengine via one of:
- crypto_transfer_ablkcipher_request_to_engine()
- crypto_transfer_aead_request_to_engine()
- crypto_transfer_akcipher_request_to_engine()
- crypto_transfer_hash_request_to_engine()
- crypto_transfer_skcipher_request_to_engine()

At the end of the request process, a call to one of the following function is needed:
- crypto_finalize_ablkcipher_request
- crypto_finalize_aead_request
- crypto_finalize_akcipher_request
- crypto_finalize_hash_request
- crypto_finalize_skcipher_request
You are required to obtain a struct crypto_engine via ``crypto_engine_alloc_init()``.
Start it via ``crypto_engine_start()``. When finished with your work, shut down the
engine using ``crypto_engine_stop()`` and destroy the engine with
``crypto_engine_exit()``.

Before transferring any request, you have to fill the context enginectx by
providing functions for the following:

* ``prepare_crypt_hardware``: Called once before any prepare functions are
called.

* ``unprepare_crypt_hardware``: Called once after all unprepare functions have
been called.

* ``prepare_cipher_request``/``prepare_hash_request``: Called before each
corresponding request is performed. If some processing or other preparatory
work is required, do it here.

* ``unprepare_cipher_request``/``unprepare_hash_request``: Called after each
request is handled. Clean up / undo what was done in the prepare function.

* ``cipher_one_request``/``hash_one_request``: Handle the current request by
performing the operation.

Note that these functions access the crypto_async_request structure
associated with the received request. You are able to retrieve the original
request by using:

::

container_of(areq, struct yourrequesttype_request, base);

When your driver receives a crypto_request, you must to transfer it to
the crypto engine via one of:

* crypto_transfer_ablkcipher_request_to_engine()

* crypto_transfer_aead_request_to_engine()

* crypto_transfer_akcipher_request_to_engine()

* crypto_transfer_hash_request_to_engine()

* crypto_transfer_skcipher_request_to_engine()

At the end of the request process, a call to one of the following functions is needed:

* crypto_finalize_ablkcipher_request()

* crypto_finalize_aead_request()

* crypto_finalize_akcipher_request()

* crypto_finalize_hash_request()

* crypto_finalize_skcipher_request()
13 changes: 0 additions & 13 deletions Documentation/devicetree/bindings/crypto/atmel-crypto.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,3 @@ sha@f8034000 {
dmas = <&dma1 2 17>;
dma-names = "tx";
};

* Eliptic Curve Cryptography (I2C)

Required properties:
- compatible : must be "atmel,atecc508a".
- reg: I2C bus address of the device.
- clock-frequency: must be present in the i2c controller node.

Example:
atecc508a@c0 {
compatible = "atmel,atecc508a";
reg = <0xC0>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ HWRNG support for the iproc-rng200 driver

Required properties:
- compatible : Must be one of:
"brcm,bcm7211-rng200"
"brcm,bcm7278-rng200"
"brcm,iproc-rng200"
- reg : base address and size of control register block
Expand Down
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/trivial-devices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ properties:
- at,24c08
# i2c trusted platform module (TPM)
- atmel,at97sc3204t
# i2c h/w symmetric crypto module
- atmel,atsha204a
# i2c h/w elliptic curve crypto module
- atmel,atecc508a
# CM32181: Ambient Light Sensor
- capella,cm32181
# CM3232: Ambient Light Sensor
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4257,6 +4257,7 @@ F: crypto/
F: drivers/crypto/
F: include/crypto/
F: include/linux/crypto*
F: lib/crypto/

CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
M: Neil Horman <nhorman@tuxdriver.com>
Expand Down
Loading

0 comments on commit 4d2fa8b

Please sign in to comment.