Factor out sequence number updates.
Also check for overflow, although it really shouldn't happen.
Change-Id: I34dfe8eaf635aeaa8bef2656fda3cd0bad7e1268
Reviewed-on: https://boringssl-review.googlesource.com/4235
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata
index 2c34dc6..38aa7ed 100644
--- a/crypto/err/ssl.errordata
+++ b/crypto/err/ssl.errordata
@@ -100,6 +100,7 @@
SSL,function,196,ssl3_prf
SSL,function,197,ssl3_read_bytes
SSL,function,198,ssl3_read_n
+SSL,function,267,ssl3_record_sequence_update
SSL,function,266,ssl3_seal_record
SSL,function,199,ssl3_send_cert_verify
SSL,function,200,ssl3_send_certificate_request
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index a45483f..52de0bb 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2446,6 +2446,7 @@
#define SSL_F_dtls1_process_fragment 264
#define SSL_F_dtls1_hm_fragment_new 265
#define SSL_F_ssl3_seal_record 266
+#define SSL_F_ssl3_record_sequence_update 267
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101
#define SSL_R_BAD_ALERT 102
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index bd3a573..766f8b2 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -990,7 +990,9 @@
wr->type = type; /* not needed but helps for debugging */
wr->length += DTLS1_RT_HEADER_LENGTH;
- ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
+ if (!ssl3_record_sequence_update(&s->s3->write_sequence[2], 6)) {
+ goto err;
+ }
/* now let's set up wb */
wb->left = prefix_len + wr->length;
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 7bf325a..d6383d7 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -415,15 +415,16 @@
return ret;
}
-void ssl3_record_sequence_update(uint8_t *seq) {
- int i;
-
- for (i = 7; i >= 0; i--) {
+int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len) {
+ size_t i;
+ for (i = seq_len - 1; i < seq_len; i--) {
++seq[i];
if (seq[i] != 0) {
- break;
+ return 1;
}
}
+ OPENSSL_PUT_ERROR(SSL, ssl3_record_sequence_update, ERR_R_OVERFLOW);
+ return 0;
}
int ssl3_alert_code(int code) {
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 4df546d..6278deb 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -787,7 +787,10 @@
long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp)(void));
int ssl3_pending(const SSL *s);
-void ssl3_record_sequence_update(uint8_t *seq);
+/* ssl3_record_sequence_update increments the sequence number in |seq|. It
+ * returns one on success and zero on wraparound. */
+int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len);
+
int ssl3_do_change_cipher_spec(SSL *ssl);
int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 6e1cf3a..1f16269 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -597,13 +597,9 @@
memcpy(p, &seq[2], 6);
memcpy(ad, dtlsseq, 8);
} else {
- int i;
memcpy(ad, seq, 8);
- for (i = 7; i >= 0; i--) {
- ++seq[i];
- if (seq[i] != 0) {
- break;
- }
+ if (!ssl3_record_sequence_update(seq, 8)) {
+ return 0;
}
}