Add functions for accessing read_sequence and write_sequence.

OpenSSL 1.1.0 doesn't seem to have these two, so this isn't based on anything.
Have them return uint64_t in preparation for switching the internal
representation to uint64_t so ssl_record_sequence_update can go away.

Change-Id: I21d55e9a29861c992f409ed293e0930a7aaef7a3
Reviewed-on: https://boringssl-review.googlesource.com/6941
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 8efbd4f..e8fbced 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2574,7 +2574,7 @@
                                             CRYPTO_EX_free *free_func);
 
 
-/* Obscure functions. */
+/* Low-level record-layer state. */
 
 /* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
  * the read and write directions. It returns one on success or zero if |ssl|
@@ -2600,6 +2600,17 @@
 OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out,
                                           size_t out_len);
 
+/* SSL_get_read_sequence returns the expected sequence number of the next
+ * incoming record in the current epoch. It always returns zero in DTLS. */
+OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl);
+
+/* SSL_get_write_sequence returns the sequence number of the next outgoing
+ * record in the current epoch. */
+OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl);
+
+
+/* Obscure functions. */
+
 /* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
  * SSL_SESSION structures so that a test can ensure that outside code agrees on
  * these values. */
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 181e99d..56edf2f 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2544,6 +2544,22 @@
   return 1;
 }
 
+static uint64_t be_to_u64(const uint8_t in[8]) {
+  return (((uint64_t)in[7]) << 56) | (((uint64_t)in[6]) << 48) |
+         (((uint64_t)in[5]) << 40) | (((uint64_t)in[4]) << 32) |
+         (((uint64_t)in[3]) << 24) | (((uint64_t)in[2]) << 16) |
+         (((uint64_t)in[1]) << 8) | ((uint64_t)in[0]);
+}
+
+uint64_t SSL_get_read_sequence(const SSL *ssl) {
+  /* TODO(davidben): Internally represent sequence numbers as uint64_t. */
+  return be_to_u64(ssl->s3->read_sequence);
+}
+
+uint64_t SSL_get_write_sequence(const SSL *ssl) {
+  return be_to_u64(ssl->s3->write_sequence);
+}
+
 uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
   return ssl->s3->tmp.server_key_exchange_hash;
 }