Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto/krb5: Add an API to query the layout of the crypto section

Provide some functions to allow the called to find out about the layout of
the crypto section:

(1) Calculate, for a given size of data, how big a buffer will be
required to hold it and where the data will be within it.

(2) Calculate, for an amount of buffer, what's the maximum size of data
that will fit therein, and where it will start.

(3) Determine where the data will be in a received message.

Signed-off-by: David 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

+117
+108
crypto/krb5/krb5_api.c
··· 40 40 return NULL; 41 41 } 42 42 EXPORT_SYMBOL(crypto_krb5_find_enctype); 43 + 44 + /** 45 + * crypto_krb5_how_much_buffer - Work out how much buffer is required for an amount of data 46 + * @krb5: The encoding to use. 47 + * @mode: The mode in which to operated (checksum/encrypt) 48 + * @data_size: How much data we want to allow for 49 + * @_offset: Where to place the offset into the buffer 50 + * 51 + * Calculate how much buffer space is required to wrap a given amount of data. 52 + * This allows for a confounder, padding and checksum as appropriate. The 53 + * amount of buffer required is returned and the offset into the buffer at 54 + * which the data will start is placed in *_offset. 55 + */ 56 + size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5, 57 + enum krb5_crypto_mode mode, 58 + size_t data_size, size_t *_offset) 59 + { 60 + switch (mode) { 61 + case KRB5_CHECKSUM_MODE: 62 + *_offset = krb5->cksum_len; 63 + return krb5->cksum_len + data_size; 64 + 65 + case KRB5_ENCRYPT_MODE: 66 + *_offset = krb5->conf_len; 67 + return krb5->conf_len + data_size + krb5->cksum_len; 68 + 69 + default: 70 + WARN_ON(1); 71 + *_offset = 0; 72 + return 0; 73 + } 74 + } 75 + EXPORT_SYMBOL(crypto_krb5_how_much_buffer); 76 + 77 + /** 78 + * crypto_krb5_how_much_data - Work out how much data can fit in an amount of buffer 79 + * @krb5: The encoding to use. 80 + * @mode: The mode in which to operated (checksum/encrypt) 81 + * @_buffer_size: How much buffer we want to allow for (may be reduced) 82 + * @_offset: Where to place the offset into the buffer 83 + * 84 + * Calculate how much data can be fitted into given amount of buffer. This 85 + * allows for a confounder, padding and checksum as appropriate. The amount of 86 + * data that will fit is returned, the amount of buffer required is shrunk to 87 + * allow for alignment and the offset into the buffer at which the data will 88 + * start is placed in *_offset. 89 + */ 90 + size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5, 91 + enum krb5_crypto_mode mode, 92 + size_t *_buffer_size, size_t *_offset) 93 + { 94 + size_t buffer_size = *_buffer_size, data_size; 95 + 96 + switch (mode) { 97 + case KRB5_CHECKSUM_MODE: 98 + if (WARN_ON(buffer_size < krb5->cksum_len + 1)) 99 + goto bad; 100 + *_offset = krb5->cksum_len; 101 + return buffer_size - krb5->cksum_len; 102 + 103 + case KRB5_ENCRYPT_MODE: 104 + if (WARN_ON(buffer_size < krb5->conf_len + 1 + krb5->cksum_len)) 105 + goto bad; 106 + data_size = buffer_size - krb5->cksum_len; 107 + *_offset = krb5->conf_len; 108 + return data_size - krb5->conf_len; 109 + 110 + default: 111 + WARN_ON(1); 112 + goto bad; 113 + } 114 + 115 + bad: 116 + *_offset = 0; 117 + return 0; 118 + } 119 + EXPORT_SYMBOL(crypto_krb5_how_much_data); 120 + 121 + /** 122 + * crypto_krb5_where_is_the_data - Find the data in a decrypted message 123 + * @krb5: The encoding to use. 124 + * @mode: Mode of operation 125 + * @_offset: Offset of the secure blob in the buffer; updated to data offset. 126 + * @_len: The length of the secure blob; updated to data length. 127 + * 128 + * Find the offset and size of the data in a secure message so that this 129 + * information can be used in the metadata buffer which will get added to the 130 + * digest by crypto_krb5_verify_mic(). 131 + */ 132 + void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5, 133 + enum krb5_crypto_mode mode, 134 + size_t *_offset, size_t *_len) 135 + { 136 + switch (mode) { 137 + case KRB5_CHECKSUM_MODE: 138 + *_offset += krb5->cksum_len; 139 + *_len -= krb5->cksum_len; 140 + return; 141 + case KRB5_ENCRYPT_MODE: 142 + *_offset += krb5->conf_len; 143 + *_len -= krb5->conf_len + krb5->cksum_len; 144 + return; 145 + default: 146 + WARN_ON_ONCE(1); 147 + return; 148 + } 149 + } 150 + EXPORT_SYMBOL(crypto_krb5_where_is_the_data);
+9
include/crypto/krb5.h
··· 101 101 * krb5_api.c 102 102 */ 103 103 const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype); 104 + size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5, 105 + enum krb5_crypto_mode mode, 106 + size_t data_size, size_t *_offset); 107 + size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5, 108 + enum krb5_crypto_mode mode, 109 + size_t *_buffer_size, size_t *_offset); 110 + void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5, 111 + enum krb5_crypto_mode mode, 112 + size_t *_offset, size_t *_len); 104 113 105 114 #endif /* _CRYPTO_KRB5_H */