Added new 64-bit implementations of Curve25519 and P-256.
[BearSSL] / src / ssl / ssl_hs_common.t0
index dc025ff..4674891 100644 (file)
@@ -34,7 +34,7 @@ preamble {
 /*
  * This macro evaluates to a pointer to the current engine context.
  */
-#define ENG  ((br_ssl_engine_context *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu)))
+#define ENG  ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu)))
 
 }
 
@@ -112,13 +112,13 @@ cc: get8 ( addr -- val ) {
 \ Read a 16-bit word from the context (address is offset in context).
 cc: get16 ( addr -- val ) {
        size_t addr = (size_t)T0_POP();
-       T0_PUSH(*(uint16_t *)((unsigned char *)ENG + addr));
+       T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr));
 }
 
 \ Read a 32-bit word from the context (address is offset in context).
 cc: get32 ( addr -- val ) {
        size_t addr = (size_t)T0_POP();
-       T0_PUSH(*(uint32_t *)((unsigned char *)ENG + addr));
+       T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr));
 }
 
 \ Set a byte in the context (address is offset in context).
@@ -130,13 +130,13 @@ cc: set8 ( val addr -- ) {
 \ Set a 16-bit word in the context (address is offset in context).
 cc: set16 ( val addr -- ) {
        size_t addr = (size_t)T0_POP();
-       *(uint16_t *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP();
+       *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP();
 }
 
 \ Set a 32-bit word in the context (address is offset in context).
 cc: set32 ( val addr -- ) {
        size_t addr = (size_t)T0_POP();
-       *(uint32_t *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP();
+       *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP();
 }
 
 \ Define a word that evaluates as an address of a field within the
@@ -581,7 +581,7 @@ cc: more-incoming-bytes? ( -- bool ) {
        read16 skip-blob ;
 
 \ Open a substructure: the inner structure length is checked against,
-\ and substracted, from the output structure current limit.
+\ and subtracted, from the output structure current limit.
 : open-elt ( lim len -- lim-outer lim-inner )
        dup { len }
        - dup 0< if ERR_BAD_PARAM fail then
@@ -763,6 +763,10 @@ cc: mkrand ( addr len -- ) {
 \       3  AES-128/GCM
 \       4  AES-256/GCM
 \       5  ChaCha20/Poly1305
+\       6  AES-128/CCM
+\       7  AES-256/CCM
+\       8  AES-128/CCM8
+\       9  AES-256/CCM8
 \ -- MAC algorithm:
 \       0  none         (for suites with AEAD encryption)
 \       2  HMAC/SHA-1
@@ -817,6 +821,15 @@ hexb| C030 1405 | \ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
 hexb| C031 3304 | \ TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
 hexb| C032 3405 | \ TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
 
+hexb| C09C 0604 | \ TLS_RSA_WITH_AES_128_CCM
+hexb| C09D 0704 | \ TLS_RSA_WITH_AES_256_CCM
+hexb| C0A0 0804 | \ TLS_RSA_WITH_AES_128_CCM_8
+hexb| C0A1 0904 | \ TLS_RSA_WITH_AES_256_CCM_8
+hexb| C0AC 2604 | \ TLS_ECDHE_ECDSA_WITH_AES_128_CCM
+hexb| C0AD 2704 | \ TLS_ECDHE_ECDSA_WITH_AES_256_CCM
+hexb| C0AE 2804 | \ TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+hexb| C0AF 2904 | \ TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+
 hexb| CCA8 1504 | \ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
 hexb| CCA9 2504 | \ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
 
@@ -879,6 +892,16 @@ hexb| 0000 | \ List terminator.
 : prf-id ( suite -- id )
        cipher-suite-to-elements 15 and ;
 
+\ Test whether a cipher suite is only for TLS-1.2. Cipher suites that
+\ can be used with TLS-1.0 or 1.1 use HMAC/SHA-1. RFC do not formally
+\ forbid using a CBC-based TLS-1.2 cipher suite, e.g. based on HMAC/SHA-256,
+\ with older protocol versions; however, servers should not do that, since
+\ it may confuse clients. Since the server code does not try such games,
+\ for consistency, the client should reject it as well (normal servers
+\ don't do that, so any attempt is a sign of foul play).
+: use-tls12? ( suite -- bool )
+       cipher-suite-to-elements 0xF0 and 0x20 <> ;
+
 \ Switch to negotiated security parameters for input or output.
 : switch-encryption ( is-client for-input -- )
        { for-input }
@@ -946,7 +969,31 @@ hexb| 0000 | \ List terminator.
                        then
                endof
 
-               ERR_BAD_PARAM fail
+               \ Now we only have AES/CCM suites (6 to 9). Since the
+               \ input is between 0 and 15, and we checked values 0 to 5,
+               \ we only need to reject values larger than 9.
+               dup 9 > if
+                       ERR_BAD_PARAM fail
+               then
+
+               \ Stack: is_client prf_id mac_id cipher_id
+               \ We want to remove the mac_id (it is zero for CCM suites)
+               \ and replace the cipher_id with the key and tag lengths.
+               \ The following table applies:
+               \  id   key length   tag length
+               \   6       16          16
+               \   7       32          16
+               \   8       16           8
+               \   9       32           8
+               swap drop
+               dup 1 and 4 << 16 + swap
+               8 and 16 swap -
+               for-input if
+                       switch-aesccm-in
+               else
+                       switch-aesccm-out
+               then
+               ret
        endcase
        ;
 
@@ -1014,6 +1061,30 @@ cc: switch-chapol-in ( is_client prf_id -- ) {
        br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id);
 }
 
+cc: switch-aesccm-out ( is_client prf_id cipher_key_len tag_len -- ) {
+       int is_client, prf_id;
+       unsigned cipher_key_len, tag_len;
+
+       tag_len = T0_POP();
+       cipher_key_len = T0_POP();
+       prf_id = T0_POP();
+       is_client = T0_POP();
+       br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id,
+               ENG->iaes_ctrcbc, cipher_key_len, tag_len);
+}
+
+cc: switch-aesccm-in ( is_client prf_id cipher_key_len tag_len -- ) {
+       int is_client, prf_id;
+       unsigned cipher_key_len, tag_len;
+
+       tag_len = T0_POP();
+       cipher_key_len = T0_POP();
+       prf_id = T0_POP();
+       is_client = T0_POP();
+       br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id,
+               ENG->iaes_ctrcbc, cipher_key_len, tag_len);
+}
+
 \ Write Finished message.
 : write-Finished ( from_client -- )
        compute-Finished