From: Denis Kenzior <denkenz@gmail.com>
To: ell@lists.01.org
Subject: Re: [PATCH v5 1/5] tls: Check buffer bounds in tls_rsa_sign
Date: Fri, 17 Jun 2016 22:56:20 -0500 [thread overview]
Message-ID: <5764C664.7070507@gmail.com> (raw)
In-Reply-To: <20160617204743.6643-1-mathew.j.martineau@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 4282 bytes --]
Hi Mat, Andrew,
On 06/17/2016 03:47 PM, Mat Martineau wrote:
> ---
> ell/tls-private.h | 2 +-
> ell/tls.c | 29 ++++++++++++++++++++++-------
> 2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/ell/tls-private.h b/ell/tls-private.h
> index 184f2ae..9ea1554 100644
> --- a/ell/tls-private.h
> +++ b/ell/tls-private.h
> @@ -65,7 +65,7 @@ struct tls_key_exchange_algorithm {
> void (*handle_client_key_exchange)(struct l_tls *tls,
> const uint8_t *buf, size_t len);
>
> - bool (*sign)(struct l_tls *tls, uint8_t **out,
> + bool (*sign)(struct l_tls *tls, uint8_t **out, size_t len,
> tls_get_hash_t get_hash);
So what's the purpose of out being a uint8_t **? It seems it is being
rewritten inside tls_rsa_sign to return the number of bytes written to
the caller.
If so, can we instead modify the signature to be:
ssize_t (*sign)(struct l_tls *tls, uint8_t *dest, size_t len,
tls_get_hash_t get_hash);
?
> bool (*verify)(struct l_tls *tls, const uint8_t *in, size_t len,
> tls_get_hash_t get_hash);
> diff --git a/ell/tls.c b/ell/tls.c
> index 0baddf7..90404e4 100644
> --- a/ell/tls.c
> +++ b/ell/tls.c
> @@ -274,7 +274,7 @@ static bool tls_send_rsa_client_key_xchg(struct l_tls *tls);
> static void tls_handle_rsa_client_key_xchg(struct l_tls *tls,
> const uint8_t *buf, size_t len);
>
> -static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
> +static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out, size_t len,
> tls_get_hash_t get_hash);
> static bool tls_rsa_verify(struct l_tls *tls, const uint8_t *in, size_t len,
> tls_get_hash_t get_hash);
> @@ -917,7 +917,7 @@ static bool tls_send_rsa_client_key_xchg(struct l_tls *tls)
> return true;
> }
>
> -static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
> +static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out, size_t len,
> tls_get_hash_t get_hash)
> {
> struct l_asymmetric_cipher *rsa_privkey;
> @@ -929,6 +929,12 @@ static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
> uint8_t sign_input[HANDSHAKE_HASH_MAX_SIZE * 2 + 32];
> size_t sign_input_len;
>
> + if (len < 2) {
> + tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR, 0);
> +
> + return false;
> + }
> +
> if (!tls->priv_key_path) {
> tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR,
> TLS_ALERT_BAD_CERT);
> @@ -968,16 +974,24 @@ static bool tls_rsa_sign(struct l_tls *tls, uint8_t **out,
>
> *(*out)++ = hash_type->tls_id;
> *(*out)++ = 1; /* RSA_sign */
We should avoid what I refer to as 'side-effects'. If an operation won't
succeed, don't scribble in the buffer if at all possible.
> + len -= 2;
This doesn't seem right. By my reading the total bytes being written
here are key_size (in cipher_sign) and 2 bytes just above.
Why are you checking for len >= key_size + 2 below?
> } else {
> get_hash(tls, 1, sign_input + 0, NULL, NULL); /* MD5 */
> get_hash(tls, 2, sign_input + 16, NULL, NULL); /* SHA1 */
> sign_input_len = 36;
> }
>
> - l_put_be16(key_size, *out);
> - result = l_asymmetric_cipher_sign(rsa_privkey, sign_input, *out + 2,
> - sign_input_len, key_size);
> - *out += key_size + 2;
So can we check the length ahead of time, e.g. something like:
if (len < needed) {
tls_disconnect();
l_asymmetric_cipher_free();
return -EMSGSIZE;
}
> + if (len >= key_size + 2) {
> + l_put_be16(key_size, *out);
> + result = l_asymmetric_cipher_sign(rsa_privkey, sign_input,
> + *out + 2,
> + sign_input_len,
> + key_size);
> + *out += key_size + 2;
> + } else {
> + tls_disconnect(tls, TLS_ALERT_INTERNAL_ERROR, 0);
> + result = false;
> + }
>
> l_asymmetric_cipher_free(rsa_privkey);
>
> @@ -1143,7 +1157,8 @@ static bool tls_send_certificate_verify(struct l_tls *tls)
> /* Fill in the Certificate Verify body */
>
> if (!tls->pending.cipher_suite->key_xchg->sign(tls, &ptr,
> - tls_get_handshake_hash_by_id))
> + 2048 - TLS_HANDSHAKE_HEADER_SIZE,
> + tls_get_handshake_hash_by_id))
> return false;
>
> /* Stop maintaining handshake message hashes other than SHA256. */
>
Regards,
-Denis
next prev parent reply other threads:[~2016-06-18 3:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-17 20:47 [PATCH v5 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
2016-06-17 20:47 ` [PATCH v5 2/5] cipher: Return number of read bytes from asymmetric ops Mat Martineau
2016-06-17 20:47 ` [PATCH v5 3/5] unit: Check asymmetric cipher result lengths Mat Martineau
2016-06-17 20:47 ` [PATCH v5 4/5] unit: Check decryption against known ciphertext Mat Martineau
2016-06-17 20:47 ` [PATCH v5 5/5] cipher: Use only one socket for asymmetric cipher Mat Martineau
2016-06-18 3:56 ` Denis Kenzior [this message]
2016-06-20 16:51 ` [PATCH v5 1/5] tls: Check buffer bounds in tls_rsa_sign Mat Martineau
2016-06-20 17:15 ` Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5764C664.7070507@gmail.com \
--to=denkenz@gmail.com \
--cc=ell@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.