void sender(char *key, int key_len, char *message) /*@ requires [_]public_invar(hmac_pub) &*& principal(?sender, _) &*& [?f1]cryptogram(key, key_len, ?key_cs, ?key_cg) &*& key_cg == cg_symmetric_key(sender, ?id) &*& [?f2]chars(message, MESSAGE_SIZE, ?msg_cs) &*& true == send(sender, shared_with(sender, id), msg_cs); @*/ /*@ ensures principal(sender, _) &*& [f1]cryptogram(key, key_len, key_cs, key_cg) &*& [f2]chars(message, MESSAGE_SIZE, msg_cs); @*/ { //@ open principal(sender, _); int socket; char hmac[64]; net_usleep(20000); if(net_connect(&socket, NULL, SERVER_PORT) != 0) abort(); if(net_set_block(socket) != 0) abort(); { int message_len = MESSAGE_SIZE + 64; char* M = malloc(message_len); if (M == 0) abort(); //@ chars_to_crypto_chars(message, MESSAGE_SIZE); memcpy(M, message, MESSAGE_SIZE); sha512_hmac(key, (unsigned int) key_len, M, (unsigned int) MESSAGE_SIZE, hmac, 0); //@ assert cryptogram(hmac, 64, ?hmac_cs, ?hmac_cg); //@ close hmac_pub(hmac_cg); //@ leak hmac_pub(hmac_cg); //@ public_cryptogram(hmac, hmac_cg); //@ chars_to_crypto_chars(hmac, 64); memcpy(M + MESSAGE_SIZE, hmac, 64); //@ crypto_chars_to_chars(M, MESSAGE_SIZE); //@ crypto_chars_to_chars(M + MESSAGE_SIZE, 64); //@ chars_join(M); net_send(&socket, M, (unsigned int) message_len); free(M); } net_close(socket); //@ close principal(sender, _); }
void receiver(int sender, int receiver, char *s_pub_key, char *r_priv_key, char *s_nonce, char *r_nonce) /*@ requires [_]public_invar(nsl_pub) &*& [_]decryption_key_classifier(nsl_public_key) &*& principal(receiver, _) &*& [?f1]cryptogram(s_pub_key, 8 * KEY_SIZE, ?s_pub_key_ccs, ?s_pub_key_cg) &*& s_pub_key_cg == cg_public_key(sender, ?s_id) &*& [?f2]cryptogram(r_priv_key, 8 * KEY_SIZE, ?r_priv_key_ccs, ?r_priv_key_cg) &*& r_priv_key_cg == cg_private_key(receiver, ?r_id) &*& chars(s_nonce, NONCE_SIZE, _) &*& chars(r_nonce, NONCE_SIZE, _); @*/ /*@ ensures principal(receiver, _) &*& [f1]cryptogram(s_pub_key, 8 * KEY_SIZE, s_pub_key_ccs, s_pub_key_cg) &*& [f2]cryptogram(r_priv_key, 8 * KEY_SIZE, r_priv_key_ccs, r_priv_key_cg) &*& cryptogram(r_nonce, NONCE_SIZE, ?r_nonce_ccs, ?r_nonce_cg) &*& r_nonce_cg == cg_nonce(receiver, _) &*& ( col || bad(sender) || bad(receiver) ? chars(s_nonce, NONCE_SIZE, _) : cryptogram(s_nonce, NONCE_SIZE, ?s_nonce_ccs, ?s_nonce_cg) &*& s_nonce_cg == cg_nonce(sender, _) &*& cg_info(s_nonce_cg) == int_pair(1, int_pair(receiver, r_id)) &*& cg_info(r_nonce_cg) == int_pair(2, int_pair(sender, int_pair(sender, int_pair(receiver, r_id)))) ); @*/ { //@ open principal(receiver, _); int socket1; int socket2; pk_context s_context; pk_context r_context; havege_state havege_state; if(net_bind(&socket1, NULL, SERVER_PORT) != 0) abort(); if(net_accept(socket1, &socket2, NULL) != 0) abort(); if(net_set_block(socket2) != 0) abort(); //@ close pk_context(&s_context); pk_init(&s_context); if (pk_parse_public_key(&s_context, s_pub_key, (unsigned int) 8 * KEY_SIZE) != 0) abort(); //@ close pk_context(&r_context); pk_init(&r_context); if (pk_parse_key(&r_context, r_priv_key, (unsigned int) 8 * KEY_SIZE, NULL, 0) != 0) abort(); // Generate NB //@ close havege_state(&havege_state); havege_init(&havege_state); //@ close principal(receiver, _); receiver_msg1(&socket2, &havege_state, &r_context, sender, receiver, s_nonce); //@ open principal(receiver, _); //@ assert receiver_inter(?p_orig, ?c_orig, ?p_inst, ?s_nonce_ccs, ?s_nonce_cg); //@ int info = int_pair(sender, int_pair(p_inst, int_pair(p_orig, c_orig))); //@ close random_request(receiver, int_pair(2, info), false); if (havege_random(&havege_state, r_nonce, NONCE_SIZE) != 0) abort(); //@ close principal(receiver, _); receiver_msg2(&socket2, &havege_state, &s_context, receiver, s_nonce, r_nonce); //@ if (col || bad(p_inst) || bad(receiver)) chars_to_crypto_chars(s_nonce, NONCE_SIZE); //@ close receiver_inter(p_orig, c_orig, p_inst, s_nonce_ccs, s_nonce_cg); receiver_msg3(&socket2, &havege_state, &r_context, sender, receiver, s_nonce, r_nonce); /*@ if (col || bad(sender) || bad(receiver)) crypto_chars_to_chars(s_nonce, NONCE_SIZE); @*/ havege_free(&havege_state); //@ open havege_state(&havege_state); //@ pk_release_context_with_key(&s_context); pk_free(&s_context); //@ open pk_context(&s_context); //@ pk_release_context_with_key(&r_context); pk_free(&r_context); //@ open pk_context(&r_context); net_close(socket2); net_close(socket1); }
void receiver(char *key, int key_len, char *message) /*@ requires [_]public_invar(hmac_pub) &*& principal(?receiver, _) &*& [?f1]cryptogram(key, key_len, ?key_cs, ?key_cg) &*& key_cg == cg_symmetric_key(?sender, ?id) &*& receiver == shared_with(sender, id) &*& chars(message, MESSAGE_SIZE, _); @*/ /*@ ensures principal(receiver, _) &*& [f1]cryptogram(key, key_len, key_cs, key_cg) &*& chars(message, MESSAGE_SIZE, ?msg_cs) &*& col || bad(sender) || bad(receiver) || send(sender, receiver, msg_cs); @*/ { //@ open principal(receiver, _); int socket1; int socket2; if(net_bind(&socket1, NULL, SERVER_PORT) != 0) abort(); if(net_accept(socket1, &socket2, NULL) != 0) abort(); if(net_set_block(socket2) != 0) abort(); { int size; char buffer[MAX_MESSAGE_SIZE]; char hmac[64]; size = net_recv(&socket2, buffer, MAX_MESSAGE_SIZE); int expected_size = MESSAGE_SIZE + 64; if (size != expected_size) abort(); //@ chars_split(buffer, expected_size); //@ assert chars(buffer, MESSAGE_SIZE, ?msg_cs); /*@ close hide_chars((void*) buffer + expected_size, MAX_MESSAGE_SIZE - expected_size, _); @*/ //Verify the hmac //@ chars_to_crypto_chars(buffer, MESSAGE_SIZE); sha512_hmac(key, (unsigned int) key_len, buffer, (unsigned int) MESSAGE_SIZE, hmac, 0); memcpy(message, (void*) buffer , MESSAGE_SIZE); //@ open cryptogram(hmac, 64, ?hmac_cs, ?hmac_cg); //@ close memcmp_secret(hmac, 64, hmac_cs, hmac_cg); //@ assert hmac_cg == cg_hmac(sender, id, msg_cs); //@ assert chars((void*) buffer + MESSAGE_SIZE, 64, ?hmac_cs2); //@ public_chars((void*) buffer + MESSAGE_SIZE, 64); //@ chars_to_crypto_chars((void*) buffer + MESSAGE_SIZE, 64); if (memcmp((void*) buffer + MESSAGE_SIZE, hmac, 64) != 0) abort(); //@ crypto_chars_join(buffer); //@ crypto_chars_to_chars(buffer, expected_size); //@ public_crypto_chars(hmac, 64); /*@ if (!col && !bad(sender) && !bad(receiver)) { public_chars_extract(hmac, hmac_cg); open [_]hmac_pub(hmac_cg); assert (send(sender, receiver, msg_cs) == true); } @*/ /*@ open hide_chars((void*) buffer + expected_size, MAX_MESSAGE_SIZE - expected_size, _); @*/ } net_close(socket2); net_close(socket1); //@ close principal(receiver, _); }
int main( int argc, char *argv[] ) { int ret = 0, len, server_fd, i, written, frags; unsigned char buf[SSL_MAX_CONTENT_LEN + 1]; #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) unsigned char psk[POLARSSL_PSK_MAX_LEN]; size_t psk_len = 0; #endif #if defined(POLARSSL_SSL_ALPN) const char *alpn_list[10]; #endif const char *pers = "ssl_client2"; entropy_context entropy; ctr_drbg_context ctr_drbg; ssl_context ssl; ssl_session saved_session; #if defined(POLARSSL_X509_CRT_PARSE_C) x509_crt cacert; x509_crt clicert; pk_context pkey; #endif char *p, *q; const int *list; /* * Make sure memory references are valid. */ server_fd = 0; memset( &ssl, 0, sizeof( ssl_context ) ); memset( &saved_session, 0, sizeof( ssl_session ) ); #if defined(POLARSSL_X509_CRT_PARSE_C) x509_crt_init( &cacert ); x509_crt_init( &clicert ); pk_init( &pkey ); #endif #if defined(POLARSSL_SSL_ALPN) memset( (void * ) alpn_list, 0, sizeof( alpn_list ) ); #endif if( argc == 0 ) { usage: if( ret == 0 ) ret = 1; printf( USAGE ); list = ssl_list_ciphersuites(); while( *list ) { printf(" %-42s", ssl_get_ciphersuite_name( *list ) ); list++; if( !*list ) break; printf(" %s\n", ssl_get_ciphersuite_name( *list ) ); list++; } printf("\n"); goto exit; } opt.server_name = DFL_SERVER_NAME; opt.server_addr = DFL_SERVER_ADDR; opt.server_port = DFL_SERVER_PORT; opt.debug_level = DFL_DEBUG_LEVEL; opt.nbio = DFL_NBIO; opt.request_page = DFL_REQUEST_PAGE; opt.request_size = DFL_REQUEST_SIZE; opt.ca_file = DFL_CA_FILE; opt.ca_path = DFL_CA_PATH; opt.crt_file = DFL_CRT_FILE; opt.key_file = DFL_KEY_FILE; opt.psk = DFL_PSK; opt.psk_identity = DFL_PSK_IDENTITY; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; opt.renegotiate = DFL_RENEGOTIATE; opt.min_version = DFL_MIN_VERSION; opt.max_version = DFL_MAX_VERSION; opt.auth_mode = DFL_AUTH_MODE; opt.mfl_code = DFL_MFL_CODE; opt.trunc_hmac = DFL_TRUNC_HMAC; opt.reconnect = DFL_RECONNECT; opt.reco_delay = DFL_RECO_DELAY; opt.tickets = DFL_TICKETS; opt.alpn_string = DFL_ALPN_STRING; for( i = 1; i < argc; i++ ) { p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; if( strcmp( p, "server_name" ) == 0 ) opt.server_name = q; else if( strcmp( p, "server_addr" ) == 0 ) opt.server_addr = q; else if( strcmp( p, "server_port" ) == 0 ) { opt.server_port = atoi( q ); if( opt.server_port < 1 || opt.server_port > 65535 ) goto usage; } else if( strcmp( p, "debug_level" ) == 0 ) { opt.debug_level = atoi( q ); if( opt.debug_level < 0 || opt.debug_level > 65535 ) goto usage; } else if( strcmp( p, "nbio" ) == 0 ) { opt.nbio = atoi( q ); if( opt.nbio < 0 || opt.nbio > 2 ) goto usage; } else if( strcmp( p, "request_page" ) == 0 ) opt.request_page = q; else if( strcmp( p, "request_size" ) == 0 ) { opt.request_size = atoi( q ); if( opt.request_size < 0 || opt.request_size > SSL_MAX_CONTENT_LEN ) goto usage; } else if( strcmp( p, "ca_file" ) == 0 ) opt.ca_file = q; else if( strcmp( p, "ca_path" ) == 0 ) opt.ca_path = q; else if( strcmp( p, "crt_file" ) == 0 ) opt.crt_file = q; else if( strcmp( p, "key_file" ) == 0 ) opt.key_file = q; else if( strcmp( p, "psk" ) == 0 ) opt.psk = q; else if( strcmp( p, "psk_identity" ) == 0 ) opt.psk_identity = q; else if( strcmp( p, "force_ciphersuite" ) == 0 ) { opt.force_ciphersuite[0] = ssl_get_ciphersuite_id( q ); if( opt.force_ciphersuite[0] == 0 ) { ret = 2; goto usage; } opt.force_ciphersuite[1] = 0; } else if( strcmp( p, "renegotiation" ) == 0 ) { opt.renegotiation = (atoi( q )) ? SSL_RENEGOTIATION_ENABLED : SSL_RENEGOTIATION_DISABLED; } else if( strcmp( p, "allow_legacy" ) == 0 ) { opt.allow_legacy = atoi( q ); if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) goto usage; } else if( strcmp( p, "renegotiate" ) == 0 ) { opt.renegotiate = atoi( q ); if( opt.renegotiate < 0 || opt.renegotiate > 1 ) goto usage; } else if( strcmp( p, "reconnect" ) == 0 ) { opt.reconnect = atoi( q ); if( opt.reconnect < 0 || opt.reconnect > 2 ) goto usage; } else if( strcmp( p, "reco_delay" ) == 0 ) { opt.reco_delay = atoi( q ); if( opt.reco_delay < 0 ) goto usage; } else if( strcmp( p, "tickets" ) == 0 ) { opt.tickets = atoi( q ); if( opt.tickets < 0 || opt.tickets > 2 ) goto usage; } else if( strcmp( p, "alpn" ) == 0 ) { opt.alpn_string = q; } else if( strcmp( p, "min_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_0; else if( strcmp( q, "tls1" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_1; else if( strcmp( q, "tls1_1" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_2; else if( strcmp( q, "tls1_2" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_3; else goto usage; } else if( strcmp( p, "max_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_0; else if( strcmp( q, "tls1" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_1; else if( strcmp( q, "tls1_1" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_2; else if( strcmp( q, "tls1_2" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_3; else goto usage; } else if( strcmp( p, "force_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_0; opt.max_version = SSL_MINOR_VERSION_0; } else if( strcmp( q, "tls1" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_1; opt.max_version = SSL_MINOR_VERSION_1; } else if( strcmp( q, "tls1_1" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_2; opt.max_version = SSL_MINOR_VERSION_2; } else if( strcmp( q, "tls1_2" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_3; opt.max_version = SSL_MINOR_VERSION_3; } else goto usage; } else if( strcmp( p, "auth_mode" ) == 0 ) { if( strcmp( q, "none" ) == 0 ) opt.auth_mode = SSL_VERIFY_NONE; else if( strcmp( q, "optional" ) == 0 ) opt.auth_mode = SSL_VERIFY_OPTIONAL; else if( strcmp( q, "required" ) == 0 ) opt.auth_mode = SSL_VERIFY_REQUIRED; else goto usage; } else if( strcmp( p, "max_frag_len" ) == 0 ) { if( strcmp( q, "512" ) == 0 ) opt.mfl_code = SSL_MAX_FRAG_LEN_512; else if( strcmp( q, "1024" ) == 0 ) opt.mfl_code = SSL_MAX_FRAG_LEN_1024; else if( strcmp( q, "2048" ) == 0 ) opt.mfl_code = SSL_MAX_FRAG_LEN_2048; else if( strcmp( q, "4096" ) == 0 ) opt.mfl_code = SSL_MAX_FRAG_LEN_4096; else goto usage; } else if( strcmp( p, "trunc_hmac" ) == 0 ) { opt.trunc_hmac = atoi( q ); if( opt.trunc_hmac < 0 || opt.trunc_hmac > 1 ) goto usage; } else goto usage; } #if defined(POLARSSL_DEBUG_C) debug_set_threshold( opt.debug_level ); #endif if( opt.force_ciphersuite[0] > 0 ) { const ssl_ciphersuite_t *ciphersuite_info; ciphersuite_info = ssl_ciphersuite_from_id( opt.force_ciphersuite[0] ); if( opt.max_version != -1 && ciphersuite_info->min_minor_ver > opt.max_version ) { printf("forced ciphersuite not allowed with this protocol version\n"); ret = 2; goto usage; } if( opt.min_version != -1 && ciphersuite_info->max_minor_ver < opt.min_version ) { printf("forced ciphersuite not allowed with this protocol version\n"); ret = 2; goto usage; } if( opt.max_version > ciphersuite_info->max_minor_ver ) opt.max_version = ciphersuite_info->max_minor_ver; if( opt.min_version < ciphersuite_info->min_minor_ver ) opt.min_version = ciphersuite_info->min_minor_ver; } #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) /* * Unhexify the pre-shared key if any is given */ if( strlen( opt.psk ) ) { unsigned char c; size_t j; if( strlen( opt.psk ) % 2 != 0 ) { printf("pre-shared key not valid hex\n"); goto exit; } psk_len = strlen( opt.psk ) / 2; for( j = 0; j < strlen( opt.psk ); j += 2 ) { c = opt.psk[j]; if( c >= '0' && c <= '9' ) c -= '0'; else if( c >= 'a' && c <= 'f' ) c -= 'a' - 10; else if( c >= 'A' && c <= 'F' ) c -= 'A' - 10; else { printf("pre-shared key not valid hex\n"); goto exit; } psk[ j / 2 ] = c << 4; c = opt.psk[j + 1]; if( c >= '0' && c <= '9' ) c -= '0'; else if( c >= 'a' && c <= 'f' ) c -= 'a' - 10; else if( c >= 'A' && c <= 'F' ) c -= 'A' - 10; else { printf("pre-shared key not valid hex\n"); goto exit; } psk[ j / 2 ] |= c; } } #endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ #if defined(POLARSSL_SSL_ALPN) if( opt.alpn_string != NULL ) { p = (char *) opt.alpn_string; i = 0; /* Leave room for a final NULL in alpn_list */ while( i < (int) sizeof alpn_list - 1 && *p != '\0' ) { alpn_list[i++] = p; /* Terminate the current string and move on to next one */ while( *p != ',' && *p != '\0' ) p++; if( *p == ',' ) *p++ = '\0'; } } #endif /* POLARSSL_SSL_ALPN */ /* * 0. Initialize the RNG and the session data */ printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( " failed\n ! ctr_drbg_init returned -0x%x\n", -ret ); goto exit; } printf( " ok\n" ); #if defined(POLARSSL_X509_CRT_PARSE_C) /* * 1.1. Load the trusted CA */ printf( " . Loading the CA root certificate ..." ); fflush( stdout ); #if defined(POLARSSL_FS_IO) if( strlen( opt.ca_path ) ) if( strcmp( opt.ca_path, "none" ) == 0 ) ret = 0; else ret = x509_crt_parse_path( &cacert, opt.ca_path ); else if( strlen( opt.ca_file ) ) if( strcmp( opt.ca_file, "none" ) == 0 ) ret = 0; else ret = x509_crt_parse_file( &cacert, opt.ca_file ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_list, strlen( test_ca_list ) ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret < 0 ) { printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret ); goto exit; } printf( " ok (%d skipped)\n", ret ); /* * 1.2. Load own certificate and private key * * (can be skipped if client authentication is not required) */ printf( " . Loading the client cert. and key..." ); fflush( stdout ); #if defined(POLARSSL_FS_IO) if( strlen( opt.crt_file ) ) if( strcmp( opt.crt_file, "none" ) == 0 ) ret = 0; else ret = x509_crt_parse_file( &clicert, opt.crt_file ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt, strlen( test_cli_crt ) ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret != 0 ) { printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret ); goto exit; } #if defined(POLARSSL_FS_IO) if( strlen( opt.key_file ) ) if( strcmp( opt.key_file, "none" ) == 0 ) ret = 0; else ret = pk_parse_keyfile( &pkey, opt.key_file, "" ); else #endif #if defined(POLARSSL_CERTS_C) ret = pk_parse_key( &pkey, (const unsigned char *) test_cli_key, strlen( test_cli_key ), NULL, 0 ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret != 0 ) { printf( " failed\n ! pk_parse_key returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); #endif /* POLARSSL_X509_CRT_PARSE_C */ /* * 2. Start the connection */ if( opt.server_addr == NULL) opt.server_addr = opt.server_name; printf( " . Connecting to tcp/%s/%-4d...", opt.server_addr, opt.server_port ); fflush( stdout ); if( ( ret = net_connect( &server_fd, opt.server_addr, opt.server_port ) ) != 0 ) { printf( " failed\n ! net_connect returned -0x%x\n\n", -ret ); goto exit; } if( opt.nbio > 0 ) ret = net_set_nonblock( server_fd ); else ret = net_set_block( server_fd ); if( ret != 0 ) { printf( " failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); /* * 3. Setup stuff */ printf( " . Setting up the SSL/TLS structure..." ); fflush( stdout ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); #if defined(POLARSSL_X509_CRT_PARSE_C) if( opt.debug_level > 0 ) ssl_set_verify( &ssl, my_verify, NULL ); #endif ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); ssl_set_authmode( &ssl, opt.auth_mode ); #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) if( ( ret = ssl_set_max_frag_len( &ssl, opt.mfl_code ) ) != 0 ) { printf( " failed\n ! ssl_set_max_frag_len returned %d\n\n", ret ); goto exit; } #endif #if defined(POLARSSL_SSL_TRUNCATED_HMAC) if( opt.trunc_hmac != 0 ) if( ( ret = ssl_set_truncated_hmac( &ssl, SSL_TRUNC_HMAC_ENABLED ) ) != 0 ) { printf( " failed\n ! ssl_set_truncated_hmac returned %d\n\n", ret ); goto exit; } #endif #if defined(POLARSSL_SSL_ALPN) if( opt.alpn_string != NULL ) if( ( ret = ssl_set_alpn_protocols( &ssl, alpn_list ) ) != 0 ) { printf( " failed\n ! ssl_set_alpn_protocols returned %d\n\n", ret ); goto exit; } #endif ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout ); if( opt.nbio == 2 ) ssl_set_bio( &ssl, my_recv, &server_fd, my_send, &server_fd ); else ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd ); #if defined(POLARSSL_SSL_SESSION_TICKETS) if( ( ret = ssl_set_session_tickets( &ssl, opt.tickets ) ) != 0 ) { printf( " failed\n ! ssl_set_session_tickets returned %d\n\n", ret ); goto exit; } #endif if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER ) ssl_set_ciphersuites( &ssl, opt.force_ciphersuite ); ssl_set_renegotiation( &ssl, opt.renegotiation ); ssl_legacy_renegotiation( &ssl, opt.allow_legacy ); #if defined(POLARSSL_X509_CRT_PARSE_C) if( strcmp( opt.ca_path, "none" ) != 0 && strcmp( opt.ca_file, "none" ) != 0 ) { ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name ); } if( strcmp( opt.crt_file, "none" ) != 0 && strcmp( opt.key_file, "none" ) != 0 ) { if( ( ret = ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 ) { printf( " failed\n ! ssl_set_own_cert returned %d\n\n", ret ); goto exit; } } #endif #if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) if( ( ret = ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity, strlen( opt.psk_identity ) ) ) != 0 ) { printf( " failed\n ! ssl_set_psk returned %d\n\n", ret ); goto exit; } #endif #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) if( ( ret = ssl_set_hostname( &ssl, opt.server_name ) ) != 0 ) { printf( " failed\n ! ssl_set_hostname returned %d\n\n", ret ); goto exit; } #endif if( opt.min_version != -1 ) ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version ); if( opt.max_version != -1 ) ssl_set_max_version( &ssl, SSL_MAJOR_VERSION_3, opt.max_version ); /* * 4. Handshake */ printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n", -ret ); if( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED ) printf( " Unable to verify the server's certificate. " "Either it is invalid,\n" " or you didn't set ca_file or ca_path " "to an appropriate value.\n" " Alternatively, you may want to use " "auth_mode=optional for testing purposes.\n" ); printf( "\n" ); goto exit; } } printf( " ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", ssl_get_version( &ssl ), ssl_get_ciphersuite( &ssl ) ); #if defined(POLARSSL_SSL_ALPN) if( opt.alpn_string != NULL ) { const char *alp = ssl_get_alpn_protocol( &ssl ); printf( " [ Application Layer Protocol is %s ]\n", alp ? alp : "(none)" ); } #endif if( opt.reconnect != 0 ) { printf(" . Saving session for reuse..." ); fflush( stdout ); if( ( ret = ssl_get_session( &ssl, &saved_session ) ) != 0 ) { printf( " failed\n ! ssl_get_session returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); } #if defined(POLARSSL_X509_CRT_PARSE_C) /* * 5. Verify the server certificate */ printf( " . Verifying peer X.509 certificate..." ); if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 ) { printf( " failed\n" ); if( ( ret & BADCERT_EXPIRED ) != 0 ) printf( " ! server certificate has expired\n" ); if( ( ret & BADCERT_REVOKED ) != 0 ) printf( " ! server certificate has been revoked\n" ); if( ( ret & BADCERT_CN_MISMATCH ) != 0 ) printf( " ! CN mismatch (expected CN=%s)\n", opt.server_name ); if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) printf( " ! self-signed or not signed by a trusted CA\n" ); printf( "\n" ); } else printf( " ok\n" ); if( ssl_get_peer_cert( &ssl ) != NULL ) { printf( " . Peer certificate information ...\n" ); x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ", ssl_get_peer_cert( &ssl ) ); printf( "%s\n", buf ); } #endif /* POLARSSL_X509_CRT_PARSE_C */ if( opt.renegotiate ) { /* * Perform renegotiation (this must be done when the server is waiting * for input from our side). */ printf( " . Performing renegotiation..." ); fflush( stdout ); while( ( ret = ssl_renegotiate( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret ); goto exit; } } printf( " ok\n" ); } /* * 6. Write the GET request */ send_request: printf( " > Write to server:" ); fflush( stdout ); if( strcmp( opt.request_page, "SERVERQUIT" ) == 0 ) len = sprintf( (char *) buf, "%s", opt.request_page ); else { size_t tail_len = strlen( GET_REQUEST_END ); len = snprintf( (char *) buf, sizeof(buf) - 1, GET_REQUEST, opt.request_page ); /* Add padding to GET request to reach opt.request_size in length */ if( opt.request_size != DFL_REQUEST_SIZE && len + tail_len < (size_t) opt.request_size ) { memset( buf + len, 'A', opt.request_size - len - tail_len ); len += opt.request_size - len - tail_len; } strncpy( (char *) buf + len, GET_REQUEST_END, sizeof(buf) - len - 1 ); len += tail_len; } /* Truncate if request size is smaller than the "natural" size */ if( opt.request_size != DFL_REQUEST_SIZE && len > opt.request_size ) { len = opt.request_size; /* Still end with \r\n unless that's really not possible */ if( len >= 2 ) buf[len - 2] = '\r'; if( len >= 1 ) buf[len - 1] = '\n'; } for( written = 0, frags = 0; written < len; written += ret, frags++ ) { while( ( ret = ssl_write( &ssl, buf + written, len - written ) ) <= 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_write returned -0x%x\n\n", -ret ); goto exit; } } } buf[written] = '\0'; printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf ); /* * 7. Read the HTTP response */ printf( " < Read from server:" ); fflush( stdout ); do { len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); ret = ssl_read( &ssl, buf, len ); if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) continue; if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) break; if( ret < 0 ) { printf( "failed\n ! ssl_read returned -0x%x\n\n", -ret ); break; } if( ret == 0 ) { printf("\n\nEOF\n\n"); ssl_close_notify( &ssl ); break; } len = ret; buf[len] = '\0'; printf( " %d bytes read\n\n%s", len, (char *) buf ); } while( 1 ); if( opt.reconnect != 0 ) { --opt.reconnect; net_close( server_fd ); #if defined(POLARSSL_TIMING_C) if( opt.reco_delay > 0 ) m_sleep( 1000 * opt.reco_delay ); #endif printf( " . Reconnecting with saved session..." ); fflush( stdout ); if( ( ret = ssl_session_reset( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_session_reset returned -0x%x\n\n", -ret ); goto exit; } if( ( ret = ssl_set_session( &ssl, &saved_session ) ) != 0 ) { printf( " failed\n ! ssl_set_session returned %d\n\n", ret ); goto exit; } if( ( ret = net_connect( &server_fd, opt.server_name, opt.server_port ) ) != 0 ) { printf( " failed\n ! net_connect returned -0x%x\n\n", -ret ); goto exit; } while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); goto exit; } } printf( " ok\n" ); goto send_request; } exit: if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) ret = 0; #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; polarssl_strerror( ret, error_buf, 100 ); printf("Last error was: -0x%X - %s\n\n", -ret, error_buf ); } #endif if( server_fd ) net_close( server_fd ); #if defined(POLARSSL_X509_CRT_PARSE_C) x509_crt_free( &clicert ); x509_crt_free( &cacert ); pk_free( &pkey ); #endif ssl_session_free( &saved_session ); ssl_free( &ssl ); ctr_drbg_free( &ctr_drbg ); entropy_free( &entropy ); memset( &ssl, 0, sizeof( ssl ) ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif // Shell can not handle large exit numbers -> 1 for errors if( ret < 0 ) ret = 1; return( ret ); }
void sender(int sender, int receiver, char *s_priv_key, char *r_pub_key, char *s_nonce, char *r_nonce) /*@ requires [_]public_invar(nsl_pub) &*& [_]decryption_key_classifier(nsl_public_key) &*& principal(sender, _) &*& [?f1]cryptogram(s_priv_key, 8 * KEY_SIZE, ?s_priv_key_ccs, ?s_priv_key_cg) &*& s_priv_key_cg == cg_private_key(sender, ?s_id) &*& [?f2]cryptogram(r_pub_key, 8 * KEY_SIZE, ?r_pub_key_ccs, ?r_pub_key_cg) &*& r_pub_key_cg == cg_public_key(receiver, ?r_id) &*& chars(s_nonce, NONCE_SIZE, _) &*& chars(r_nonce, NONCE_SIZE, _); @*/ /*@ ensures principal(sender, _) &*& [f1]cryptogram(s_priv_key, 8 * KEY_SIZE, s_priv_key_ccs, s_priv_key_cg) &*& [f2]cryptogram(r_pub_key, 8 * KEY_SIZE, r_pub_key_ccs, r_pub_key_cg) &*& cryptogram(s_nonce, NONCE_SIZE, ?s_nonce_ccs, ?s_nonce_cg) &*& s_nonce_cg == cg_nonce(sender, _) &*& cg_info(s_nonce_cg) == int_pair(1, int_pair(receiver, r_id)) &*& col || bad(sender) || bad(receiver) ? chars(r_nonce, NONCE_SIZE, _) : cryptogram(r_nonce, NONCE_SIZE, _, ?r_nonce_cg) &*& r_nonce_cg == cg_nonce(receiver, _) &*& cg_info(r_nonce_cg) == int_pair(2, int_pair(sender, int_pair(sender, int_pair(receiver, r_id)))); @*/ { int socket; pk_context s_context; pk_context r_context; havege_state havege_state; net_usleep(20000); if(net_connect(&socket, NULL, SERVER_PORT) != 0) abort(); if(net_set_block(socket) != 0) abort(); //@ close pk_context(&s_context); pk_init(&s_context); if (pk_parse_key(&s_context, s_priv_key, (unsigned int) 8 * KEY_SIZE, NULL, 0) != 0) abort(); //@ close pk_context(&r_context); pk_init(&r_context); if (pk_parse_public_key(&r_context, r_pub_key, (unsigned int) 8 * KEY_SIZE) != 0) abort(); // Generate NA //@ open principal(sender, _); //@ close havege_state(&havege_state); havege_init(&havege_state); //@ close random_request(sender, int_pair(1, int_pair(receiver, r_id)), false); if (havege_random(&havege_state, s_nonce, NONCE_SIZE) != 0) abort(); //@ assert cryptogram(s_nonce, NONCE_SIZE, ?cs_s_nonce, ?cg_s_nonce); //@ close principal(sender, _); sender_msg1(&socket, &havege_state, &r_context, sender, s_nonce); sender_msg2(&socket, &havege_state, &s_context, sender, receiver, s_nonce, r_nonce); sender_msg3(&socket, &havege_state, &r_context, sender, r_nonce); havege_free(&havege_state); //@ open havege_state(&havege_state); //@ pk_release_context_with_key(&s_context); pk_free(&s_context); //@ open pk_context(&s_context); //@ pk_release_context_with_key(&r_context); pk_free(&r_context); //@ open pk_context(&r_context); net_close(socket); }
void app_send(char *key, char *message, int message_len) /*@ requires polarssl_generated_values(?creator, ?count1) &*& [?f0]polarssl_world(sc_auth_polarssl_pub) &*& [?f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, ?key_cs, ?key_cg) &*& key_cg == polarssl_symmetric_key(creator, ?key_id) &*& [?f2]chars(message, message_len, ?m_cs) &*& message_len >= POLARSSL_MIN_ENCRYPTED_BYTE_SIZE &*& message_len < POLARSSL_MAX_MESSAGE_BYTE_SIZE - 84 &*& bad(creator) ? [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(m_cs) : true == app_send_event(creator, m_cs); @*/ /*@ ensures polarssl_generated_values(creator, ?count2) &*& count2 > count1 &*& [f0]polarssl_world(sc_auth_polarssl_pub) &*& [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg) &*& [f2]chars(message, message_len, m_cs); @*/ { int socket; havege_state havege_state; char iv[16]; // init { net_usleep(20000); if(net_connect(&socket, NULL, APP_RECEIVE_PORT) != 0) abort(); if(net_set_block(socket) != 0) abort(); //@ close havege_state(&havege_state); havege_init(&havege_state); } // iv stuff { //@ close random_request(creator, 0, false); if (havege_random(&havege_state, iv, 16) != 0) abort(); } //@ open polarssl_cryptogram(iv, 16, ?iv_cs, _); char* m = malloc(16 + message_len + 16); if (m == 0) abort(); memcpy(m, iv, 16); //@ assert chars(m, 16, iv_cs); //@ assert chars(m + 16, message_len + 16, ?cs1); //@ polarssl_public_generated_chars_assume(sc_auth_polarssl_pub, iv_cs); // encrypt message { unsigned int temp; gcm_context gcm_context; //@ close gcm_context(&gcm_context); //@ open [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg); //@ close polarssl_key_id(creator, key_id); if (gcm_init(&gcm_context, POLARSSL_AES_CIPHER_ID, key, (unsigned int) KEY_BYTE_SIZE * 8) != 0) abort(); //@ close [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg); //@ chars_split(m + 16, message_len); if (gcm_crypt_and_tag(&gcm_context, POLARSSL_GCM_ENCRYPT, (unsigned int) message_len, iv, 16, NULL, 0, message, m + 16, 16, (char*) ((m + 16) + message_len)) != 0) abort(); gcm_free(&gcm_context); //@ open gcm_context(&gcm_context); } //@ assert polarssl_cryptogram(m + 16, message_len, ?e_cs, ?e_cg); /*@ assert e_cg == polarssl_auth_encrypted( creator, key_id, ?t_cs, m_cs, iv_cs); @*/ //@ close sc_auth_polarssl_pub(e_cg); //@ leak sc_auth_polarssl_pub(e_cg); /*@ polarssl_public_message_from_cryptogram( sc_auth_polarssl_pub, m + 16, message_len, e_cs, e_cg); @*/ /*@ open polarssl_public_message(sc_auth_polarssl_pub) (m + 16, message_len, e_cs); @*/ //@ assert chars(m + 16 + message_len, 16, t_cs); //@ chars_join(m); //@ chars_join(m); //@ assert chars(m, 16 + message_len + 16, ?cs); //@ append_assoc(iv_cs, e_cs, t_cs); //@ assert cs == append(iv_cs, append(e_cs, t_cs)); //@ polarssl_public_generated_chars_assume(sc_auth_polarssl_pub, t_cs); /*@ polarssl_public_generated_chars_join( sc_auth_polarssl_pub, iv_cs, e_cs); @*/ /*@ polarssl_public_generated_chars_join( sc_auth_polarssl_pub, append(iv_cs, e_cs), t_cs); @*/ /*@ close polarssl_public_message(sc_auth_polarssl_pub) (m, 16 + message_len + 16, append(iv_cs, append(e_cs, t_cs))); @*/ net_send(&socket, m, (unsigned int) 16 + (unsigned int) message_len + 16); //@ open polarssl_public_message(sc_auth_polarssl_pub)(m, _, _); { free(m); havege_free(&havege_state); //@ open havege_state(&havege_state); net_close(socket); } }
int app_receive(char *key, char **message) /*@ requires [?f0]polarssl_world(sc_auth_polarssl_pub) &*& [?f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, ?key_cs, ?key_cg) &*& key_cg == polarssl_symmetric_key(?creator, ?key_id) &*& pointer(message, _); @*/ /*@ ensures [f0]polarssl_world(sc_auth_polarssl_pub) &*& [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg) &*& pointer(message, ?message_p) &*& malloc_block(message_p, result) &*& chars(message_p, result, ?m_cs) &*& bad(creator) ? [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(m_cs) : true == app_send_event(creator, m_cs); @*/ { int socket1; int socket2; int size; int result_size; char buffer[POLARSSL_MAX_MESSAGE_BYTE_SIZE]; char iv[16]; char tag[16]; char* encrypted; char* decrypted; // Receive message if(net_bind(&socket1, NULL, APP_RECEIVE_PORT) != 0) abort(); if(net_accept(socket1, &socket2, NULL) != 0) abort(); if(net_set_block(socket2) != 0) abort(); size = net_recv(&socket2, buffer, POLARSSL_MAX_MESSAGE_BYTE_SIZE); if (size < 16 + POLARSSL_MIN_ENCRYPTED_BYTE_SIZE + 16) abort(); //@ open polarssl_public_message(sc_auth_polarssl_pub)(buffer, size, ?cs); //@ close [1/2]hide_chars(buffer, size, cs); result_size = size - 16 - 16; encrypted = malloc(result_size); if (encrypted == 0) abort(); decrypted = malloc(result_size); if (decrypted == 0) abort(); // Extract parts of message memcpy(iv, buffer, 16); memcpy(encrypted, (void*) buffer + 16, (unsigned int) result_size); memcpy(tag, (void*) buffer + 16 + result_size, 16); //@ assert chars(iv, 16, ?iv_cs); //@ assert chars(encrypted, result_size, ?e_cs); //@ assert chars(tag, 16, ?t_cs); //@ chars_join(buffer); //@ chars_join(buffer); //@ open [1/2]hide_chars(buffer, size, cs); //@ close [1/2]hide_chars(buffer, size, cs); //@ assert cs == append(iv_cs, append(e_cs, t_cs)); // Decrypt message { gcm_context gcm_context; //@ close gcm_context(&gcm_context); //@ open [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg); //@ close polarssl_key_id(creator, key_id); if (gcm_init(&gcm_context, POLARSSL_AES_CIPHER_ID, key, (unsigned int) KEY_BYTE_SIZE * 8) != 0) abort(); /*@ assert gcm_context_initialized(&gcm_context, some(pair(creator, key_id))); @*/ //@ close [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg); //@ polarssl_public_generated_chars_split(sc_auth_polarssl_pub, cs, 16); /*@ polarssl_public_generated_chars_split( sc_auth_polarssl_pub, append(e_cs, t_cs), result_size); @*/ //@ assert chars(encrypted, result_size, e_cs); if (gcm_auth_decrypt(&gcm_context, (unsigned int) result_size, iv, 16, NULL, 0, tag, 16, encrypted, decrypted) != 0) abort(); gcm_free(&gcm_context); //@ open gcm_context(&gcm_context); } //@ assert chars(decrypted, result_size, ?dec_cs); //@ chars_join(buffer); //@ open [1/2]hide_chars(buffer, size, cs); /*@ polarssl_cryptogram e_cg = polarssl_auth_encrypted( creator, key_id, t_cs, dec_cs, iv_cs); @*/ //@ assert e_cs == polarssl_chars_for_cryptogram(e_cg); //@ polarssl_cryptogram_constraints(e_cs, e_cg); /*@ polarssl_public_generated_chars_extract( sc_auth_polarssl_pub, e_cs, e_cg); @*/ //@ open [_]sc_auth_polarssl_pub(e_cg); /*@ if (!bad(creator)) { assert true == app_send_event(creator, dec_cs); } else { assert [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(dec_cs); } @*/ net_close(socket1); net_close(socket2); free(encrypted); *message = decrypted; return result_size; }
void sender(char *enc_key, char *hmac_key, char *msg, unsigned int msg_len) /*@ requires [_]public_invar(enc_then_hmac_pub) &*& principal(?sender, _) &*& [?f1]cryptogram(enc_key, KEY_SIZE, ?enc_key_ccs, ?enc_key_cg) &*& [?f2]cryptogram(hmac_key, KEY_SIZE, ?hmac_key_ccs, ?hmac_key_cg) &*& enc_key_cg == cg_symmetric_key(sender, ?enc_id) &*& hmac_key_cg == cg_symmetric_key(sender, ?hmac_id) &*& cg_info(hmac_key_cg) == enc_id &*& shared_with(sender, enc_id) == shared_with(sender, hmac_id) &*& [?f3]crypto_chars(secret, msg, msg_len, ?msg_ccs) &*& MAX_SIZE >= msg_len &*& msg_len >= MINIMAL_STRING_SIZE &*& bad(sender) || bad(shared_with(sender, enc_id)) ? [_]public_ccs(msg_ccs) : true == send(sender, shared_with(sender, enc_id), msg_ccs); @*/ /*@ ensures principal(sender, _) &*& [f1]cryptogram(enc_key, KEY_SIZE, enc_key_ccs, enc_key_cg) &*& [f2]cryptogram(hmac_key, KEY_SIZE, hmac_key_ccs, hmac_key_cg) &*& [f3]crypto_chars(secret, msg, msg_len, msg_ccs); @*/ { //@ open principal(sender, _); int socket; havege_state havege_state; char iv[16]; unsigned int iv_off = 0; char hmac[64]; aes_context aes_context; net_usleep(20000); if(net_connect(&socket, NULL, SERVER_PORT) != 0) abort(); if(net_set_block(socket) != 0) abort(); { int message_len = 16 + (int) msg_len + 64; char* message = malloc(message_len); if (message == 0) abort(); // IV stuff //@ close havege_state(&havege_state); havege_init(&havege_state); //@ close random_request(sender, 0, false); if (havege_random(&havege_state, iv, 16) != 0) abort(); //@ open cryptogram(iv, 16, ?iv_ccs, ?iv_cg); //@ close enc_then_hmac_pub(iv_cg); //@ leak enc_then_hmac_pub(iv_cg); memcpy(message, iv, 16); //@ close cryptogram(message, 16, iv_ccs, iv_cg); //@ public_cryptogram(message, iv_cg); //@ assert chars(message, 16, ?iv_cs); //@ public_chars(message, 16); havege_free(&havege_state); //@ open havege_state(&havege_state); // encrypt //@ close aes_context(&aes_context); if (aes_setkey_enc(&aes_context, enc_key, (unsigned int) (KEY_SIZE * 8)) != 0) abort(); if (aes_crypt_cfb128(&aes_context, AES_ENCRYPT, msg_len, &iv_off, iv, msg, message + 16) != 0) abort(); //@ open cryptogram(message + 16, msg_len, ?enc_ccs, ?enc_cg); //@ close cryptogram(message + 16, msg_len, enc_ccs, enc_cg); //@ close enc_then_hmac_pub(enc_cg); //@ leak enc_then_hmac_pub(enc_cg); //@ public_cryptogram(message + 16, enc_cg); //@ assert chars(message + 16, msg_len, ?enc_cs); //@ public_chars(message + 16, msg_len); //@ assert chars(message, 16 + msg_len, append(iv_cs, enc_cs)); //@ assert enc_cg == cg_encrypted(sender, enc_id, msg_ccs, iv_ccs); zeroize(iv, 16); aes_free(&aes_context); //@ open aes_context(&aes_context); // hmac //@ chars_to_crypto_chars(message, 16 + msg_len); //@ HASH_PUB_PAYLOAD(append(iv_cs, enc_cs)) sha512_hmac(hmac_key, KEY_SIZE, message, (unsigned int) (16 + (int) msg_len), message + 16 + (int) msg_len, 0); //@ assert cryptogram(message + 16 + msg_len, 64, ?hmac_ccs, ?hmac_cg); //@ cs_to_ccs_append(iv_cs, enc_cs); //@ assert hmac_cg == cg_hmac(sender, hmac_id, append(iv_ccs, enc_ccs)); /*@ if (!col && !enc_then_hmac_public_key(sender, enc_id, true)) close enc_then_hmac_pub_1(enc_id, msg_ccs, iv_ccs); @*/ /*@ if (col || enc_then_hmac_public_key(sender, enc_id, true)) { assert [_]public_ccs(iv_ccs); assert [_]public_ccs(enc_ccs); public_ccs_join(iv_ccs, enc_ccs); } @*/ //@ close enc_then_hmac_pub(hmac_cg); //@ leak enc_then_hmac_pub(hmac_cg); //@ public_cryptogram(message + 16 + msg_len, hmac_cg); //@ assert chars(message + 16 + msg_len, 64, ?hmac_cs); //@ append_assoc(iv_ccs, enc_ccs, hmac_ccs); //@ append_assoc(iv_cs, enc_cs, hmac_cs); //@ cs_to_ccs_crypto_chars(message, append(iv_cs, enc_cs)); /*@ assert chars(message, message_len, append(iv_cs, append(enc_cs, hmac_cs))); @*/ net_send(&socket, message, (unsigned int) message_len); free(message); } net_close(socket); //@ close principal(sender, _); }
int receiver(char *enc_key, char *hmac_key, char *msg) /*@ requires [_]public_invar(enc_then_hmac_pub) &*& [_]decryption_key_classifier(enc_then_hmac_public_key) &*& principal(?receiver, _) &*& [?f1]cryptogram(enc_key, KEY_SIZE, ?enc_key_ccs, ?enc_key_cg) &*& [?f2]cryptogram(hmac_key, KEY_SIZE, ?hmac_key_ccs, ?hmac_key_cg) &*& enc_key_cg == cg_symmetric_key(?sender, ?enc_id) &*& hmac_key_cg == cg_symmetric_key(sender, ?hmac_id) &*& cg_info(hmac_key_cg) == enc_id &*& receiver == shared_with(sender, enc_id) &*& receiver == shared_with(sender, hmac_id) &*& chars(msg, MAX_SIZE, _); @*/ /*@ ensures principal(receiver, _) &*& [f1]cryptogram(enc_key, KEY_SIZE, enc_key_ccs, enc_key_cg) &*& [f2]cryptogram(hmac_key, KEY_SIZE, hmac_key_ccs, hmac_key_cg) &*& chars(msg + result, MAX_SIZE - result, _) &*& crypto_chars(?kind, msg, result, ?msg_ccs) &*& col || bad(sender) || bad(receiver) || (kind == secret && send(sender, receiver, msg_ccs)); @*/ { //@ open principal(receiver, _); int socket1; int socket2; int size; int enc_size; char iv[16]; unsigned int iv_off = 0; char hmac[64]; aes_context aes_context; if(net_bind(&socket1, NULL, SERVER_PORT) != 0) abort(); if(net_accept(socket1, &socket2, NULL) != 0) abort(); if(net_set_block(socket2) != 0) abort(); { int max_size = 16 + MAX_SIZE + 64; char *buffer = malloc (max_size); if (buffer == 0) abort(); size = net_recv(&socket2, buffer, (unsigned int) max_size); if (size <= 16 + 64) abort(); enc_size = size - 16 - 64; if (enc_size < MINIMAL_STRING_SIZE) abort(); //@ chars_split(buffer, size); //@ assert chars(buffer, size, ?all_cs); //@ close hide_chars((void*) buffer + size, max_size - size, _); //Verify the hmac //@ chars_split(buffer, size - 64); //@ public_chars(buffer + size - 64, 64); //@ assert chars(buffer + size - 64, 64, ?hmac_cs); //@ assert chars(buffer, size - 64, ?pay_cs); //@ chars_to_crypto_chars(buffer, size - 64); //@ HASH_PUB_PAYLOAD(pay_cs) sha512_hmac(hmac_key, KEY_SIZE, buffer, (unsigned int) (size - 64), hmac, 0); //@ open cryptogram(hmac, 64, ?hmac_ccs, ?hmac_cg); //@ chars_to_crypto_chars((void*) buffer + size - 64, 64); //@ close memcmp_secret(hmac, 64, hmac_ccs, hmac_cg); if (memcmp((void*) buffer + size - 64, hmac, 64) != 0) abort(); /*@ if (!col) { public_ccs_cg(hmac_cg); public_crypto_chars(hmac, 64); } else { crypto_chars_to_chars(hmac, 64); } @*/ //@ assert all_cs == append(pay_cs, hmac_cs); // IV stuff //@ cs_to_ccs_crypto_chars(buffer, pay_cs); //@ chars_split(buffer, 16); //@ assert chars(buffer, 16, ?iv_cs); //@ chars_to_crypto_chars(buffer, 16); //@ assert crypto_chars(normal, buffer, 16, ?iv_ccs); memcpy(iv, buffer, 16); //@ cs_to_ccs_crypto_chars(iv, iv_cs); //@ interpret_nonce(iv, 16); //@ open cryptogram(iv, 16, iv_ccs, ?iv_cg); //Decrypt //@ assert chars(buffer + 16, enc_size, ?enc_cs); //@ interpret_encrypted(buffer + 16, enc_size); //@ open cryptogram(buffer + 16, enc_size, ?enc_ccs, ?enc_cg); //@ close cryptogram(buffer + 16, enc_size, enc_ccs, enc_cg); //@ assert enc_cg == cg_encrypted(?p2, ?c2, ?dec_ccs2, ?iv_ccs2); //@ close aes_context(&aes_context); if (aes_setkey_enc(&aes_context, enc_key, (unsigned int) (KEY_SIZE * 8)) != 0) abort(); //@ structure s = known_value(0, dec_ccs2); //@ close decryption_pre(true, false, receiver, s, enc_ccs); if (aes_crypt_cfb128(&aes_context, AES_DECRYPT, (unsigned int) enc_size, &iv_off, iv, buffer + 16, msg) != 0) abort(); //@ assert pay_cs == append(iv_cs, enc_cs); //@ cs_to_ccs_append(iv_cs, enc_cs); zeroize(iv, 16); aes_free(&aes_context); //@ open aes_context(&aes_context); //@ public_cg_ccs(enc_cg); //@ public_cryptogram(buffer + 16, enc_cg); /*@ open decryption_post(true, ?garbage, receiver, s, sender, enc_id, ?dec_ccs); @*/ /*@ if (!col) { open [_]enc_then_hmac_pub(hmac_cg); open [_]enc_then_hmac_pub(enc_cg); if (!enc_then_hmac_public_key(sender, enc_id, true)) { assert [_]enc_then_hmac_pub_1(?id, ?dec_ccs3, ?ent); cryptogram enc_cg3 = cg_encrypted(sender, id, dec_ccs3, ent); take_append(16, iv_ccs, ccs_for_cg(enc_cg)); take_append(16, ent, ccs_for_cg(enc_cg3)); assert ent == iv_ccs; drop_append(16, iv_ccs, ccs_for_cg(enc_cg)); drop_append(16, ent, ccs_for_cg(enc_cg3)); assert ccs_for_cg(enc_cg) == ccs_for_cg(enc_cg3); ccs_for_cg_inj(enc_cg, enc_cg3); assert dec_ccs2 == dec_ccs3; close exists(pair(nil, nil)); close has_structure(dec_ccs2, s); leak has_structure(dec_ccs2, s); } } else { crypto_chars_to_chars(msg, enc_size); chars_to_secret_crypto_chars(msg, enc_size); } @*/ //@ if (garbage) decryption_garbage(msg, enc_size, s); //@ open hide_chars((void*) buffer + size, max_size - size, _); //@ crypto_chars_to_chars(buffer, 16); //@ crypto_chars_to_chars(buffer + size - 64, 64); //@ chars_join(buffer); //@ chars_join(buffer); free(buffer); } net_close(socket2); net_close(socket1); return enc_size; //@ close principal(receiver, _); }
void attacker() /*@ requires [_]public_invar(?pub) &*& [_]decryption_key_classifier(?classifier) &*& public_invariant_constraints(pub, ?proof_pred) &*& proof_pred() &*& principal(?bad_one, _) &*& true == bad(bad_one) &*& is_public_key_classifier(_, pub, classifier, proof_pred); @*/ /*@ ensures public_invariant_constraints(pub, proof_pred) &*& proof_pred() &*& principal(bad_one, _) &*& is_public_key_classifier(_, pub, classifier, proof_pred); @*/ { bool havege_failure = false; int server_or_client; int port; int* socket; int socket1; int socket2; //@ open principal(bad_one, _); havege_state havege_state; //@ close havege_state(&havege_state); havege_init(&havege_state); //@ open public_invariant_constraints(pub, proof_pred); /*@ { lemma void principal_with_public_nonces(cryptogram nonce) requires is_bad_nonce_is_public(?proof, pub, proof_pred) &*& proof_pred() &*& nonce == cg_nonce(bad_one, _); ensures is_bad_nonce_is_public(proof, pub, proof_pred) &*& proof_pred() &*& [_]pub(nonce); { proof(nonce); } produce_lemma_function_pointer_chunk(principal_with_public_nonces) : principal_with_public_nonces (pub, attacker_nonce_pred(pub, proof_pred), bad_one)(nonce__) { open attacker_nonce_pred(pub, proof_pred)(); call(); close attacker_nonce_pred(pub, proof_pred)(); } {duplicate_lemma_function_pointer_chunk(principal_with_public_nonces);}; } @*/ //@ close_havege_util(pub, proof_pred, bad_one); r_int(&havege_state, &server_or_client); r_int(&havege_state, &port); //@ open_havege_util(pub, proof_pred, bad_one); bool network_failure = false; if (server_or_client % 2 == 0) { if(net_connect(&socket1, NULL, port) != 0) network_failure = true; else if(net_set_block(socket1) != 0) network_failure = true; socket = &socket1; } else { if(net_bind(&socket1, NULL, port) != 0) {network_failure = true;} else if(net_accept(socket1, &socket2, NULL) != 0) {net_close(socket1); network_failure = true;} else if(net_set_block(socket2) != 0) {net_close(socket1); network_failure = true;} socket = &socket2; } if (!network_failure) { //@ close attacker_invariant(pub, proof_pred, ?kc, &havege_state, socket, bad_one); int j = 0; while(j < POLARSSL_ATTACKER_ITERATIONS) /*@ invariant attacker_invariant(pub, proof_pred, kc, &havege_state, socket, bad_one); @*/ { attacker_core(&havege_state, socket); j++; } //@ open attacker_invariant(pub, proof_pred, kc, &havege_state, socket, bad_one); if (server_or_client % 2 == 0) net_close(socket1); else { net_close(socket1); net_close(socket2); } } //@ close public_invariant_constraints(pub, proof_pred); //@ close principal(bad_one, _); havege_free(&havege_state); //@ open havege_state(&havege_state); /*@ leak is_principal_with_public_nonces(_, pub, attacker_nonce_pred(pub, proof_pred), bad_one); @*/ }