diff options
author | Stephan Mueller <smueller@chronox.de> | 2015-03-06 21:34:22 +0100 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-03-09 21:06:18 +1100 |
commit | dbe5fe7e1b3b3632bef2c09964a5f5505de4d744 (patch) | |
tree | 2479f39dfca4a23dc2a569597551949866198e8d /Documentation/DocBook | |
parent | cde001e4c3c3625c60b68a83eb1f1c2572dee07a (diff) | |
download | op-kernel-dev-dbe5fe7e1b3b3632bef2c09964a5f5505de4d744.zip op-kernel-dev-dbe5fe7e1b3b3632bef2c09964a5f5505de4d744.tar.gz |
crypto: doc - AEAD / RNG AF_ALG interface
The patch moves the information provided in
Documentation/crypto/crypto-API-userspace.txt into a separate chapter in
the kernel crypto API DocBook. Some corrections are applied (such as
removing a reference to Netlink when the AF_ALG socket is referred to).
In addition, the AEAD and RNG interface description is now added.
Also, a brief description of the zero-copy interface with an example
code snippet is provided.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'Documentation/DocBook')
-rw-r--r-- | Documentation/DocBook/crypto-API.tmpl | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/Documentation/DocBook/crypto-API.tmpl b/Documentation/DocBook/crypto-API.tmpl index 33f63cf..efc8d90 100644 --- a/Documentation/DocBook/crypto-API.tmpl +++ b/Documentation/DocBook/crypto-API.tmpl @@ -1072,6 +1072,602 @@ kernel crypto API | Caller </sect1> </chapter> + <chapter id="User"><title>User Space Interface</title> + <sect1><title>Introduction</title> + <para> + The concepts of the kernel crypto API visible to kernel space is fully + applicable to the user space interface as well. Therefore, the kernel + crypto API high level discussion for the in-kernel use cases applies + here as well. + </para> + + <para> + The major difference, however, is that user space can only act as a + consumer and never as a provider of a transformation or cipher algorithm. + </para> + + <para> + The following covers the user space interface exported by the kernel + crypto API. A working example of this description is libkcapi that + can be obtained from [1]. That library can be used by user space + applications that require cryptographic services from the kernel. + </para> + + <para> + Some details of the in-kernel kernel crypto API aspects do not + apply to user space, however. This includes the difference between + synchronous and asynchronous invocations. The user space API call + is fully synchronous. + </para> + + <para> + [1] http://www.chronox.de/libkcapi.html + </para> + + </sect1> + + <sect1><title>User Space API General Remarks</title> + <para> + The kernel crypto API is accessible from user space. Currently, + the following ciphers are accessible: + </para> + + <itemizedlist> + <listitem> + <para>Message digest including keyed message digest (HMAC, CMAC)</para> + </listitem> + + <listitem> + <para>Symmetric ciphers</para> + </listitem> + + <listitem> + <para>AEAD ciphers</para> + </listitem> + + <listitem> + <para>Random Number Generators</para> + </listitem> + </itemizedlist> + + <para> + The interface is provided via socket type using the type AF_ALG. + In addition, the setsockopt option type is SOL_ALG. In case the + user space header files do not export these flags yet, use the + following macros: + </para> + + <programlisting> +#ifndef AF_ALG +#define AF_ALG 38 +#endif +#ifndef SOL_ALG +#define SOL_ALG 279 +#endif + </programlisting> + + <para> + A cipher is accessed with the same name as done for the in-kernel + API calls. This includes the generic vs. unique naming schema for + ciphers as well as the enforcement of priorities for generic names. + </para> + + <para> + To interact with the kernel crypto API, a socket must be + created by the user space application. User space invokes the cipher + operation with the send()/write() system call family. The result of the + cipher operation is obtained with the read()/recv() system call family. + </para> + + <para> + The following API calls assume that the socket descriptor + is already opened by the user space application and discusses only + the kernel crypto API specific invocations. + </para> + + <para> + To initialize the socket interface, the following sequence has to + be performed by the consumer: + </para> + + <orderedlist> + <listitem> + <para> + Create a socket of type AF_ALG with the struct sockaddr_alg + parameter specified below for the different cipher types. + </para> + </listitem> + + <listitem> + <para> + Invoke bind with the socket descriptor + </para> + </listitem> + + <listitem> + <para> + Invoke accept with the socket descriptor. The accept system call + returns a new file descriptor that is to be used to interact with + the particular cipher instance. When invoking send/write or recv/read + system calls to send data to the kernel or obtain data from the + kernel, the file descriptor returned by accept must be used. + </para> + </listitem> + </orderedlist> + </sect1> + + <sect1><title>In-place Cipher operation</title> + <para> + Just like the in-kernel operation of the kernel crypto API, the user + space interface allows the cipher operation in-place. That means that + the input buffer used for the send/write system call and the output + buffer used by the read/recv system call may be one and the same. + This is of particular interest for symmetric cipher operations where a + copying of the output data to its final destination can be avoided. + </para> + + <para> + If a consumer on the other hand wants to maintain the plaintext and + the ciphertext in different memory locations, all a consumer needs + to do is to provide different memory pointers for the encryption and + decryption operation. + </para> + </sect1> + + <sect1><title>Message Digest API</title> + <para> + The message digest type to be used for the cipher operation is + selected when invoking the bind syscall. bind requires the caller + to provide a filled struct sockaddr data structure. This data + structure must be filled as follows: + </para> + + <programlisting> +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "hash", /* this selects the hash logic in the kernel */ + .salg_name = "sha1" /* this is the cipher name */ +}; + </programlisting> + + <para> + The salg_type value "hash" applies to message digests and keyed + message digests. Though, a keyed message digest is referenced by + the appropriate salg_name. Please see below for the setsockopt + interface that explains how the key can be set for a keyed message + digest. + </para> + + <para> + Using the send() system call, the application provides the data that + should be processed with the message digest. The send system call + allows the following flags to be specified: + </para> + + <itemizedlist> + <listitem> + <para> + MSG_MORE: If this flag is set, the send system call acts like a + message digest update function where the final hash is not + yet calculated. If the flag is not set, the send system call + calculates the final message digest immediately. + </para> + </listitem> + </itemizedlist> + + <para> + With the recv() system call, the application can read the message + digest from the kernel crypto API. If the buffer is too small for the + message digest, the flag MSG_TRUNC is set by the kernel. + </para> + + <para> + In order to set a message digest key, the calling application must use + the setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC + operation is performed without the initial HMAC state change caused by + the key. + </para> + </sect1> + + <sect1><title>Symmetric Cipher API</title> + <para> + The operation is very similar to the message digest discussion. + During initialization, the struct sockaddr data structure must be + filled as follows: + </para> + + <programlisting> +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "skcipher", /* this selects the symmetric cipher */ + .salg_name = "cbc(aes)" /* this is the cipher name */ +}; + </programlisting> + + <para> + Before data can be sent to the kernel using the write/send system + call family, the consumer must set the key. The key setting is + described with the setsockopt invocation below. + </para> + + <para> + Using the sendmsg() system call, the application provides the data that should be processed for encryption or decryption. In addition, the IV is + specified with the data structure provided by the sendmsg() system call. + </para> + + <para> + The sendmsg system call parameter of struct msghdr is embedded into the + struct cmsghdr data structure. See recv(2) and cmsg(3) for more + information on how the cmsghdr data structure is used together with the + send/recv system call family. That cmsghdr data structure holds the + following information specified with a separate header instances: + </para> + + <itemizedlist> + <listitem> + <para> + specification of the cipher operation type with one of these flags: + </para> + <itemizedlist> + <listitem> + <para>ALG_OP_ENCRYPT - encryption of data</para> + </listitem> + <listitem> + <para>ALG_OP_DECRYPT - decryption of data</para> + </listitem> + </itemizedlist> + </listitem> + + <listitem> + <para> + specification of the IV information marked with the flag ALG_SET_IV + </para> + </listitem> + </itemizedlist> + + <para> + The send system call family allows the following flag to be specified: + </para> + + <itemizedlist> + <listitem> + <para> + MSG_MORE: If this flag is set, the send system call acts like a + cipher update function where more input data is expected + with a subsequent invocation of the send system call. + </para> + </listitem> + </itemizedlist> + + <para> + Note: The kernel reports -EINVAL for any unexpected data. The caller + must make sure that all data matches the constraints given in + /proc/crypto for the selected cipher. + </para> + + <para> + With the recv() system call, the application can read the result of + the cipher operation from the kernel crypto API. The output buffer + must be at least as large as to hold all blocks of the encrypted or + decrypted data. If the output data size is smaller, only as many + blocks are returned that fit into that output buffer size. + </para> + </sect1> + + <sect1><title>AEAD Cipher API</title> + <para> + The operation is very similar to the symmetric cipher discussion. + During initialization, the struct sockaddr data structure must be + filled as follows: + </para> + + <programlisting> +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "aead", /* this selects the symmetric cipher */ + .salg_name = "gcm(aes)" /* this is the cipher name */ +}; + </programlisting> + + <para> + Before data can be sent to the kernel using the write/send system + call family, the consumer must set the key. The key setting is + described with the setsockopt invocation below. + </para> + + <para> + In addition, before data can be sent to the kernel using the + write/send system call family, the consumer must set the authentication + tag size. To set the authentication tag size, the caller must use the + setsockopt invocation described below. + </para> + + <para> + Using the sendmsg() system call, the application provides the data that should be processed for encryption or decryption. In addition, the IV is + specified with the data structure provided by the sendmsg() system call. + </para> + + <para> + The sendmsg system call parameter of struct msghdr is embedded into the + struct cmsghdr data structure. See recv(2) and cmsg(3) for more + information on how the cmsghdr data structure is used together with the + send/recv system call family. That cmsghdr data structure holds the + following information specified with a separate header instances: + </para> + + <itemizedlist> + <listitem> + <para> + specification of the cipher operation type with one of these flags: + </para> + <itemizedlist> + <listitem> + <para>ALG_OP_ENCRYPT - encryption of data</para> + </listitem> + <listitem> + <para>ALG_OP_DECRYPT - decryption of data</para> + </listitem> + </itemizedlist> + </listitem> + + <listitem> + <para> + specification of the IV information marked with the flag ALG_SET_IV + </para> + </listitem> + + <listitem> + <para> + specification of the associated authentication data (AAD) with the + flag ALG_SET_AEAD_ASSOCLEN. The AAD is sent to the kernel together + with the plaintext / ciphertext. See below for the memory structure. + </para> + </listitem> + </itemizedlist> + + <para> + The send system call family allows the following flag to be specified: + </para> + + <itemizedlist> + <listitem> + <para> + MSG_MORE: If this flag is set, the send system call acts like a + cipher update function where more input data is expected + with a subsequent invocation of the send system call. + </para> + </listitem> + </itemizedlist> + + <para> + Note: The kernel reports -EINVAL for any unexpected data. The caller + must make sure that all data matches the constraints given in + /proc/crypto for the selected cipher. + </para> + + <para> + With the recv() system call, the application can read the result of + the cipher operation from the kernel crypto API. The output buffer + must be at least as large as defined with the memory structure below. + If the output data size is smaller, the cipher operation is not performed. + </para> + + <para> + The authenticated decryption operation may indicate an integrity error. + Such breach in integrity is marked with the -EBADMSG error code. + </para> + + <sect2><title>AEAD Memory Structure</title> + <para> + The AEAD cipher operates with the following information that + is communicated between user and kernel space as one data stream: + </para> + + <itemizedlist> + <listitem> + <para>plaintext or ciphertext</para> + </listitem> + + <listitem> + <para>associated authentication data (AAD)</para> + </listitem> + + <listitem> + <para>authentication tag</para> + </listitem> + </itemizedlist> + + <para> + The sizes of the AAD and the authentication tag are provided with + the sendmsg and setsockopt calls (see there). As the kernel knows + the size of the entire data stream, the kernel is now able to + calculate the right offsets of the data components in the data + stream. + </para> + + <para> + The user space caller must arrange the aforementioned information + in the following order: + </para> + + <itemizedlist> + <listitem> + <para> + AEAD encryption input: AAD || plaintext + </para> + </listitem> + + <listitem> + <para> + AEAD decryption input: AAD || ciphertext || authentication tag + </para> + </listitem> + </itemizedlist> + + <para> + The output buffer the user space caller provides must be at least as + large to hold the following data: + </para> + + <itemizedlist> + <listitem> + <para> + AEAD encryption output: ciphertext || authentication tag + </para> + </listitem> + + <listitem> + <para> + AEAD decryption output: plaintext + </para> + </listitem> + </itemizedlist> + </sect2> + </sect1> + + <sect1><title>Random Number Generator API</title> + <para> + Again, the operation is very similar to the other APIs. + During initialization, the struct sockaddr data structure must be + filled as follows: + </para> + + <programlisting> +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "rng", /* this selects the symmetric cipher */ + .salg_name = "drbg_nopr_sha256" /* this is the cipher name */ +}; + </programlisting> + + <para> + Depending on the RNG type, the RNG must be seeded. The seed is provided + using the setsockopt interface to set the key. For example, the + ansi_cprng requires a seed. The DRBGs do not require a seed, but + may be seeded. + </para> + + <para> + Using the read()/recvmsg() system calls, random numbers can be obtained. + The kernel generates at most 128 bytes in one call. If user space + requires more data, multiple calls to read()/recvmsg() must be made. + </para> + + <para> + WARNING: The user space caller may invoke the initially mentioned + accept system call multiple times. In this case, the returned file + descriptors have the same state. + </para> + + </sect1> + + <sect1><title>Zero-Copy Interface</title> + <para> + In addition to the send/write/read/recv system call familty, the AF_ALG + interface can be accessed with the zero-copy interface of splice/vmsplice. + As the name indicates, the kernel tries to avoid a copy operation into + kernel space. + </para> + + <para> + The zero-copy operation requires data to be aligned at the page boundary. + Non-aligned data can be used as well, but may require more operations of + the kernel which would defeat the speed gains obtained from the zero-copy + interface. + </para> + + <para> + The system-interent limit for the size of one zero-copy operation is + 16 pages. If more data is to be sent to AF_ALG, user space must slice + the input into segments with a maximum size of 16 pages. + </para> + + <para> + Zero-copy can be used with the following code example (a complete working + example is provided with libkcapi): + </para> + + <programlisting> +int pipes[2]; + +pipe(pipes); +/* input data in iov */ +vmsplice(pipes[1], iov, iovlen, SPLICE_F_GIFT); +/* opfd is the file descriptor returned from accept() system call */ +splice(pipes[0], NULL, opfd, NULL, ret, 0); +read(opfd, out, outlen); + </programlisting> + + </sect1> + + <sect1><title>Setsockopt Interface</title> + <para> + In addition to the read/recv and send/write system call handling + to send and retrieve data subject to the cipher operation, a consumer + also needs to set the additional information for the cipher operation. + This additional information is set using the setsockopt system call + that must be invoked with the file descriptor of the open cipher + (i.e. the file descriptor returned by the accept system call). + </para> + + <para> + Each setsockopt invocation must use the level SOL_ALG. + </para> + + <para> + The setsockopt interface allows setting the following data using + the mentioned optname: + </para> + + <itemizedlist> + <listitem> + <para> + ALG_SET_KEY -- Setting the key. Key setting is applicable to: + </para> + <itemizedlist> + <listitem> + <para>the skcipher cipher type (symmetric ciphers)</para> + </listitem> + <listitem> + <para>the hash cipher type (keyed message digests)</para> + </listitem> + <listitem> + <para>the AEAD cipher type</para> + </listitem> + <listitem> + <para>the RNG cipher type to provide the seed</para> + </listitem> + </itemizedlist> + </listitem> + + <listitem> + <para> + ALG_SET_AEAD_AUTHSIZE -- Setting the authentication tag size + for AEAD ciphers. For a encryption operation, the authentication + tag of the given size will be generated. For a decryption operation, + the provided ciphertext is assumed to contain an authentication tag + of the given size (see section about AEAD memory layout below). + </para> + </listitem> + </itemizedlist> + + </sect1> + + <sect1><title>User space API example</title> + <para> + Please see [1] for libkcapi which provides an easy-to-use wrapper + around the aforementioned Netlink kernel interface. [1] also contains + a test application that invokes all libkcapi API calls. + </para> + + <para> + [1] http://www.chronox.de/libkcapi.html + </para> + + </sect1> + + </chapter> + <chapter id="API"><title>Programming Interface</title> <sect1><title>Block Cipher Context Data Structures</title> !Pinclude/linux/crypto.h Block Cipher Context Data Structures |