59 #define EINVAL_CHANGE_CIPHER __einfo_error ( EINFO_EINVAL_CHANGE_CIPHER ) 60 #define EINFO_EINVAL_CHANGE_CIPHER \ 61 __einfo_uniqify ( EINFO_EINVAL, 0x01, \ 62 "Invalid Change Cipher record" ) 63 #define EINVAL_ALERT __einfo_error ( EINFO_EINVAL_ALERT ) 64 #define EINFO_EINVAL_ALERT \ 65 __einfo_uniqify ( EINFO_EINVAL, 0x02, \ 66 "Invalid Alert record" ) 67 #define EINVAL_HELLO __einfo_error ( EINFO_EINVAL_HELLO ) 68 #define EINFO_EINVAL_HELLO \ 69 __einfo_uniqify ( EINFO_EINVAL, 0x03, \ 70 "Invalid Server Hello record" ) 71 #define EINVAL_CERTIFICATE __einfo_error ( EINFO_EINVAL_CERTIFICATE ) 72 #define EINFO_EINVAL_CERTIFICATE \ 73 __einfo_uniqify ( EINFO_EINVAL, 0x04, \ 74 "Invalid Certificate" ) 75 #define EINVAL_CERTIFICATES __einfo_error ( EINFO_EINVAL_CERTIFICATES ) 76 #define EINFO_EINVAL_CERTIFICATES \ 77 __einfo_uniqify ( EINFO_EINVAL, 0x05, \ 78 "Invalid Server Certificate record" ) 79 #define EINVAL_HELLO_DONE __einfo_error ( EINFO_EINVAL_HELLO_DONE ) 80 #define EINFO_EINVAL_HELLO_DONE \ 81 __einfo_uniqify ( EINFO_EINVAL, 0x06, \ 82 "Invalid Server Hello Done record" ) 83 #define EINVAL_FINISHED __einfo_error ( EINFO_EINVAL_FINISHED ) 84 #define EINFO_EINVAL_FINISHED \ 85 __einfo_uniqify ( EINFO_EINVAL, 0x07, \ 86 "Invalid Server Finished record" ) 87 #define EINVAL_HANDSHAKE __einfo_error ( EINFO_EINVAL_HANDSHAKE ) 88 #define EINFO_EINVAL_HANDSHAKE \ 89 __einfo_uniqify ( EINFO_EINVAL, 0x08, \ 90 "Invalid Handshake record" ) 91 #define EINVAL_IV __einfo_error ( EINFO_EINVAL_IV ) 92 #define EINFO_EINVAL_IV \ 93 __einfo_uniqify ( EINFO_EINVAL, 0x0a, \ 94 "Invalid initialisation vector" ) 95 #define EINVAL_PADDING __einfo_error ( EINFO_EINVAL_PADDING ) 96 #define EINFO_EINVAL_PADDING \ 97 __einfo_uniqify ( EINFO_EINVAL, 0x0b, \ 98 "Invalid block padding" ) 99 #define EINVAL_RX_STATE __einfo_error ( EINFO_EINVAL_RX_STATE ) 100 #define EINFO_EINVAL_RX_STATE \ 101 __einfo_uniqify ( EINFO_EINVAL, 0x0c, \ 102 "Invalid receive state" ) 103 #define EINVAL_MAC __einfo_error ( EINFO_EINVAL_MAC ) 104 #define EINFO_EINVAL_MAC \ 105 __einfo_uniqify ( EINFO_EINVAL, 0x0d, \ 106 "Invalid MAC or authentication tag" ) 107 #define EINVAL_TICKET __einfo_error ( EINFO_EINVAL_TICKET ) 108 #define EINFO_EINVAL_TICKET \ 109 __einfo_uniqify ( EINFO_EINVAL, 0x0e, \ 110 "Invalid New Session Ticket record") 111 #define EINVAL_KEY_EXCHANGE __einfo_error ( EINFO_EINVAL_KEY_EXCHANGE ) 112 #define EINFO_EINVAL_KEY_EXCHANGE \ 113 __einfo_uniqify ( EINFO_EINVAL, 0x0f, \ 114 "Invalid Server Key Exchange record" ) 115 #define EIO_ALERT __einfo_error ( EINFO_EIO_ALERT ) 116 #define EINFO_EIO_ALERT \ 117 __einfo_uniqify ( EINFO_EIO, 0x01, \ 118 "Unknown alert level" ) 119 #define ENOMEM_CONTEXT __einfo_error ( EINFO_ENOMEM_CONTEXT ) 120 #define EINFO_ENOMEM_CONTEXT \ 121 __einfo_uniqify ( EINFO_ENOMEM, 0x01, \ 122 "Not enough space for crypto context" ) 123 #define ENOMEM_CERTIFICATE __einfo_error ( EINFO_ENOMEM_CERTIFICATE ) 124 #define EINFO_ENOMEM_CERTIFICATE \ 125 __einfo_uniqify ( EINFO_ENOMEM, 0x02, \ 126 "Not enough space for certificate" ) 127 #define ENOMEM_CHAIN __einfo_error ( EINFO_ENOMEM_CHAIN ) 128 #define EINFO_ENOMEM_CHAIN \ 129 __einfo_uniqify ( EINFO_ENOMEM, 0x03, \ 130 "Not enough space for certificate chain" ) 131 #define ENOMEM_TX_PLAINTEXT __einfo_error ( EINFO_ENOMEM_TX_PLAINTEXT ) 132 #define EINFO_ENOMEM_TX_PLAINTEXT \ 133 __einfo_uniqify ( EINFO_ENOMEM, 0x04, \ 134 "Not enough space for transmitted plaintext" ) 135 #define ENOMEM_TX_CIPHERTEXT __einfo_error ( EINFO_ENOMEM_TX_CIPHERTEXT ) 136 #define EINFO_ENOMEM_TX_CIPHERTEXT \ 137 __einfo_uniqify ( EINFO_ENOMEM, 0x05, \ 138 "Not enough space for transmitted ciphertext" ) 139 #define ENOMEM_RX_DATA __einfo_error ( EINFO_ENOMEM_RX_DATA ) 140 #define EINFO_ENOMEM_RX_DATA \ 141 __einfo_uniqify ( EINFO_ENOMEM, 0x07, \ 142 "Not enough space for received data" ) 143 #define ENOMEM_RX_CONCAT __einfo_error ( EINFO_ENOMEM_RX_CONCAT ) 144 #define EINFO_ENOMEM_RX_CONCAT \ 145 __einfo_uniqify ( EINFO_ENOMEM, 0x08, \ 146 "Not enough space to concatenate received data" ) 147 #define ENOTSUP_CIPHER __einfo_error ( EINFO_ENOTSUP_CIPHER ) 148 #define EINFO_ENOTSUP_CIPHER \ 149 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, \ 150 "Unsupported cipher" ) 151 #define ENOTSUP_NULL __einfo_error ( EINFO_ENOTSUP_NULL ) 152 #define EINFO_ENOTSUP_NULL \ 153 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, \ 154 "Refusing to use null cipher" ) 155 #define ENOTSUP_SIG_HASH __einfo_error ( EINFO_ENOTSUP_SIG_HASH ) 156 #define EINFO_ENOTSUP_SIG_HASH \ 157 __einfo_uniqify ( EINFO_ENOTSUP, 0x03, \ 158 "Unsupported signature and hash algorithm" ) 159 #define ENOTSUP_VERSION __einfo_error ( EINFO_ENOTSUP_VERSION ) 160 #define EINFO_ENOTSUP_VERSION \ 161 __einfo_uniqify ( EINFO_ENOTSUP, 0x04, \ 162 "Unsupported protocol version" ) 163 #define ENOTSUP_CURVE __einfo_error ( EINFO_ENOTSUP_CURVE ) 164 #define EINFO_ENOTSUP_CURVE \ 165 __einfo_uniqify ( EINFO_ENOTSUP, 0x05, \ 166 "Unsupported elliptic curve" ) 167 #define EPERM_ALERT __einfo_error ( EINFO_EPERM_ALERT ) 168 #define EINFO_EPERM_ALERT \ 169 __einfo_uniqify ( EINFO_EPERM, 0x01, \ 170 "Received fatal alert" ) 171 #define EPERM_VERIFY __einfo_error ( EINFO_EPERM_VERIFY ) 172 #define EINFO_EPERM_VERIFY \ 173 __einfo_uniqify ( EINFO_EPERM, 0x02, \ 174 "Handshake verification failed" ) 175 #define EPERM_RENEG_INSECURE __einfo_error ( EINFO_EPERM_RENEG_INSECURE ) 176 #define EINFO_EPERM_RENEG_INSECURE \ 177 __einfo_uniqify ( EINFO_EPERM, 0x04, \ 178 "Secure renegotiation not supported" ) 179 #define EPERM_RENEG_VERIFY __einfo_error ( EINFO_EPERM_RENEG_VERIFY ) 180 #define EINFO_EPERM_RENEG_VERIFY \ 181 __einfo_uniqify ( EINFO_EPERM, 0x05, \ 182 "Secure renegotiation verification failed" ) 183 #define EPERM_KEY_EXCHANGE __einfo_error ( EINFO_EPERM_KEY_EXCHANGE ) 184 #define EINFO_EPERM_KEY_EXCHANGE \ 185 __einfo_uniqify ( EINFO_EPERM, 0x06, \ 186 "ServerKeyExchange verification failed" ) 187 #define EPERM_EMS __einfo_error ( EINFO_EPERM_EMS ) 188 #define EINFO_EPERM_EMS \ 189 __einfo_uniqify ( EINFO_EPERM, 0x07, \ 190 "Extended master secret extension mismatch" ) 191 #define EPROTO_VERSION __einfo_error ( EINFO_EPROTO_VERSION ) 192 #define EINFO_EPROTO_VERSION \ 193 __einfo_uniqify ( EINFO_EPROTO, 0x01, \ 194 "Illegal protocol version upgrade" ) 205 const void *
data,
size_t len );
236 static inline __attribute__ (( always_inline ))
unsigned long 468 DBGC ( tls,
"TLS %p could not generate random data: %s\n",
488 while ( (
data =
va_arg ( args,
void * ) ) ) {
507 const void *secret,
size_t secret_len,
508 void *
out,
size_t out_len,
517 DBGC2 ( tls,
"TLS %p %s secret:\n", tls, digest->
name );
518 DBGC2_HD ( tls, secret, secret_len );
526 DBGC2 ( tls,
"TLS %p %s A(1):\n", tls, digest->
name );
534 memcpy ( ctx_partial,
ctx,
sizeof ( ctx_partial ) );
541 if ( frag_len > out_len )
544 DBGC2 ( tls,
"TLS %p %s output:\n", tls, digest->
name );
549 DBGC2 ( tls,
"TLS %p %s A(n):\n", tls, digest->
name );
568 size_t secret_len,
void *
out,
size_t out_len, ... ) {
571 size_t subsecret_len;
572 const void *md5_secret;
573 const void *sha1_secret;
582 out, out_len, seeds );
589 subsecret_len = ( ( secret_len + 1 ) / 2 );
591 sha1_secret = ( secret + secret_len - subsecret_len );
596 subsecret_len,
out, out_len, seeds );
602 subsecret_len, buf, out_len, seeds );
606 for ( i = 0 ; i < out_len ; i++ )
623 #define tls_prf_label( tls, secret, secret_len, out, out_len, label, ... ) \ 624 tls_prf ( (tls), (secret), (secret_len), (out), (out_len), \ 625 label, ( sizeof ( label ) - 1 ), __VA_ARGS__, NULL ) 644 const void *pre_master_secret,
645 size_t pre_master_secret_len ) {
653 DBGC ( tls,
"TLS %p pre-master secret:\n", tls );
654 DBGC_HD ( tls, pre_master_secret, pre_master_secret_len );
655 DBGC ( tls,
"TLS %p client random bytes:\n", tls );
657 DBGC ( tls,
"TLS %p server random bytes:\n", tls );
659 DBGC ( tls,
"TLS %p session hash:\n", tls );
660 DBGC_HD ( tls, digest_out,
sizeof ( digest_out ) );
664 tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
667 "extended master secret",
668 digest_out, sizeof ( digest_out ) );
670 tls_prf_label ( tls, pre_master_secret, pre_master_secret_len,
681 DBGC ( tls,
"TLS %p generated %smaster secret:\n", tls,
699 size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
706 key_block, sizeof ( key_block ),
"key expansion",
715 DBGC ( tls,
"TLS %p TX MAC secret:\n", tls );
721 DBGC ( tls,
"TLS %p RX MAC secret:\n", tls );
728 key, key_size ) ) != 0 ) {
729 DBGC ( tls,
"TLS %p could not set TX key: %s\n",
733 DBGC ( tls,
"TLS %p TX key:\n", tls );
740 key, key_size ) ) != 0 ) {
741 DBGC ( tls,
"TLS %p could not set TX key: %s\n",
745 DBGC ( tls,
"TLS %p RX key:\n", tls );
751 DBGC ( tls,
"TLS %p TX IV:\n", tls );
757 DBGC ( tls,
"TLS %p RX IV:\n", tls );
820 const void *
data,
size_t len ) {
859 #define TLS_NUM_CIPHER_SUITES table_num_entries ( TLS_CIPHER_SUITES ) 873 if ( suite->
code == cipher_suite )
889 memset ( cipherspec, 0,
sizeof ( *cipherspec ) );
913 dynamic =
zalloc ( total );
915 DBGC ( tls,
"TLS %p could not allocate %zd bytes for crypto " 916 "context\n", tls, total );
928 cipherspec->
suite = suite;
941 unsigned int cipher_suite ) {
949 DBGC ( tls,
"TLS %p does not support cipher %04x\n",
950 tls,
ntohs ( cipher_suite ) );
968 DBGC ( tls,
"TLS %p selected %s-%s-%s-%d-%s\n", tls,
988 DBGC ( tls,
"TLS %p refusing to use null cipher\n", tls );
1005 #define TLS_NUM_SIG_HASH_ALGORITHMS \ 1006 table_num_entries ( TLS_SIG_HASH_ALGORITHMS ) 1077 #define TLS_NUM_NAMED_CURVES table_num_entries ( TLS_NAMED_CURVES ) 1091 if (
curve->code == named_curve )
1155 const void *
data,
size_t len ) {
1231 typeof ( *server_name_ext ) server_name;
1232 typeof ( *max_fragment_length_ext ) max_fragment_length;
1233 typeof ( *signature_algorithms_ext ) signature_algorithms;
1234 typeof ( *renegotiation_info_ext ) renegotiation_info;
1235 typeof ( *session_ticket_ext ) session_ticket;
1236 typeof ( *extended_master_secret_ext ) extended_master_secret;
1237 typeof ( *named_curve_ext )
1248 uint8_t compression_methods_len;
1249 uint8_t compression_methods[1];
1251 typeof ( *extensions ) extensions;
1262 sizeof (
hello.type_length ) ) );
1267 sizeof (
hello.session_id ) );
1271 hello.compression_methods_len =
sizeof (
hello.compression_methods );
1273 extensions = &
hello.extensions;
1276 server_name_ext = &extensions->server_name;
1278 server_name_ext->len =
htons (
sizeof ( server_name_ext->data ) );
1279 server_name_ext->data.len
1280 =
htons (
sizeof ( server_name_ext->data.list ) );
1282 server_name_ext->data.list[0].len
1283 =
htons (
sizeof ( server_name_ext->data.list[0].name ) );
1284 memcpy ( server_name_ext->data.list[0].name, session->
name,
1285 sizeof ( server_name_ext->data.list[0].name ) );
1288 max_fragment_length_ext = &extensions->max_fragment_length;
1290 max_fragment_length_ext->len
1291 =
htons (
sizeof ( max_fragment_length_ext->data ) );
1295 signature_algorithms_ext = &extensions->signature_algorithms;
1297 signature_algorithms_ext->len
1298 =
htons (
sizeof ( signature_algorithms_ext->data ) );
1299 signature_algorithms_ext->data.len
1300 =
htons (
sizeof ( signature_algorithms_ext->data.code ) );
1302 signature_algorithms_ext->data.code[i++] = sighash->
code;
1305 renegotiation_info_ext = &extensions->renegotiation_info;
1307 renegotiation_info_ext->len
1308 =
htons (
sizeof ( renegotiation_info_ext->data ) );
1309 renegotiation_info_ext->data.len
1310 =
sizeof ( renegotiation_info_ext->data.data );
1312 sizeof ( renegotiation_info_ext->data.data ) );
1315 session_ticket_ext = &extensions->session_ticket;
1317 session_ticket_ext->len
1318 =
htons (
sizeof ( session_ticket_ext->data ) );
1319 memcpy ( session_ticket_ext->data.data, session->
ticket,
1320 sizeof ( session_ticket_ext->data.data ) );
1323 extended_master_secret_ext = &extensions->extended_master_secret;
1324 extended_master_secret_ext->type
1326 extended_master_secret_ext->len = 0;
1329 if (
sizeof ( extensions->named_curve ) ) {
1330 named_curve_ext = &extensions->named_curve[0];
1332 named_curve_ext->len
1333 =
htons (
sizeof ( named_curve_ext->data ) );
1334 named_curve_ext->data.len
1335 =
htons (
sizeof ( named_curve_ext->data.code ) );
1337 named_curve_ext->data.code[i++] =
curve->code;
1340 return action ( tls, &
hello,
sizeof (
hello ) );
1368 typeof ( *certificate ) certificates[0];
1379 len += (
sizeof ( *certificate ) + cert->
raw.
len );
1380 DBGC ( tls,
"TLS %p sending client certificate %s\n",
1392 certificates =
iob_put ( iobuf,
sizeof ( *certificates ) );
1393 certificates->type_length =
1395 htonl (
sizeof ( *certificates ) +
len -
1396 sizeof ( certificates->type_length ) ) );
1400 certificate =
iob_put ( iobuf,
sizeof ( *certificate ) );
1425 .
data = &pre_master_secret,
1426 .len =
sizeof ( pre_master_secret ),
1434 ( sizeof ( pre_master_secret.random ) ) ) ) != 0 ) {
1440 &builder ) ) != 0 ) {
1441 DBGC ( tls,
"TLS %p could not encrypt pre-master secret: %s\n",
1450 uint16_t encrypted_pre_master_secret_len;
1456 sizeof (
header.type_length ) ) );
1460 sizeof (
header ) ) ) != 0 ) {
1461 DBGC ( tls,
"TLS %p could not construct Client Key " 1469 builder.
len ) ) != 0 ) {
1475 sizeof ( pre_master_secret ) );
1499 size_t param_len ) {
1515 assert ( param_len <= tls->server.exchange_len );
1521 if ( (
sizeof ( *
sig ) > remaining ) ||
1522 (
ntohs (
sig->signature_len ) > ( remaining -
1523 sizeof ( *sig ) ) ) ) {
1524 DBGC ( tls,
"TLS %p received underlength ServerKeyExchange\n",
1534 if ( use_sig_hash ) {
1537 if ( ( ! pubkey ) || ( ! digest ) ) {
1538 DBGC ( tls,
"TLS %p ServerKeyExchange unsupported " 1539 "signature and hash algorithm\n", tls );
1543 DBGC ( tls,
"TLS %p ServerKeyExchange incorrect " 1544 "signature algorithm %s (expected %s)\n", tls,
1570 DBGC ( tls,
"TLS %p ServerKeyExchange failed " 1571 "verification\n", tls );
1603 for ( i = 0 ; i < (
sizeof ( dh_val ) /
sizeof ( dh_val[0] ) ) ; i++ ){
1605 if ( (
sizeof ( *dh_val[i] ) > remaining ) ||
1606 (
ntohs ( dh_val[i]->
len ) > ( remaining -
1607 sizeof ( *dh_val[i] ) ) )){
1608 DBGC ( tls,
"TLS %p received underlength " 1609 "ServerKeyExchange\n", tls );
1615 frag_len = (
sizeof ( *dh_val[i] ) +
ntohs ( dh_val[i]->
len ));
1617 remaining -= frag_len;
1627 sizeof (
private ) ) ) != 0 ) {
1633 typeof ( dh_val[0] ) dh_p = dh_val[0];
1634 typeof ( dh_val[1] ) dh_g = dh_val[1];
1635 typeof ( dh_val[2] ) dh_ys = dh_val[2];
1644 typeof ( *key_xchg ) key_xchg;
1649 dynamic =
malloc (
sizeof ( *dynamic ) );
1654 pre_master_secret = dynamic->pre_master_secret;
1655 key_xchg = &dynamic->key_xchg;
1656 key_xchg->type_length =
1658 htonl (
sizeof ( *key_xchg ) -
1659 sizeof ( key_xchg->type_length ) ) );
1660 key_xchg->dh_xs_len =
htons (
len );
1664 dh_g->data,
ntohs ( dh_g->len ),
1665 dh_ys->data,
ntohs ( dh_ys->len ),
1666 private, sizeof (
private ),
1668 pre_master_secret ) ) != 0 ) {
1669 DBGC ( tls,
"TLS %p could not calculate DHE key: %s\n",
1675 while (
len && ( ! *pre_master_secret ) ) {
1676 pre_master_secret++;
1682 sizeof ( *key_xchg ) ) ) !=0){
1683 goto err_send_handshake;
1730 sizeof ( *ecdh ) ) ) ) {
1731 DBGC ( tls,
"TLS %p received underlength ServerKeyExchange\n",
1737 param_len = (
sizeof ( *ecdh ) + ecdh->public_len );
1745 DBGC ( tls,
"TLS %p unsupported curve type %d\n",
1746 tls, ecdh->curve_type );
1753 DBGC ( tls,
"TLS %p unsupported named curve %d\n",
1754 tls,
ntohs ( ecdh->named_curve ) );
1759 DBGC ( tls,
"TLS %p using named curve %s\n", tls, curve->
curve->
name );
1765 if ( ecdh->public_len != (
offset + pointsize ) ) {
1766 DBGC ( tls,
"TLS %p invalid %s key\n",
1774 if ( curve->
format && ( ecdh->public[0] != curve->
format ) ) {
1775 DBGC ( tls,
"TLS %p invalid %s curve point format\n",
1785 uint8_t pre_master_secret[pointsize];
1789 uint8_t public[ecdh->public_len];
1794 sizeof (
private ) ) ) != 0){
1800 private, ( key_xchg.public +
offset ),
1801 pre_master_secret ) ) != 0 ) {
1802 DBGC ( tls,
"TLS %p could not exchange ECDHE key: %s\n",
1808 key_xchg.type_length =
1810 htonl (
sizeof ( key_xchg ) -
1811 sizeof ( key_xchg.type_length ) ) );
1812 key_xchg.public_len =
sizeof ( key_xchg.public );
1814 key_xchg.public[0] = curve->
format;
1818 sizeof ( key_xchg ) ) ) !=0){
1849 DBGC ( tls,
"TLS %p could not exchange keys: %s\n",
1856 DBGC ( tls,
"TLS %p could not generate keys: %s\n",
1887 DBGC ( tls,
"TLS %p could not identify (%s,%s) " 1888 "signature and hash algorithm\n", tls,
1897 &builder ) ) != 0 ) {
1898 DBGC ( tls,
"TLS %p could not sign %s digest using %s client " 1899 "private key: %s\n", tls, digest->
name, pubkey->
name,
1901 goto err_pubkey_sign;
1906 int use_sig_hash = ( ( sig_hash ==
NULL ) ? 0 : 1 );
1916 sizeof (
header.type_length )));
1917 if ( use_sig_hash ) {
1919 sizeof (
header.sig_hash[0] ) );
1924 sizeof (
header ) ) ) != 0 ) {
1925 DBGC ( tls,
"TLS %p could not construct Certificate " 1933 builder.
len ) ) != 0 ) {
1952 static const struct {
1959 &change_cipher,
sizeof ( change_cipher ) );
1981 "client finished", digest_out, sizeof ( digest_out ) );
1984 memset ( &finished, 0,
sizeof ( finished ) );
1986 htonl (
sizeof ( finished ) -
1987 sizeof ( finished.type_length ) ) );
1989 sizeof ( finished.verify_data ) );
1993 sizeof ( finished ) ) ) != 0 )
2018 if ( (
sizeof ( *change_cipher ) !=
len ) ||
2020 DBGC ( tls,
"TLS %p received invalid Change Cipher\n", tls );
2024 iob_pull ( iobuf,
sizeof ( *change_cipher ) );
2028 DBGC ( tls,
"TLS %p could not activate RX cipher: %s\n",
2055 DBGC ( tls,
"TLS %p received overlength Alert\n", tls );
2062 switch (
alert->level ) {
2064 DBGC ( tls,
"TLS %p received warning alert %d\n",
2065 tls,
alert->description );
2068 DBGC ( tls,
"TLS %p received fatal alert %d\n",
2069 tls,
alert->description );
2072 DBGC ( tls,
"TLS %p received unknown alert level %d" 2073 "(alert %d)\n", tls,
alert->level,
alert->description );
2092 DBGC ( tls,
"TLS %p ignoring Hello Request\n", tls );
2098 DBGC ( tls,
"TLS %p refusing to renegotiate insecurely\n",
2118 const void *
data,
size_t len ) {
2154 if ( (
sizeof ( *hello_a ) >
len ) ||
2155 ( hello_a->session_id_len > (
len - sizeof ( *hello_a ) ) ) ||
2156 (
sizeof ( *hello_b ) > (
len -
sizeof ( *hello_a ) -
2157 hello_a->session_id_len ) ) ) {
2158 DBGC ( tls,
"TLS %p received underlength Server Hello\n", tls );
2162 session_id = hello_a->session_id;
2163 hello_b = ( (
void * ) ( session_id + hello_a->session_id_len ) );
2166 remaining = (
len -
sizeof ( *hello_a ) - hello_a->session_id_len -
2167 sizeof ( *hello_b ) );
2171 exts = ( (
void * ) hello_b->next );
2172 if ( (
sizeof ( *exts ) > remaining ) ||
2173 ( ( exts_len =
ntohs ( exts->len ) ) >
2174 ( remaining -
sizeof ( *exts ) ) ) ) {
2175 DBGC ( tls,
"TLS %p received underlength extensions\n",
2182 for (
ext = ( (
void * ) exts->data ), remaining = exts_len ;
2184 ext = ( ( (
void * )
ext ) + sizeof ( *
ext ) + ext_len ),
2185 remaining -= (
sizeof ( *
ext ) + ext_len ) ) {
2188 if ( (
sizeof ( *
ext ) > remaining ) ||
2189 ( ( ext_len =
ntohs (
ext->len ) ) >
2190 ( remaining - sizeof ( *
ext ) ) ) ) {
2191 DBGC ( tls,
"TLS %p received underlength " 2192 "extension\n", tls );
2198 switch (
ext->type ) {
2200 reneg = ( (
void * )
ext->data );
2201 if ( (
sizeof ( *reneg ) > ext_len ) ||
2203 ( ext_len - sizeof ( *reneg ) ) ) ) {
2204 DBGC ( tls,
"TLS %p received " 2205 "underlength renegotiation " 2212 ems = ( (
void * )
ext->data );
2221 DBGC ( tls,
"TLS %p does not support protocol version %d.%d\n",
2226 DBGC ( tls,
"TLS %p server attempted to illegally upgrade to " 2227 "protocol version %d.%d\n",
2232 DBGC ( tls,
"TLS %p using protocol version %d.%d\n",
2251 if ( hello_a->session_id_len &&
2257 DBGC ( tls,
"TLS %p resuming session ID:\n", tls );
2265 DBGC ( tls,
"TLS %p mismatched extended master secret " 2266 "extension\n", tls );
2273 if ( hello_a->session_id_len &&
2274 ( hello_a->session_id_len <= sizeof ( tls->
session_id ))){
2278 DBGC ( tls,
"TLS %p new session ID:\n", tls );
2288 if ( ( reneg ==
NULL ) ||
2289 ( reneg->len != sizeof ( tls->
verify ) ) ||
2291 sizeof ( tls->
verify ) ) != 0 ) ) {
2292 DBGC ( tls,
"TLS %p server failed secure " 2293 "renegotiation\n", tls );
2297 }
else if ( reneg !=
NULL ) {
2300 if ( reneg->len != 0 ) {
2301 DBGC ( tls,
"TLS %p server provided non-empty initial " 2302 "renegotiation\n", tls );
2320 const void *
data,
size_t len ) {
2329 if (
sizeof ( *new_session_ticket ) >
len ) {
2330 DBGC ( tls,
"TLS %p received underlength New Session Ticket\n",
2335 ticket_len =
ntohs ( new_session_ticket->len );
2336 if ( ticket_len > (
len -
sizeof ( *new_session_ticket ) ) ) {
2337 DBGC ( tls,
"TLS %p received overlength New Session Ticket\n",
2355 DBGC ( tls,
"TLS %p new session ticket:\n", tls );
2371 const void *
data,
size_t len ) {
2372 size_t remaining =
len;
2384 goto err_alloc_chain;
2388 while ( remaining ) {
2393 size_t certificate_len;
2398 if (
sizeof ( *certificate ) > remaining ) {
2399 DBGC ( tls,
"TLS %p underlength certificate:\n", tls );
2402 goto err_underlength;
2404 certificate_len =
tls_uint24 ( &certificate->length );
2405 if ( certificate_len > ( remaining -
sizeof ( *certificate ) )){
2406 DBGC ( tls,
"TLS %p overlength certificate:\n", tls );
2409 goto err_overlength;
2411 record_len = (
sizeof ( *certificate ) + certificate_len );
2416 certificate_len ) ) != 0 ) {
2417 DBGC ( tls,
"TLS %p could not append certificate: %s\n",
2423 DBGC ( tls,
"TLS %p found certificate %s\n",
2428 remaining -= record_len;
2452 const void *
data,
size_t len ) {
2457 size_t certificates_len;
2461 if (
sizeof ( *certificate ) >
len ) {
2462 DBGC ( tls,
"TLS %p received underlength Server Certificate\n",
2467 certificates_len =
tls_uint24 ( &certificate->length );
2468 if ( certificates_len > (
len -
sizeof ( *certificate ) ) ) {
2469 DBGC ( tls,
"TLS %p received overlength Server Certificate\n",
2477 certificates_len ) ) != 0 )
2492 const void *
data,
size_t len ) {
2546 DBGC ( tls,
"TLS %p selected client certificate %s\n",
2556 goto err_auto_append;
2560 DBGC ( tls,
"TLS %p could not find certificate corresponding " 2561 "to private key\n", tls );
2583 const void *
data,
size_t len ) {
2590 if (
sizeof ( *hello_done ) !=
len ) {
2591 DBGC ( tls,
"TLS %p received overlength Server Hello Done\n",
2601 DBGC ( tls,
"TLS %p could not start certificate validation: " 2619 const void *
data,
size_t len ) {
2629 if (
sizeof ( *finished ) !=
len ) {
2630 DBGC ( tls,
"TLS %p received overlength Finished\n", tls );
2639 "server finished", digest_out, sizeof ( digest_out ) );
2642 DBGC ( tls,
"TLS %p verification failed\n", tls );
2701 while ( ( remaining =
iob_len ( iobuf ) ) ) {
2707 const void *payload;
2712 if (
sizeof ( *handshake ) > remaining ) {
2716 payload_len =
tls_uint24 ( &handshake->length );
2717 if ( payload_len > ( remaining -
sizeof ( *handshake ) ) ) {
2721 payload = &handshake->payload;
2722 record_len = (
sizeof ( *handshake ) + payload_len );
2725 switch ( handshake->type ) {
2756 DBGC ( tls,
"TLS %p ignoring handshake type %d\n",
2757 tls, handshake->type );
2816 DBGC ( tls,
"TLS %p could not deliver data: " 2859 DBGC ( tls,
"TLS %p unknown record type %d\n", tls,
type );
2866 list_add ( &(*iobuf)->list, rx_data );
2869 DBGC ( tls,
"TLS %p could not concatenate non-data record " 2870 "type %d\n", tls,
type );
2872 goto err_concatenate;
2876 if ( (
rc = handler ( tls, *iobuf ) ) != 0 )
2929 const void *
data,
size_t len ) {
2960 const void *
data,
size_t len,
void *hmac ) {
3016 return (
count * each );
3066 const void *plaintext;
3067 const void *encrypt;
3076 plaintext = iobuf->
data;
3097 sizeof (
iv.rec ) ) ) != 0 ) {
3109 tls_hmac ( cipherspec, &authhdr, plaintext, record_len,
3114 &authhdr,
NULL, sizeof ( authhdr ) );
3118 encrypt_len = ( record_len + suite->
mac_len );
3121 -( encrypt_len + 1 ) ) + 1 );
3128 tlshdr =
iob_put ( iobuf,
sizeof ( *tlshdr ) );
3136 sizeof (
iv.rec ) );
3139 ciphertext =
iob_put ( iobuf, record_len );
3140 assert ( ciphertext <= plaintext );
3141 if ( encrypt_len > record_len ) {
3142 memmove ( ciphertext, plaintext, record_len );
3143 encrypt = ciphertext;
3145 encrypt = plaintext;
3156 DBGC2 ( tls,
"Sending plaintext data:\n" );
3157 DBGC2_HDA ( tls, 0, encrypt, encrypt_len );
3159 ciphertext, encrypt_len );
3165 plaintext += record_len;
3173 DBGC ( tls,
"TLS %p could not deliver ciphertext: %s\n",
3197 const void *
data,
size_t len ) {
3230 padding = ( iobuf->
tail - 1 );
3234 DBGC ( tls,
"TLS %p received underlength padding\n", tls );
3238 for ( i = 0 ; i <
pad ; i++ ) {
3239 if ( *(--padding) !=
pad ) {
3240 DBGC ( tls,
"TLS %p received bad padding\n", tls );
3288 DBGC ( tls,
"TLS %p received underlength IV\n", tls );
3295 len -=
sizeof (
iv.record );
3299 DBGC ( tls,
"TLS %p received underlength authentication tag\n",
3320 NULL, sizeof ( authhdr ) );
3328 check_len +=
iob_len ( iobuf );
3345 DBGC ( tls,
"TLS %p received underlength MAC\n", tls );
3354 DBGC2 ( tls,
"Received plaintext data:\n" );
3358 check_len +=
iob_len ( iobuf );
3365 tls_hmac_list ( cipherspec, &authhdr, rx_data, verify_mac );
3372 DBGC ( tls,
"TLS %p failed MAC verification\n", tls );
3378 DBGC ( tls,
"TLS %p failed authentication tag verification\n",
3504 reserve = ( ( -iv_len ) & ( cipher->
alignsize - 1 ) );
3505 remaining += reserve;
3509 while ( remaining ) {
3515 frag_len = remaining;
3518 remaining -= frag_len;
3520 frag_len += remaining;
3527 DBGC ( tls,
"TLS %p could not allocate %zd of %zd " 3528 "bytes for receive buffer\n", tls,
3715 DBGC ( tls,
"TLS %p certificate validation failed: %s\n",
3719 DBGC ( tls,
"TLS %p certificate validation succeeded\n", tls );
3727 DBGC ( tls,
"TLS %p server certificate does not match %s: %s\n",
3815 DBGC ( tls,
"TLS %p could not send Client Hello: %s\n",
3823 DBGC ( tls,
"TLS %p cold not send Certificate: %s\n",
3831 DBGC ( tls,
"TLS %p could not send Client Key " 3839 DBGC ( tls,
"TLS %p could not send Certificate " 3847 DBGC ( tls,
"TLS %p could not send Change Cipher: " 3853 DBGC ( tls,
"TLS %p could not activate TX cipher: " 3862 DBGC ( tls,
"TLS %p could not send Finished: %s\n",
3914 DBGC ( tls,
"TLS %p joining session %s\n", tls,
name );
3927 name_copy = ( ( (
void * ) session ) +
sizeof ( *session ) );
3929 session->
name = name_copy;
3938 DBGC ( tls,
"TLS %p created session %s\n", tls,
name );
3968 tls =
malloc (
sizeof ( *tls ) );
3973 memset ( tls, 0,
sizeof ( *tls ) );
#define TLS_MAX_FRAGMENT_LENGTH_VALUE
Advertised maximum fragment length.
Transport Layer Security Protocol.
#define cpu_to_be16(value)
struct tls_verify_data verify
Verification data.
void * memswap(void *first, void *second, size_t len)
Swap memory regions.
static void free_tls(struct refcnt *refcnt)
Free TLS connection.
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
#define iob_pull(iobuf, len)
static int tls_send_certificate(struct tls_connection *tls)
Transmit Certificate record.
uint8_t id[32]
Session ID.
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
struct tls_header header
Current received record header.
An object interface operation.
int extended_master_secret
Extended master secret flag.
static int is_auth_cipher(struct cipher_algorithm *cipher)
size_t blocksize
Block size.
struct digest_algorithm * digest
Digest algorithm.
struct asn1_cursor raw
Raw public key information.
uint8_t random[32]
Random bytes.
struct arbelprm_rc_send_wqe rc
pseudo_bit_t hash[0x00010]
static void tls_tx_resume_all(struct tls_session *session)
Resume TX state machine for all connections within a session.
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
static int tls_change_cipher(struct tls_connection *tls, struct tls_cipherspec_pair *pair)
Activate next cipher suite.
void intf_close(struct interface *intf, int rc)
Close an object interface.
uint8_t sha1[SHA1_DIGEST_SIZE]
SHA-1 digest.
static void tls_validator_done(struct tls_connection *tls, int rc)
Handle certificate validation completion.
static void privkey_put(struct private_key *key)
Drop reference to private key.
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
static int tls_send_record(struct tls_connection *tls, unsigned int type, struct io_buffer *iobuf)
Send plaintext record(s)
struct asn1_cursor key
Public key (within server certificate)
struct tls_cipher_suite tls_cipher_suite_null
Null cipher suite.
static int tls_select_cipher(struct tls_connection *tls, unsigned int cipher_suite)
Select next cipher suite.
#define iob_put(iobuf, len)
#define TLS_NUM_CIPHER_SUITES
Number of supported cipher suites.
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
static void tls_tx_resume(struct tls_connection *tls)
Resume TX state machine.
static int tls_new_ciphertext(struct tls_connection *tls, struct tls_header *tlshdr, struct list_head *rx_data)
Receive new ciphertext record.
static int tls_newdata_process_header(struct tls_connection *tls)
Handle received TLS header.
#define TLS_RENEGOTIATION_INFO
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
A TLS cipher specification pair.
struct process process
Transmit process.
struct x509_chain certstore
Certificate store.
struct tls_session * session
Session.
static struct tls_named_curve * tls_find_named_curve(unsigned int named_curve)
Identify named curve.
uint8_t master_secret[48]
Master secret.
struct tls_key_exchange_algorithm * exchange
Key exchange algorithm.
struct list_head data
List of received data buffers.
uint8_t md5[MD5_DIGEST_SIZE]
MD5 digest.
uint8_t record_iv_len
Record initialisation vector length.
static unsigned long tls_uint24(const tls24_t *field24)
Extract 24-bit field value.
static void tls_restart(struct tls_connection *tls)
Restart negotiation.
#define TLS_NUM_NAMED_CURVES
Number of supported named curves.
struct io_buffer * handshake
Received handshake fragment.
int dhe_key(const void *modulus, size_t len, const void *generator, size_t generator_len, const void *partner, size_t partner_len, const void *private, size_t private_len, void *public, void *shared)
Calculate Diffie-Hellman key.
static struct pubkey_algorithm * tls_signature_hash_pubkey(struct tls_signature_hash_id code)
Find TLS signature algorithm.
struct stp_switch root
Root switch.
struct pending_operation negotiation
Security negotiation pending operation.
#define list_add(new, head)
Add a new entry to the head of a list.
uint16_t spec
ENA specification version.
struct list_head links
List of links.
static struct tls_cipher_suite * tls_find_cipher_suite(unsigned int cipher_suite)
Identify cipher suite.
#define EPERM_KEY_EXCHANGE
uint32_t first
First block in range.
#define ref_init(refcnt, free)
Initialise a reference counter.
struct refcnt refcnt
Reference counter.
struct tls_cipherspec_pair cipherspec
Cipher specifications.
#define iob_push(iobuf, len)
static void tls_verify_handshake(struct tls_connection *tls, void *out)
Calculate handshake verification hash.
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
static int tls_send_client_key_exchange_pubkey(struct tls_connection *tls)
Transmit Client Key Exchange record using public key exchange.
static int tls_cipherstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *xfer __unused)
Receive new ciphertext.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
struct io_buffer * alloc_iob_raw(size_t len, size_t align, size_t offset)
Allocate I/O buffer with specified alignment and offset.
static int tls_add_handshake(struct tls_connection *tls, const void *data, size_t len)
Add handshake record to verification hash.
int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
uint32_t type
Operating system type.
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
static void tls_generate_master_secret(struct tls_connection *tls, const void *pre_master_secret, size_t pre_master_secret_len)
Generate master secret.
static LIST_HEAD(tls_sessions)
List of TLS session.
size_t alignsize
Alignment size.
static struct interface_operation tls_plainstream_ops[]
TLS plaintext stream interface operations.
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
struct x509_root root_certificates
Root certificates.
struct asn1_algorithm * signature_algorithm
Signature algorithm.
const void * data
Start of data.
void * exchange
Server Key Exchange record (if any)
size_t new_session_ticket_len
Length of new session ticket.
#define TLS_VERSION_TLS_1_2
TLS version 1.2.
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
static struct private_key * privkey_get(struct private_key *key)
Get reference to private key.
uint8_t session_id[32]
Session ID.
FILE_LICENCE(GPL2_OR_LATER)
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
#define EINVAL_HELLO_DONE
unsigned long long uint64_t
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
struct eltorito_descriptor_fixed fixed
Fixed portion.
void alert(unsigned int row, const char *fmt,...)
Show alert message.
struct pubkey_algorithm pubkey_null
struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm
Public key exchange algorithm.
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
static struct digest_algorithm * tls_signature_hash_digest(struct tls_signature_hash_id code)
Find TLS hash algorithm.
static struct interface_operation tls_validator_ops[]
TLS certificate validator interface operations.
#define va_copy(dest, src)
#define TLS_SERVER_HELLO_DONE
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
static void tls_close(struct tls_connection *tls, int rc)
Finish with TLS connection.
#define TLS_CERTIFICATE_REQUEST
uint8_t mac[ETH_ALEN]
MAC address.
static void md5_sha1_final(void *ctx, void *out)
Generate MD5+SHA1 digest.
struct golan_eq_context ctx
A TLS cipher specification.
static void iob_populate(struct io_buffer *iobuf, void *data, size_t len, size_t max_len)
Create a temporary I/O buffer.
#define EINVAL_CERTIFICATE
static void free_tls_session(struct refcnt *refcnt)
Free TLS session.
const char * name
Algorithm name.
struct pubkey_algorithm * pubkey
Public-key encryption algorithm.
static void md5_sha1_init(void *ctx)
Initialise MD5+SHA1 algorithm.
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
void process_del(struct process *process)
Remove process from process list.
static unsigned int code
Response code.
size_t xfer_window(struct interface *intf)
Check flow control window.
u8 iv[16]
Initialization vector.
static void tls_hmac_final(struct tls_cipherspec *cipherspec, void *ctx, void *hmac)
Finalise HMAC.
static struct interface_descriptor tls_cipherstream_desc
TLS ciphertext stream interface descriptor.
A doubly-linked list entry (or list head)
#define TLS_MAX_FRAGMENT_LENGTH
static int tls_send_handshake(struct tls_connection *tls, const void *data, size_t len)
Transmit Handshake record.
Data transfer interfaces.
size_t len
Length of data.
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
static struct interface_descriptor tls_validator_desc
TLS certificate validator interface descriptor.
#define EINVAL_CHANGE_CIPHER
struct private_key * key
Private key (if used)
#define list_empty(list)
Test whether a list is empty.
static void tls_hmac_list(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, struct list_head *list, void *hmac)
Calculate HMAC over list of I/O buffers.
struct tls_server server
Server state.
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
#define cipher_encrypt(cipher, ctx, src, dst, len)
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
struct refcnt refcnt
Reference counter.
size_t authsize
Authentication tag size.
#define list_del(list)
Delete an entry from a list.
static int tls_send_client_key_exchange_ecdhe(struct tls_connection *tls)
Transmit Client Key Exchange record using ECDHE key exchange.
static int tls_new_hello_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Hello Request handshake record.
#define ENOMEM
Not enough space.
static int pubkey_sign(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
#define iob_disown(iobuf)
Disown an I/O buffer.
#define TLS_NAMED_CURVE_TYPE
TLS named curved type.
uint8_t * handshake_ctx
Digest algorithm context used for handshake verification.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Elliptic Curve Ephemeral Diffie-Hellman (ECDHE) key exchange.
static void tls_hmac_update_va(struct digest_algorithm *digest, void *ctx, va_list args)
Update HMAC with a list of ( data, len ) pairs.
int(* exchange)(struct tls_connection *tls)
Transmit Client Key Exchange record.
u32 version
Driver version.
REQUIRE_OBJECT(config_crypto)
static int tls_newdata_process_data(struct tls_connection *tls)
Handle received TLS data payload.
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
#define TLS_TYPE_CHANGE_CIPHER
Change cipher content type.
size_t id_len
Length of session ID.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
static struct tls_signature_hash_algorithm * tls_signature_hash_algorithm(struct pubkey_algorithm *pubkey, struct digest_algorithm *digest)
Find TLS signature and hash algorithm.
Keyed-Hashing for Message Authentication.
#define TLS_RX_ALIGN
RX I/O buffer alignment.
void * new_session_ticket
New session ticket.
struct tls_client client
Client state.
static int tls_progress(struct tls_connection *tls, struct job_progress *progress)
Report job progress.
static int tls_send_change_cipher(struct tls_connection *tls)
Transmit Change Cipher record.
void * cipher_ctx
Bulk encryption cipher context.
static void tls_tx_step(struct tls_connection *tls)
TLS TX state machine.
static size_t tls_iob_reserved(struct tls_connection *tls, size_t len)
Calculate maximum additional length required for transmitted record(s)
int extended_master_secret
Extended master secret flag.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
pseudo_bit_t value[0x00020]
#define TLS_SESSION_TICKET
#define __unused
Declare a variable or data structure as unused.
static int tls_new_session_ticket(struct tls_connection *tls, const void *data, size_t len)
Receive New Session Ticket handshake record.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
struct tls_cipher_suite * suite
Cipher suite.
static void tls_hmac_update(struct tls_cipherspec *cipherspec, void *ctx, const void *data, size_t len)
Update HMAC.
struct digest_algorithm * digest
MAC digest algorithm.
static void tls_prf(struct tls_connection *tls, const void *secret, size_t secret_len, void *out, size_t out_len,...)
Generate secure pseudo-random data.
struct list_head list
List of connections within the same session.
uint32_t gmt_unix_time
GMT Unix time.
#define be16_to_cpu(value)
u32 link
Link to next descriptor.
uint8_t fixed_iv_len
Fixed initialisation vector length.
static unsigned int count
Number of entries.
char * strcpy(char *dest, const char *src)
Copy string.
A TLS signature algorithm.
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
#define TLS_TX_BUFSIZE
TX maximum fragment length.
static int tls_new_alert(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Alert record.
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
size_t ticket_len
Length of session ticket.
uint8_t master_secret[48]
Master secret.
struct list_head list
List of sessions.
static void tls_hmac_init(struct tls_cipherspec *cipherspec, void *ctx, struct tls_auth_header *authhdr)
Initialise HMAC.
#define TLS_ALERT_WARNING
static int tls_send_client_key_exchange(struct tls_connection *tls)
Transmit Client Key Exchange record.
static int tls_new_data(struct tls_connection *tls, struct list_head *rx_data)
Receive new data record.
const char * name
Curve name.
struct tls_cipherspec_pair cipherspec
Cipher specifications.
static int tls_new_change_cipher(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Change Cipher record.
#define TLS_RX_BUFSIZE
RX I/O buffer size.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
#define cpu_to_le32(value)
int ecdhe_key(struct elliptic_curve *curve, const void *partner, const void *private, void *public, void *shared)
Calculate ECDHE key.
#define TLS_NAMED_CURVES
TLS named curve table.
static struct digest_algorithm md5_sha1_algorithm
Hybrid MD5+SHA1 digest algorithm.
struct x509_public_key public_key
Public key information.
void process_add(struct process *process)
Add process to process list.
uint8_t pre_master_secret_len
Pre-master secret length.
#define ENOTCONN
The socket is not connected.
static void digest_init(struct digest_algorithm *digest, void *ctx)
size_t keysize
Scalar (and private key) size.
struct io_buffer * iob_concatenate(struct list_head *list)
Concatenate I/O buffers into a single buffer.
An object interface descriptor.
#define TLS_NUM_SIG_HASH_ALGORITHMS
Number of supported signature and hash algorithms.
#define TLS_HELLO_REQUEST
#define iob_unput(iobuf, len)
A link in an X.509 certificate chain.
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
int x509_auto_append(struct x509_chain *chain, struct x509_chain *store)
Append X.509 certificates to X.509 certificate chain.
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
static int tls_send_plaintext(struct tls_connection *tls, unsigned int type, const void *data, size_t len)
Send plaintext record.
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
char * strerror(int errno)
Retrieve string representation of error number.
uint64_t seq
Sequence number.
static void(* free)(struct refcnt *refcnt))
struct interface cipherstream
Ciphertext stream.
struct pending_operation negotiation
Security negotiation pending operation.
void * zalloc(size_t size)
Allocate cleared memory.
static int tls_new_finished(struct tls_connection *tls, const void *data, size_t len)
Receive new Finished handshake record.
struct x509_subject subject
Subject.
uint8_t hash
Hash algorithm.
void * ticket
Session ticket.
#define ref_get(refcnt)
Get additional reference to object.
struct digest_algorithm digest_null
struct elliptic_curve * curve
Elliptic curve.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
static struct interface_operation tls_cipherstream_ops[]
TLS ciphertext stream interface operations.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
struct x509_chain * chain
Certificate chain.
static int tls_new_server_hello(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello handshake record.
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
uint8_t mac_len
MAC length.
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
size_t strlen(const char *src)
Get length of string.
struct pending_operation validation
Certificate validation pending operation.
static int tls_verify_dh_params(struct tls_connection *tls, size_t param_len)
Verify Diffie-Hellman parameter signature.
An RSA digestInfo prefix.
uint8_t signature
Signature algorithm.
Data transfer interface opening.
#define EPERM_RENEG_VERIFY
#define TLS_SIG_HASH_ALGORITHMS
TLS signature hash algorithm table.
REQUIRING_SYMBOL(add_tls)
u16 keysize
Length of encryption key to be used, network byte order.
uint16_t hello
Hello time.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
unsigned int pending
Pending transmissions.
u32 lifetime
For Lifetime-type KDEs, the lifetime in seconds.
struct tls_cipherspec pending
Next cipher specification.
size_t ctxsize
Context size.
#define cipher_decrypt(cipher, ctx, src, dst, len)
uint32_t next
Next descriptor address.
#define TLS_EXTENDED_MASTER_SECRET
void * malloc(size_t size)
Allocate memory.
static int tls_plainstream_deliver(struct tls_connection *tls, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Deliver datagram as raw data.
static int tls_new_certificate_request(struct tls_connection *tls, const void *data __unused, size_t len __unused)
Receive new Certificate Request handshake record.
void * memmove(void *dest, const void *src, size_t len) __nonnull
#define TLS_RX_MIN_BUFSIZE
Minimum RX I/O buffer size.
struct tls_rx rx
Receive state.
struct cipher_algorithm cipher_null
Cryptographic configuration.
struct tls_signature_hash_id code
Numeric code.
#define TLS_NEW_SESSION_TICKET
uint16_t ext
Extended status.
enum tls_rx_state state
State machine current state.
#define TLS_VERSION_MAX
Maximum supported TLS version.
#define TLS_SERVER_NAME_HOST_NAME
uint8_t client[12]
Client verification data.
An X.509 root certificate list.
struct tls_tx tx
Transmit state.
#define TLS_TYPE_HANDSHAKE
Handshake content type.
RSA public-key cryptography.
static struct interface_descriptor tls_plainstream_desc
TLS plaintext stream interface descriptor.
#define iob_reserve(iobuf, len)
static int tls_generate_keys(struct tls_connection *tls)
Generate key material.
void intf_insert(struct interface *intf, struct interface *upper, struct interface *lower)
Insert a filter interface.
#define INIT_LIST_HEAD(list)
Initialise a list head.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
static int tls_version(struct tls_connection *tls, unsigned int version)
Check for TLS version.
static int tls_send_certificate_verify(struct tls_connection *tls)
Transmit Certificate Verify record.
#define EPERM_RENEG_INSECURE
struct digest_algorithm * handshake_digest
Digest algorithm used for handshake verification.
uint8_t random[28]
Random data.
static int tls_client_hello(struct tls_connection *tls, int(*action)(struct tls_connection *tls, const void *data, size_t len))
Digest or transmit Client Hello record.
uint64_t seq
Sequence number.
#define ENOMEM_TX_PLAINTEXT
static void tls_hmac(struct tls_cipherspec *cipherspec, struct tls_auth_header *authhdr, const void *data, size_t len, void *hmac)
Calculate HMAC.
struct list_head list
List of which this buffer is a member.
static int tls_new_handshake(struct tls_connection *tls, struct io_buffer *iobuf)
Receive new Handshake record.
static int tls_parse_chain(struct tls_connection *tls, const void *data, size_t len)
Parse certificate chain.
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
size_t ctxsize
Context size.
#define TLS_SERVER_KEY_EXCHANGE
static struct process_descriptor tls_process_desc
TLS TX process descriptor.
__builtin_va_list va_list
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
int strcmp(const char *first, const char *second)
Compare strings.
size_t digestsize
Digest size.
const char * name
Algorithm name.
uint8_t sha1[SHA1_CTX_SIZE]
SHA-1 context.
struct io_buffer iobuf
Current received record header (static I/O buffer)
struct digest_algorithm * handshake
Handshake digest algorithm (for TLSv1.2 and above)
void * data
Start of data.
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Ephemeral Diffie-Hellman key exchange.
struct interface validator
Certificate validator.
struct ena_llq_option header
Header locations.
int job_progress(struct interface *intf, struct job_progress *progress)
Get job progress.
#define ENOMEM_CERTIFICATE
struct x509_chain * chain
Certificate chain (if used)
A message digest algorithm.
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
uint16_t version
Protocol version.
#define cpu_to_be64(value)
uint8_t data[48]
Additional event data.
static void tls_clear_handshake(struct tls_connection *tls)
Clear handshake digest algorithm.
struct tls_cipherspec active
Current cipher specification.
uint8_t server[12]
Server verification data.
A TLS key exchange algorithm.
struct digest_algorithm * digest
Digest algorithm.
struct x509_root * root
Root of trust.
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
static void tls_clear_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec)
struct private_key * key
Private key.
struct tls_client_random random
Random bytes.
struct x509_certificate * x509_find_key(struct x509_chain *store, struct private_key *key)
Identify X.509 certificate by corresponding public key.
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
static void tls_set_uint24(tls24_t *field24, unsigned long value)
Set 24-bit field value.
static int tls_new_record(struct tls_connection *tls, unsigned int type, struct list_head *rx_data)
Receive new record.
struct cipher_algorithm * cipher
Bulk encryption cipher algorithm.
struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm
Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm.
struct list_head conn
List of connections.
static size_t tls_cipherstream_window(struct tls_connection *tls)
Check flow control window.
int secure_renegotiation
Secure renegotiation flag.
static int tls_send_finished(struct tls_connection *tls)
Transmit Finished record.
typeof(acpi_finder=acpi_find)
ACPI table finder.
#define EINVAL_KEY_EXCHANGE
static int tls_new_certificate(struct tls_connection *tls, const void *data, size_t len)
Receive new Certificate handshake record.
struct pubkey_algorithm * pubkey
Public-key algorithm.
static void tls_p_hash_va(struct tls_connection *tls, struct digest_algorithm *digest, const void *secret, size_t secret_len, void *out, size_t out_len, va_list seeds)
Generate secure pseudo-random data using a single hash function.
static int tls_session(struct tls_connection *tls, const char *name)
Find or create session for TLS connection.
void * dynamic
Dynamically-allocated storage.
uint16_t offset
Offset to command line.
uint8_t meta
Metadata flags.
static int tls_send_client_hello(struct tls_connection *tls)
Transmit Client Hello record.
#define va_start(ap, last)
static int tls_generate_random(struct tls_connection *tls, void *data, size_t len)
Generate random data.
struct rsa_digestinfo_prefix rsa_md5_sha1_prefix __rsa_digestinfo_prefix
RSA digestInfo prefix for MD5+SHA1 algorithm.
#define EINVAL_CERTIFICATES
struct asn1_cursor raw
Raw certificate.
static int tls_ready(struct tls_connection *tls)
Determine if TLS connection is ready for application data.
const char * name
Server name.
A TLS signature and hash algorithm identifier.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
const char * name
Algorithm name.
#define TLS_CERTIFICATE_VERIFY
#define TLS_TYPE_DATA
Application data content type.
size_t pointsize
Point (and public key) size.
size_t exchange_len
Server Key Exchange record length.
size_t session_id_len
Length of session ID.
#define TLS_TYPE_ALERT
Alert content type.
static int tls_verify_padding(struct tls_connection *tls, struct io_buffer *iobuf)
Verify block padding.
struct interface plainstream
Plaintext stream.
#define TLS_VERSION_MIN
Minimum TLS version.
struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm
Ephemeral Diffie-Hellman key exchange algorithm.
u8 signature
CPU signature.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
static int tls_set_cipher(struct tls_connection *tls, struct tls_cipherspec *cipherspec, struct tls_cipher_suite *suite)
Set cipher suite.
#define NULL
NULL pointer (VOID *)
size_t len
Length of data.
static int tls_select_handshake(struct tls_connection *tls, struct digest_algorithm *digest)
Select handshake digest algorithm.
#define tls_prf_label(tls, secret, secret_len, out, out_len, label,...)
Generate secure pseudo-random data.
#define TLS_CIPHER_SUITES
TLS cipher suite table.
uint8_t format
Curve point format byte (if any)
#define TLS_CLIENT_KEY_EXCHANGE
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
struct bofm_section_header done
void * fixed_iv
Fixed initialisation vector.
static int tls_new_server_hello_done(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Hello Done handshake record.
int add_tls(struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
Add TLS on an interface.
static void md5_sha1_update(void *ctx, const void *data, size_t len)
Accumulate data with MD5+SHA1 algorithm.
#define TLS_SIGNATURE_ALGORITHMS
static int tls_new_server_key_exchange(struct tls_connection *tls, const void *data, size_t len)
Receive new Server Key Exchange handshake record.
const char * name
Algorithm name.
struct digest_algorithm md5_algorithm
MD5 algorithm.
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
static struct io_buffer * tls_alloc_iob(struct tls_connection *tls, size_t len)
Allocate I/O buffer for transmitted record(s)
static size_t tls_plainstream_window(struct tls_connection *tls)
Check flow control window.
#define ref_put(refcnt)
Drop reference to object.
static int tls_send_client_key_exchange_dhe(struct tls_connection *tls)
Transmit Client Key Exchange record using DHE key exchange.
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
uint16_t code
Numeric code (in network-endian order)
static int tls_new_unknown(struct tls_connection *tls __unused, struct io_buffer *iobuf)
Receive new unknown record.
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
void * mac_secret
MAC secret.
static int is_block_cipher(struct cipher_algorithm *cipher)
void * memset(void *dest, int character, size_t len) __nonnull
#define TLS_CHANGE_CIPHER_SPEC
Change cipher spec magic byte.
struct x509_root * root
Root of trust.
uint8_t key_len
Key length.