206 lines
		
	
	
	
		
			8.1 KiB
			
		
	
	
	
		
			Text
		
	
	
	
	
	
		
		
			
		
	
	
			206 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>
							 |