aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-19 00:20:45 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-19 00:20:45 +0100
commitcccf8e735da9eb62f1de021534ca50255d82e931 (patch)
tree8a2f9965d8000e507056ebb934686fb8f4161f14
parenta9e186680668056e2c35ce5a99769a7ff0df44cd (diff)
downloadbusybox-w32-cccf8e735da9eb62f1de021534ca50255d82e931.tar.gz
busybox-w32-cccf8e735da9eb62f1de021534ca50255d82e931.tar.bz2
busybox-w32-cccf8e735da9eb62f1de021534ca50255d82e931.zip
tls: teach it to decrypt AES256-encrypted data
This adds decryption only. There is no MAC verification, code simply throws away MAC. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/tls.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 6928582df..f3d0bde90 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -181,7 +181,7 @@ typedef struct tls_state {
181 uint8_t master_secret[48]; 181 uint8_t master_secret[48];
182 182
183 uint8_t encrypt_on_write; 183 uint8_t encrypt_on_write;
184 uint8_t decrypt_on_read; 184 int min_encrypted_len_on_read;
185 uint8_t client_write_MAC_key[SHA256_OUTSIZE]; 185 uint8_t client_write_MAC_key[SHA256_OUTSIZE];
186 uint8_t server_write_MAC_key[SHA256_OUTSIZE]; 186 uint8_t server_write_MAC_key[SHA256_OUTSIZE];
187 uint8_t client_write_key[AES256_KEYSIZE]; 187 uint8_t client_write_key[AES256_KEYSIZE];
@@ -634,7 +634,7 @@ static void xwrite_and_hash(tls_state_t *tls, /*const*/ void *buf, unsigned size
634static int xread_tls_block(tls_state_t *tls) 634static int xread_tls_block(tls_state_t *tls)
635{ 635{
636 struct record_hdr *xhdr; 636 struct record_hdr *xhdr;
637 int len; 637 int sz;
638 int total; 638 int total;
639 int target; 639 int target;
640 640
@@ -658,24 +658,57 @@ static int xread_tls_block(tls_state_t *tls)
658 /* if total >= target, we have a full packet (and possibly more)... */ 658 /* if total >= target, we have a full packet (and possibly more)... */
659 if (total - target >= 0) 659 if (total - target >= 0)
660 break; 660 break;
661 len = safe_read(tls->fd, tls->inbuf + total, sizeof(tls->inbuf) - total); 661 sz = safe_read(tls->fd, tls->inbuf + total, sizeof(tls->inbuf) - total);
662 if (len <= 0) 662 if (sz <= 0)
663 bb_perror_msg_and_die("short read"); 663 bb_perror_msg_and_die("short read");
664 total += len; 664 total += sz;
665 } 665 }
666 tls->tail = total - target; 666 tls->tail = total - target;
667 tls->insize = target; 667 tls->insize = target;
668 target -= sizeof(*xhdr); 668 sz = target - sizeof(*xhdr);
669
670 /* Needs to be decrypted? */
671 if (tls->min_encrypted_len_on_read) {
672 psCipherContext_t ctx;
673 uint8_t *p = tls->inbuf + sizeof(*xhdr);
674 int padding_len;
675
676 if (sz & (AES_BLOCKSIZE-1)
677 || sz < tls->min_encrypted_len_on_read
678 ) {
679 bb_error_msg_and_die("bad encrypted len:%u", sz);
680 }
681 /* Decrypt content+MAC+padding in place */
682 psAesInit(&ctx, p, /* IV */
683 tls->server_write_key, sizeof(tls->server_write_key)
684 );
685 psAesDecrypt(&ctx,
686 p + AES_BLOCKSIZE, /* ciphertext */
687 p + AES_BLOCKSIZE, /* plaintext */
688 sz
689 );
690 padding_len = p[sz - 1];
691 dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[AES_BLOCKSIZE], padding_len);
692 padding_len++;
693 sz -= AES_BLOCKSIZE + SHA256_OUTSIZE + padding_len;
694 if (sz < 0) {
695 bb_error_msg_and_die("bad padding size:%u", padding_len);
696 }
697 if (sz != 0) {
698 /* Skip IV */
699 memmove(tls->inbuf + 5, tls->inbuf + 5 + AES_BLOCKSIZE, sz);
700 }
701 }
669 702
670 /* RFC 5246 is not saying it explicitly, but sha256 hash 703 /* RFC 5246 is not saying it explicitly, but sha256 hash
671 * in our FINISHED record must include data of incoming packets too! 704 * in our FINISHED record must include data of incoming packets too!
672 */ 705 */
673 if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE) { 706 if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE) {
674 sha256_hash_dbg("<< sha256:%s", &tls->handshake_sha256_ctx, tls->inbuf + 5, target); 707 sha256_hash_dbg("<< sha256:%s", &tls->handshake_sha256_ctx, tls->inbuf + 5, sz);
675 } 708 }
676 709
677 dbg("got block len:%u\n", target); 710 dbg("got block len:%u\n", sz);
678 return target; 711 return sz;
679} 712}
680 713
681/* 714/*
@@ -1194,9 +1227,6 @@ static void send_change_cipher_spec(tls_state_t *tls)
1194 /* Not "xwrite_and_hash": this is not a handshake message */ 1227 /* Not "xwrite_and_hash": this is not a handshake message */
1195 dbg(">> CHANGE_CIPHER_SPEC\n"); 1228 dbg(">> CHANGE_CIPHER_SPEC\n");
1196 xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC)); 1229 xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC));
1197
1198 /* tls->write_seq64_be = 0; - already is */
1199 tls->encrypt_on_write = 1;
1200} 1230}
1201 1231
1202// 7.4.9. Finished 1232// 7.4.9. Finished
@@ -1335,7 +1365,9 @@ static void tls_handshake(tls_state_t *tls)
1335 send_client_key_exchange(tls); 1365 send_client_key_exchange(tls);
1336 1366
1337 send_change_cipher_spec(tls); 1367 send_change_cipher_spec(tls);
1338 /* we now should send encrypted... as soon as we grok AES. */ 1368 /* from now on we should send encrypted */
1369 /* tls->write_seq64_be = 0; - already is */
1370 tls->encrypt_on_write = 1;
1339 1371
1340 send_client_finished(tls); 1372 send_client_finished(tls);
1341 1373
@@ -1344,8 +1376,8 @@ static void tls_handshake(tls_state_t *tls)
1344 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) 1376 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
1345 tls_error_die(tls); 1377 tls_error_die(tls);
1346 dbg("<< CHANGE_CIPHER_SPEC\n"); 1378 dbg("<< CHANGE_CIPHER_SPEC\n");
1347 tls->decrypt_on_read = 1; 1379 /* all incoming packets now should be encrypted and have IV + MAC + padding */
1348 /* we now should receive encrypted */ 1380 tls->min_encrypted_len_on_read = AES_BLOCKSIZE + SHA256_OUTSIZE + AES_BLOCKSIZE;
1349 1381
1350 /* Get (encrypted) FINISHED from the server */ 1382 /* Get (encrypted) FINISHED from the server */
1351 len = xread_tls_block(tls); 1383 len = xread_tls_block(tls);
@@ -1356,8 +1388,13 @@ static void tls_handshake(tls_state_t *tls)
1356} 1388}
1357 1389
1358// To run a test server using openssl: 1390// To run a test server using openssl:
1391// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost'
1359// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 1392// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1
1393//
1394// Unencryped SHA256 example:
1360// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' 1395// openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost'
1396// openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL
1397// openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256
1361 1398
1362int tls_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1399int tls_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1363int tls_main(int argc UNUSED_PARAM, char **argv) 1400int tls_main(int argc UNUSED_PARAM, char **argv)
@@ -1381,12 +1418,8 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1381 1418
1382 return EXIT_SUCCESS; 1419 return EXIT_SUCCESS;
1383} 1420}
1384
1385/* Unencryped SHA256 example: 1421/* Unencryped SHA256 example:
1386 * $ openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' 1422 * s_client says:
1387 * $ openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL
1388 * $ openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256
1389 * s_client says:
1390 1423
1391write to 0x1d750b0 [0x1e6f153] (99 bytes => 99 (0x63)) 1424write to 0x1d750b0 [0x1e6f153] (99 bytes => 99 (0x63))
13920000 - 16 03 01 005e 01 00005a 0303 [4d ef 5c 82 3e ....^...Z..M.\.> >> ClHello 14250000 - 16 03 01 005e 01 00005a 0303 [4d ef 5c 82 3e ....^...Z..M.\.> >> ClHello