Commit 0392b110 authored by David Howells's avatar David Howells
Browse files

crypto/krb5: Add an API to perform requests



Add an API by which users of the krb5 crypto library can perform crypto
requests, such as encrypt, decrypt, get_mic and verify_mic.  These
functions take the previously prepared crypto objects to work on.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: "David S. Miller" <davem@davemloft.net>
cc: Chuck Lever <chuck.lever@oracle.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: linux-nfs@vger.kernel.org
cc: linux-crypto@vger.kernel.org
cc: netdev@vger.kernel.org
parent a9c27d2d
Loading
Loading
Loading
Loading
+141 −0
Original line number Diff line number Diff line
@@ -292,3 +292,144 @@ struct crypto_shash *crypto_krb5_prepare_checksum(const struct krb5_enctype *krb
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(crypto_krb5_prepare_checksum);

/**
 * crypto_krb5_encrypt - Apply Kerberos encryption and integrity.
 * @krb5: The encoding to use.
 * @aead: The keyed crypto object to use.
 * @sg: Scatterlist defining the crypto buffer.
 * @nr_sg: The number of elements in @sg.
 * @sg_len: The size of the buffer.
 * @data_offset: The offset of the data in the @sg buffer.
 * @data_len: The length of the data.
 * @preconfounded: True if the confounder is already inserted.
 *
 * Using the specified Kerberos encoding, insert a confounder and padding as
 * needed, encrypt this and the data in place and insert an integrity checksum
 * into the buffer.
 *
 * The buffer must include space for the confounder, the checksum and any
 * padding required.  The caller can preinsert the confounder into the buffer
 * (for testing, for example).
 *
 * The resulting secured blob may be less than the size of the buffer.
 *
 * Returns the size of the secure blob if successful, -ENOMEM on an allocation
 * failure, -EFAULT if there is insufficient space, -EMSGSIZE if the confounder
 * is too short or the data is misaligned.  Other errors may also be returned
 * from the crypto layer.
 */
ssize_t crypto_krb5_encrypt(const struct krb5_enctype *krb5,
			    struct crypto_aead *aead,
			    struct scatterlist *sg, unsigned int nr_sg,
			    size_t sg_len,
			    size_t data_offset, size_t data_len,
			    bool preconfounded)
{
	if (WARN_ON(data_offset > sg_len ||
		    data_len > sg_len ||
		    data_offset > sg_len - data_len))
		return -EMSGSIZE;
	return krb5->profile->encrypt(krb5, aead, sg, nr_sg, sg_len,
				      data_offset, data_len, preconfounded);
}
EXPORT_SYMBOL(crypto_krb5_encrypt);

/**
 * crypto_krb5_decrypt - Validate and remove Kerberos encryption and integrity.
 * @krb5: The encoding to use.
 * @aead: The keyed crypto object to use.
 * @sg: Scatterlist defining the crypto buffer.
 * @nr_sg: The number of elements in @sg.
 * @_offset: Offset of the secure blob in the buffer; updated to data offset.
 * @_len: The length of the secure blob; updated to data length.
 *
 * Using the specified Kerberos encoding, check and remove the integrity
 * checksum and decrypt the secure region, stripping off the confounder.
 *
 * If successful, @_offset and @_len are updated to outline the region in which
 * the data plus the trailing padding are stored.  The caller is responsible
 * for working out how much padding there is and removing it.
 *
 * Returns the 0 if successful, -ENOMEM on an allocation failure; sets
 * *_error_code and returns -EPROTO if the data cannot be parsed, or -EBADMSG
 * if the integrity checksum doesn't match).  Other errors may also be returned
 * from the crypto layer.
 */
int crypto_krb5_decrypt(const struct krb5_enctype *krb5,
			struct crypto_aead *aead,
			struct scatterlist *sg, unsigned int nr_sg,
			size_t *_offset, size_t *_len)
{
	return krb5->profile->decrypt(krb5, aead, sg, nr_sg, _offset, _len);
}
EXPORT_SYMBOL(crypto_krb5_decrypt);

/**
 * crypto_krb5_get_mic - Apply Kerberos integrity checksum.
 * @krb5: The encoding to use.
 * @shash: The keyed hash to use.
 * @metadata: Metadata to add into the hash before adding the data.
 * @sg: Scatterlist defining the crypto buffer.
 * @nr_sg: The number of elements in @sg.
 * @sg_len: The size of the buffer.
 * @data_offset: The offset of the data in the @sg buffer.
 * @data_len: The length of the data.
 *
 * Using the specified Kerberos encoding, calculate and insert an integrity
 * checksum into the buffer.
 *
 * The buffer must include space for the checksum at the front.
 *
 * Returns the size of the secure blob if successful, -ENOMEM on an allocation
 * failure, -EFAULT if there is insufficient space, -EMSGSIZE if the gap for
 * the checksum is too short.  Other errors may also be returned from the
 * crypto layer.
 */
ssize_t crypto_krb5_get_mic(const struct krb5_enctype *krb5,
			    struct crypto_shash *shash,
			    const struct krb5_buffer *metadata,
			    struct scatterlist *sg, unsigned int nr_sg,
			    size_t sg_len,
			    size_t data_offset, size_t data_len)
{
	if (WARN_ON(data_offset > sg_len ||
		    data_len > sg_len ||
		    data_offset > sg_len - data_len))
		return -EMSGSIZE;
	return krb5->profile->get_mic(krb5, shash, metadata, sg, nr_sg, sg_len,
				      data_offset, data_len);
}
EXPORT_SYMBOL(crypto_krb5_get_mic);

/**
 * crypto_krb5_verify_mic - Validate and remove Kerberos integrity checksum.
 * @krb5: The encoding to use.
 * @shash: The keyed hash to use.
 * @metadata: Metadata to add into the hash before adding the data.
 * @sg: Scatterlist defining the crypto buffer.
 * @nr_sg: The number of elements in @sg.
 * @_offset: Offset of the secure blob in the buffer; updated to data offset.
 * @_len: The length of the secure blob; updated to data length.
 *
 * Using the specified Kerberos encoding, check and remove the integrity
 * checksum.
 *
 * If successful, @_offset and @_len are updated to outline the region in which
 * the data is stored.
 *
 * Returns the 0 if successful, -ENOMEM on an allocation failure; sets
 * *_error_code and returns -EPROTO if the data cannot be parsed, or -EBADMSG
 * if the checksum doesn't match).  Other errors may also be returned from the
 * crypto layer.
 */
int crypto_krb5_verify_mic(const struct krb5_enctype *krb5,
			   struct crypto_shash *shash,
			   const struct krb5_buffer *metadata,
			   struct scatterlist *sg, unsigned int nr_sg,
			   size_t *_offset, size_t *_len)
{
	return krb5->profile->verify_mic(krb5, shash, metadata, sg, nr_sg,
					 _offset, _len);
}
EXPORT_SYMBOL(crypto_krb5_verify_mic);
+21 −0
Original line number Diff line number Diff line
@@ -117,5 +117,26 @@ struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *kr
struct crypto_shash *crypto_krb5_prepare_checksum(const struct krb5_enctype *krb5,
						  const struct krb5_buffer *TK,
						  u32 usage, gfp_t gfp);
ssize_t crypto_krb5_encrypt(const struct krb5_enctype *krb5,
			    struct crypto_aead *aead,
			    struct scatterlist *sg, unsigned int nr_sg,
			    size_t sg_len,
			    size_t data_offset, size_t data_len,
			    bool preconfounded);
int crypto_krb5_decrypt(const struct krb5_enctype *krb5,
			struct crypto_aead *aead,
			struct scatterlist *sg, unsigned int nr_sg,
			size_t *_offset, size_t *_len);
ssize_t crypto_krb5_get_mic(const struct krb5_enctype *krb5,
			    struct crypto_shash *shash,
			    const struct krb5_buffer *metadata,
			    struct scatterlist *sg, unsigned int nr_sg,
			    size_t sg_len,
			    size_t data_offset, size_t data_len);
int crypto_krb5_verify_mic(const struct krb5_enctype *krb5,
			   struct crypto_shash *shash,
			   const struct krb5_buffer *metadata,
			   struct scatterlist *sg, unsigned int nr_sg,
			   size_t *_offset, size_t *_len);

#endif /* _CRYPTO_KRB5_H */