 e63b673f60
			
		
	
	
	e63b673f60
	
	
	
		
			
			The userspace interface of the kernel crypto API is documented with * a general explanation * a discussion of the memory in-place operation * the description of the message digest API * the description of the symmetric cipher API The documentation refers to libkcapi as a working example on how to use the kernel crypto API from user space. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
		
			
				
	
	
		
			205 lines
		
	
	
	
		
			8.1 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
	
		
			8.1 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
| Introduction
 | |
| ============
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| In addition, only a subset of all cipher types are available as documented
 | |
| below.
 | |
| 
 | |
| 
 | |
| User space API general remarks
 | |
| ==============================
 | |
| 
 | |
| The kernel crypto API is accessible from user space. Currently, the following
 | |
| ciphers are accessible:
 | |
| 
 | |
| 	* Message digest including keyed message digest (HMAC, CMAC)
 | |
| 
 | |
| 	* Symmetric ciphers
 | |
| 
 | |
| Note, AEAD ciphers are currently not supported via the symmetric cipher
 | |
| interface.
 | |
| 
 | |
| The interface is provided via Netlink 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:
 | |
| 
 | |
| #ifndef AF_ALG
 | |
| #define AF_ALG 38
 | |
| #endif
 | |
| #ifndef SOL_ALG
 | |
| #define SOL_ALG 279
 | |
| #endif
 | |
| 
 | |
| 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.
 | |
| 
 | |
| To interact with the kernel crypto API, a Netlink 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.
 | |
| 
 | |
| The following API calls assume that the Netlink socket descriptor is already
 | |
| opened by the user space application and discusses only the kernel crypto API
 | |
| specific invocations.
 | |
| 
 | |
| To initialize a Netlink interface, the following sequence has to be performed
 | |
| by the consumer:
 | |
| 
 | |
| 	1. Create a socket of type AF_ALG with the struct sockaddr_alg parameter
 | |
| 	   specified below for the different cipher types.
 | |
| 
 | |
| 	2. Invoke bind with the socket descriptor
 | |
| 
 | |
| 	3. 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.
 | |
| 
 | |
| In-place cipher operation
 | |
| =========================
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Message digest API
 | |
| ==================
 | |
| 
 | |
| 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:
 | |
| 
 | |
| 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 */
 | |
| };
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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:
 | |
| 
 | |
| 	* 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 
 | |
| Symmetric cipher API
 | |
| ====================
 | |
| 
 | |
| The operation is very similar to the message digest discussion. During
 | |
| initialization, the struct sockaddr data structure must be filled as follows:
 | |
| 
 | |
| 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 */
 | |
| };
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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:
 | |
| 
 | |
| 	* specification of the cipher operation type with one of these flags:
 | |
| 		ALG_OP_ENCRYPT - encryption of data
 | |
| 		ALG_OP_DECRYPT - decryption of data
 | |
| 
 | |
| 	* specification of the IV information marked with the flag ALG_SET_IV
 | |
| 
 | |
| The send system call family allows the following flag to be specified:
 | |
| 
 | |
| 	* 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Setsockopt interface
 | |
| ====================
 | |
| 
 | |
| 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).
 | |
| 
 | |
| Each setsockopt invocation must use the level SOL_ALG.
 | |
| 
 | |
| The setsockopt interface allows setting the following data using the mentioned
 | |
| optname:
 | |
| 
 | |
| 	* ALG_SET_KEY -- Setting the key. Key setting is applicable to:
 | |
| 
 | |
| 		- the skcipher cipher type (symmetric ciphers)
 | |
| 
 | |
| 		- the hash cipher type (keyed message digests)
 | |
| 
 | |
| User space API example
 | |
| ======================
 | |
| 
 | |
| 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.
 | |
| 
 | |
| [1] http://www.chronox.de/libkcapi.html
 | |
| 
 | |
| Author
 | |
| ======
 | |
| 
 | |
| Stephan Mueller <smueller@chronox.de>
 |