Added macro that indicates presence of the time callback feature. Also added C++...
[BearSSL] / src / ssl / ssl_hs_common.t0
index f4ad65b..4674891 100644 (file)
@@ -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