cryptkeyres * key_decrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) { static cryptkeyres res; if (debugging) { fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, arg->remotename, arg->deskey.key.high, arg->deskey.key.low); } res.cryptkeyres_u.deskey = arg->deskey; res.status = pk_decrypt(uid, arg->remotename, NULL, &res.cryptkeyres_u.deskey); if (debugging) { if (res.status == KEY_SUCCESS) { fprintf(stderr, "%08x%08x\n", res.cryptkeyres_u.deskey.key.high, res.cryptkeyres_u.deskey.key.low); } else { fprintf(stderr, "%s\n", strstatus(res.status)); } fflush(stderr); } return (&res); }
result_t PKey::decrypt(Buffer_base *data, obj_ptr<Buffer_base> &retVal, exlib::AsyncEvent *ac) { if (switchToAsync(ac)) return CHECK_ERROR(CALL_E_NOSYNC); result_t hr; bool priv; hr = isPrivate(priv); if (hr < 0) return hr; if (!priv) return CHECK_ERROR(CALL_E_INVALID_CALL); int ret; std::string str; std::string output; size_t olen; data->toString(str); output.resize(POLARSSL_PREMASTER_SIZE * 2); ret = pk_decrypt(&m_key, (const unsigned char *)str.c_str(), str.length(), (unsigned char *)&output[0], &olen, output.length(), ctr_drbg_random, &g_ssl.ctr_drbg); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); output.resize(olen); retVal = new Buffer(output); return 0; }
int cPublicKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength) { size_t DecryptedLen = a_DecryptedMaxLength; int res = pk_decrypt(&m_Pk, a_EncryptedData, a_EncryptedLength, a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength, ctr_drbg_random, &m_Ctr_drbg ); if (res != 0) { return res; } return (int)DecryptedLen; }
int cCryptoKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength) { ASSERT(IsValid()); size_t DecryptedLen = a_DecryptedMaxLength; int res = pk_decrypt(&m_Pk, a_EncryptedData, a_EncryptedLength, a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength, ctr_drbg_random, m_CtrDrbg.GetInternal() ); if (res != 0) { return res; } return (int)DecryptedLen; }
static int get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) { int rc; gcry_mpi_t plain_dek = NULL; byte *frame = NULL; unsigned int n; size_t nframe; u16 csum, csum2; int card = 0; if (sk->is_protected && sk->protect.s2k.mode == 1002) { /* Note, that we only support RSA for now. */ #ifdef ENABLE_CARD_SUPPORT unsigned char *rbuf; size_t rbuflen; char *snbuf; unsigned char *indata = NULL; size_t indatalen; snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk); if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0])) BUG (); rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen); xfree (snbuf); xfree (indata); if (rc) goto leave; frame = rbuf; nframe = rbuflen; card = 1; #else rc = gpg_error (GPG_ERR_NOT_SUPPORTED); goto leave; #endif /*!ENABLE_CARD_SUPPORT*/ } else { rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey ); if( rc ) goto leave; if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek)) BUG(); gcry_mpi_release (plain_dek); plain_dek = NULL; } /* Now get the DEK (data encryption key) from the frame * * Old versions encode the DEK in in this format (msb is left): * * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2 * * Later versions encode the DEK like this: * * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) * * (mpi_get_buffer already removed the leading zero). * * RND are non-zero randow bytes. * A is the cipher algorithm * DEK is the encryption key (session key) with length k * CSUM */ if (DBG_CIPHER) log_printhex ("DEK frame:", frame, nframe ); n=0; if (!card) { if( n + 7 > nframe ) { rc = G10ERR_WRONG_SECKEY; goto leave; } if( frame[n] == 1 && frame[nframe-1] == 2 ) { log_info(_("old encoding of the DEK is not supported\n")); rc = G10ERR_CIPHER_ALGO; goto leave; } if( frame[n] != 2 ) /* somethink is wrong */ { rc = G10ERR_WRONG_SECKEY; goto leave; } for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */ ; n++; /* and the zero byte */ } if( n + 4 > nframe ) { rc = G10ERR_WRONG_SECKEY; goto leave; } dek->keylen = nframe - (n+1) - 2; dek->algo = frame[n++]; if( dek->algo == CIPHER_ALGO_IDEA ) write_status(STATUS_RSA_OR_IDEA); rc = openpgp_cipher_test_algo (dek->algo); if( rc ) { if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) { log_info(_("cipher algorithm %d%s is unknown or disabled\n"), dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":""); if(dek->algo==CIPHER_ALGO_IDEA) idea_cipher_warn (0); } dek->algo = 0; goto leave; } if ( dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo) ) { rc = GPG_ERR_WRONG_SECKEY; goto leave; } /* copy the key to DEK and compare the checksum */ csum = frame[nframe-2] << 8; csum |= frame[nframe-1]; memcpy( dek->key, frame+n, dek->keylen ); for( csum2=0, n=0; n < dek->keylen; n++ ) csum2 += dek->key[n]; if( csum != csum2 ) { rc = G10ERR_WRONG_SECKEY; goto leave; } if( DBG_CIPHER ) log_printhex ("DEK is:", dek->key, dek->keylen ); /* check that the algo is in the preferences and whether it has expired */ { PKT_public_key *pk = NULL; KBNODE pkb = get_pubkeyblock (keyid); if( !pkb ) { rc = -1; log_error("oops: public key not found for preference check\n"); } else if(pkb->pkt->pkt.public_key->selfsigversion > 3 && dek->algo != CIPHER_ALGO_3DES && !opt.quiet && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo )) log_info (_("WARNING: cipher algorithm %s not found in recipient" " preferences\n"), openpgp_cipher_algo_name (dek->algo)); if (!rc) { KBNODE k; for (k=pkb; k; k = k->next) { if (k->pkt->pkttype == PKT_PUBLIC_KEY || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){ u32 aki[2]; keyid_from_pk(k->pkt->pkt.public_key, aki); if (aki[0]==keyid[0] && aki[1]==keyid[1]) { pk = k->pkt->pkt.public_key; break; } } } if (!pk) BUG (); if ( pk->expiredate && pk->expiredate <= make_timestamp() ) { log_info(_("NOTE: secret key %s expired at %s\n"), keystr(keyid), asctimestamp( pk->expiredate) ); } } if ( pk && pk->is_revoked ) { log_info( _("NOTE: key has been revoked") ); log_printf ("\n"); show_revocation_reason( pk, 1 ); } release_kbnode (pkb); rc = 0; } leave: gcry_mpi_release (plain_dek); xfree (frame); return rc; }
struct item *asymmetric_decryption(struct item *key, struct item *item, char tag) /*@ requires [?f]world(?pub, ?key_clsfy) &*& true == valid_tag(tag) &*& principal(?principal1, ?count1) &*& item(item, ?enc, pub) &*& item(key, ?k, pub) &*& enc == asymmetric_encrypted_item(?principal2, ?count2, ?pay, ?ent) &*& k == private_key_item(?principal3, ?count3); @*/ /*@ ensures [f]world(pub, key_clsfy) &*& principal(principal1, count1 + 1) &*& item(item, enc, pub) &*& item(key, k, pub) &*& item(result, ?dec, pub) &*& tag_for_item(dec) == tag &*& col ? [_]pub(dec) : principal2 != principal3 || count2 != count3 ? true == key_clsfy(principal3, count3, false) &*& [_]pub(dec) : switch(pay) { case some(dec2): return dec == dec2; case none: return false; }; @*/ { struct item* result = 0; debug_print("DECRYPTING:\n"); print_item(item); check_is_asymmetric_encrypted(item); { pk_context context; unsigned int olen; char output[MAX_PACKAGE_SIZE]; // Key //@ close pk_context(&context); //@ open [f]world(pub, key_clsfy); pk_init(&context); //@ close [f]world(pub, key_clsfy); set_private_key(&context, key); //@ open [f]world(pub, key_clsfy); /*@ assert pk_context_with_key(&context, pk_private, ?principal, ?count, RSA_BIT_KEY_SIZE); @*/ // Decryption //@ open item(item, enc, pub); /*@ assert enc == asymmetric_encrypted_item(principal2, count2, pay, ent); @*/ //@ open [_]item_constraints(enc, ?enc_cs, pub); //@ assert [_]ic_parts(enc)(?enc_tag, ?enc_cont); //@ assert enc_cs == append(enc_tag, enc_cont); //@ open [_]ic_cg(enc)(_, ?enc_cg); //@ assert enc_cg == cg_asym_encrypted(principal2, count2, ?cs_pay, ent); if (item->size - TAG_LENGTH > RSA_KEY_SIZE || item->size - TAG_LENGTH < MINIMAL_STRING_SIZE) abort_crypto_lib("Asymmetric decryption failed: incorrect sizes"); //@ assert item->content |-> ?i_cont &*& item->size |-> ?i_size; //@ crypto_chars_split(i_cont, TAG_LENGTH); //@ drop_append(TAG_LENGTH, enc_tag, enc_cont); //@ assert crypto_chars(secret, i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont); //@ if (col) enc_cg = chars_for_cg_sur(enc_cont, tag_asym_encrypted); //@ if (col) public_crypto_chars_extract(i_cont + TAG_LENGTH, enc_cg); //@ close cryptogram(i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont, enc_cg); void *random_state = nonces_expose_state(); //@ close random_state_predicate(havege_state_initialized); /*@ produce_function_pointer_chunk random_function( asym_enc_havege_random_stub) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ open principal(principal1, count1); //@ structure s = known_value(0, full_tag(tag)); //@ close decryption_pre(false, false, principal1, s, enc_cont); if(pk_decrypt(&context, item->content + TAG_LENGTH, (unsigned int) item->size - TAG_LENGTH, output, &olen, MAX_PACKAGE_SIZE, asym_enc_havege_random_stub, random_state) != 0) abort_crypto_lib("Decryption failed"); /*@ open decryption_post(false, ?garbage, principal1, s, ?p_key, ?c_key, ?cs_out); @*/ //@ assert u_integer(&olen, ?size_out); //@ pk_release_context_with_key(&context); //@ open cryptogram(i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont, enc_cg); pk_free(&context); //@ open pk_context(&context); nonces_hide_state(random_state); //@ assert chars((void*)output + size_out, MAX_PACKAGE_SIZE - size_out, ?cs_rest); result = malloc(sizeof(struct item)); if (result == 0) {abort_crypto_lib("Malloc failed");} result->size = (int) olen; if ((int) olen <= MINIMAL_STRING_SIZE) abort_crypto_lib("Decryption: Incorrect size"); result->content = malloc(result->size); if (result->content == 0) {abort_crypto_lib("Malloc failed");} //@ close [f]world(pub, key_clsfy); //@ assert u_integer(&olen, ?olen_val); //@ assert crypto_chars(_, output, olen_val, cs_out); //@ crypto_chars_split(output, TAG_LENGTH); //@ assert crypto_chars(_, output, TAG_LENGTH, ?cs_tag); //@ assert crypto_chars(_, (void*) output + TAG_LENGTH, olen_val - TAG_LENGTH, ?cs_i); /*@ if (col) { crypto_chars_to_chars(output, TAG_LENGTH); chars_to_crypto_chars(output, TAG_LENGTH); } else if (!garbage) { switch(pay) { case some(pay1): open [_]item_constraints(pay1, cs_out, pub); case none: open [_]ill_formed_item_chars(enc)(cs_out); public_generated_split(polarssl_pub(pub), cs_out, TAG_LENGTH); } public_crypto_chars(output, TAG_LENGTH); } @*/ //@ close check_tag2_ghost_args(false, garbage, p_key, c_key, cs_i); check_tag2(output, tag); //@ if (!garbage) chars_to_secret_crypto_chars(output, TAG_LENGTH); //@ crypto_chars_join(output); memcpy(result->content, output, olen); //@ assert result->content |-> ?cont; //@ assert crypto_chars(?kind, cont, olen_val, cs_out); zeroize(output, (int) olen); //@ close item(item, enc, pub); //@ assert enc == asymmetric_encrypted_item(principal2, count2, pay, ent); //@ assert col || enc_cg == cg_asym_encrypted(principal2, count2, cs_pay, ent); /*@ if (col) { crypto_chars_to_chars(cont, olen_val); public_chars(cont, olen_val); chars_to_crypto_chars(cont, olen_val); } else if (garbage) { assert true == key_clsfy(principal3, count3, false); public_chars(cont, olen_val); chars_to_crypto_chars(cont, olen_val); } else { assert principal2 == principal3; assert count2 == count3; assert cs_out == cs_pay; switch(pay) { case some(pay1): assert [_]item_constraints(pay1, cs_out, pub); case none: open [_]ill_formed_item_chars(enc)(cs_out); assert [_]public_generated(polarssl_pub(pub))(cs_out); public_crypto_chars(cont, olen_val); chars_to_crypto_chars(cont, olen_val); } } @*/ parse_item(result->content, (int) olen); /*@ if (col || garbage) { retreive_proof_obligations(); deserialize_item(cs_out, pub); leak proof_obligations(pub); chars_to_secret_crypto_chars(cont, olen_val); } @*/ //@ open [_]item_constraints(?dec, cs_out, pub); //@ assert [_]ic_parts(dec)(?dec_tag, ?dec_cont); //@ take_append(TAG_LENGTH, dec_tag, dec_cont); //@ drop_append(TAG_LENGTH, dec_tag, dec_cont); //@ assert dec_tag == full_tag(tag); //@ assert tag_for_item(dec) == tag; //@ close item(result, dec, pub); } return result; }
void receiver_msg3(int* socket, havege_state* havege_state, pk_context* r_context, int sender, int receiver, char* s_nonce, char* r_nonce) /*@ requires GENERAL_PRE(receiver) &*& pk_context_with_key(r_context, pk_private, receiver, ?r_id, 8 * KEY_SIZE) &*& RECEIVER_INTER &*& cryptogram(r_nonce, NONCE_SIZE, ?r_nonce_ccs, ?r_nonce_cg) &*& r_nonce_cg == cg_nonce(receiver, _) &*& cg_info(r_nonce_cg) == int_pair(2, int_pair(sender, int_pair(p_inst, int_pair(p_orig, c_orig)))); @*/ /*@ ensures GENERAL_POST(receiver) &*& pk_context_with_key(r_context, pk_private, receiver, r_id, 8 * KEY_SIZE) &*& ( col || bad(p_inst) || bad(receiver) ? crypto_chars(normal, s_nonce, NONCE_SIZE, s_nonce_ccs) : cryptogram(s_nonce, NONCE_SIZE, s_nonce_ccs, s_nonce_cg) ) &*& cryptogram(r_nonce, NONCE_SIZE, r_nonce_ccs, r_nonce_cg) &*& col || bad(sender) || bad(receiver) || (receiver == p_orig && r_id == c_orig && sender == p_inst); @*/ { //@ open principal(receiver, _); unsigned int size; char message[MSG3_SIZE]; char encrypted[KEY_SIZE]; //@ open receiver_inter(p_orig, c_orig, p_inst, s_nonce_ccs, s_nonce_cg); // Receive the message net_recv(socket, encrypted, KEY_SIZE); //@ assert chars(encrypted, KEY_SIZE, ?enc_cs); //@ interpret_asym_encrypted(encrypted, KEY_SIZE); //@ assert cryptogram(encrypted, KEY_SIZE, ?enc_ccs, ?enc_cg); //@ assert enc_cg == cg_asym_encrypted(?p, ?c, ?pay, ?ent); // Decrypt the message /*@ produce_function_pointer_chunk random_function(random_stub_nsl) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ close random_state_predicate(havege_state_initialized); //@ structure st = known_value(0, r_nonce_ccs); //@ close decryption_pre(false, false, receiver, st, enc_ccs); if (pk_decrypt(r_context, encrypted, KEY_SIZE, message, &size, MSG3_SIZE, random_stub_nsl, havege_state) != 0) abort(); if (size != MSG3_SIZE) abort(); //@ assert u_integer(&size, MSG3_SIZE); //@ assert crypto_chars(?kind, message, NONCE_SIZE, ?dec_ccs); /*@ open decryption_post(false, ?garbage, receiver, st, receiver, r_id, dec_ccs); @*/ // Interpret the message //@ open cryptogram(r_nonce, NONCE_SIZE, r_nonce_ccs, r_nonce_cg); //@ open [_]nsl_pub(enc_cg); //@ assert [_]nsl_pub_msg_sender(?sender2); /*@ if (col || garbage) { crypto_chars_to_chars(message, NONCE_SIZE); chars_to_crypto_chars(message, NONCE_SIZE); } else { if (bad(receiver) || bad(sender2)) { public_crypto_chars(message, NONCE_SIZE); chars_to_crypto_chars(message, NONCE_SIZE); } else { assert [_]nsl_pub_msg3(sender2, receiver, ?r_nonce_cg2); close memcmp_secret(message, NONCE_SIZE, dec_ccs, r_nonce_cg2); } } @*/ //@ close memcmp_secret(r_nonce, NONCE_SIZE, r_nonce_ccs, r_nonce_cg); if (memcmp((void*) message, r_nonce, NONCE_SIZE) != 0) abort(); //@ assert dec_ccs == r_nonce_ccs; /*@ if (garbage) { close exists(pair(nil, nil)); close has_structure(r_nonce_ccs, st); leak has_structure(r_nonce_ccs, st); decryption_garbage(message, NONCE_SIZE, st); crypto_chars_to_chars(message, NONCE_SIZE); chars_to_secret_crypto_chars(message, NONCE_SIZE); } else if (!col && !bad(sender) && !bad(receiver)) { if (bad(receiver) || bad(sender2)) { public_crypto_chars(r_nonce, NONCE_SIZE); public_ccs_cg(r_nonce_cg); open [_]nsl_pub(r_nonce_cg); assert false; } else if (bad(p_inst)) { assert [_]nsl_pub_msg3(sender2, receiver, ?r_nonce_cg2); int p1_1 = int_pair(p_orig, c_orig); int p1_2 = int_pair(p_inst, p1_1); int p1_3 = int_pair(sender, p1_2); int p2_1 = int_pair(receiver, r_id); int p2_2 = int_pair(sender2, p2_1); int p2_3 = int_pair(sender2, p2_2); assert cg_info(r_nonce_cg) == int_pair(2, p1_3); assert cg_info(r_nonce_cg2) == int_pair(2, p2_3); ccs_for_cg_inj(r_nonce_cg, r_nonce_cg2); int_right_int_pair(2, p1_3); int_right_int_pair(2, p2_3); int_left_int_pair(sender, p1_2); int_left_int_pair(sender2, p2_2); int_right_int_pair(sender, p1_2); int_right_int_pair(sender2, p2_2); int_left_int_pair(p_inst, p1_1); assert false; } } @*/ zeroize(message, MSG3_SIZE); //@ close cryptogram(r_nonce, NONCE_SIZE, r_nonce_ccs, r_nonce_cg); //@ public_cryptogram(encrypted, enc_cg); //@ close principal(receiver, _); }
void receiver_msg1(int* socket, havege_state* havege_state, pk_context* r_context, int sender, int receiver, char* s_nonce) /*@ requires GENERAL_PRE(receiver) &*& pk_context_with_key(r_context, pk_private, receiver, ?r_id, 8 * KEY_SIZE) &*& chars(s_nonce, NONCE_SIZE, _); @*/ /*@ ensures GENERAL_POST(receiver) &*& pk_context_with_key(r_context, pk_private, receiver, r_id, 8 * KEY_SIZE) &*& RECEIVER_INTER; @*/ { //@ open principal(receiver, _); unsigned int size; char message[MSG1_SIZE]; char encrypted[KEY_SIZE]; // Receive the message net_recv(socket, encrypted, KEY_SIZE); //@ assert chars(encrypted, KEY_SIZE, ?enc_cs); //@ interpret_asym_encrypted(encrypted, KEY_SIZE); //@ assert cryptogram(encrypted, KEY_SIZE, ?enc_ccs, ?enc_cg); //@ assert enc_cg == cg_asym_encrypted(?p, ?c, ?pay, ?ent); // Decrypt the message /*@ produce_function_pointer_chunk random_function(random_stub_nsl) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ close random_state_predicate(havege_state_initialized); //@ structure st = known_value(0, cs_to_ccs(identifier(sender))); //@ close decryption_pre(false, false, receiver, st, enc_ccs); if (pk_decrypt(r_context, encrypted, KEY_SIZE, message, &size, MSG1_SIZE, random_stub_nsl, havege_state) != 0) abort(); if (size != MSG1_SIZE) abort(); //@ assert u_integer(&size, MSG1_SIZE); //@ assert crypto_chars(?kind, message, MSG1_SIZE, ?dec_ccs); /*@ open decryption_post(false, ?garbage, receiver, st, receiver, r_id, dec_ccs); @*/ //@ crypto_chars_split(message, ID_SIZE); //@ assert crypto_chars(kind, message, ID_SIZE, ?id_ccs); /*@ assert crypto_chars(kind, (void*) message + ID_SIZE, NONCE_SIZE, ?s_nonce_ccs); @*/ //@ assert dec_ccs == append(id_ccs, s_nonce_ccs); //@ open [_]nsl_pub(enc_cg); //@ assert [_]nsl_pub_msg_sender(?p_instigator2); /*@ if (col || garbage) { crypto_chars_to_chars(message, ID_SIZE); } else { if (bad(receiver) || bad(p_instigator2)) { assert [_]public_ccs(dec_ccs); public_ccs_split(dec_ccs, ID_SIZE); } else { assert [_]nsl_pub_msg1(_, _, ?s_nonce_cg); take_append(ID_SIZE, cs_to_ccs(identifier(p_instigator2)), ccs_for_cg(s_nonce_cg)); drop_append(ID_SIZE, cs_to_ccs(identifier(p_instigator2)), ccs_for_cg(s_nonce_cg)); } public_crypto_chars(message, ID_SIZE); } @*/ //@ chars_to_crypto_chars(message, ID_SIZE); /*@ close check_identifier_ghost_args(false, garbage, receiver, r_id, s_nonce_ccs); @*/ check_identifier(message, sender); //@ assert id_ccs == cs_to_ccs(identifier(sender)); memcpy(s_nonce, (void*) message + ID_SIZE, NONCE_SIZE); // Interpret message //@ cryptogram s_nonce_cg; //@ int p_inst; /*@ if (!col && !garbage) { p_inst = p_instigator2; if (bad(p_inst) || bad(receiver)) { public_crypto_chars(s_nonce, NONCE_SIZE); chars_to_crypto_chars(s_nonce, NONCE_SIZE); crypto_chars_to_chars(message, ID_SIZE); chars_to_crypto_chars(message, ID_SIZE); public_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); chars_to_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); } else { assert [_]nsl_pub_msg1(p_inst, receiver, ?s_nonce_cg2); s_nonce_cg = s_nonce_cg2; assert s_nonce_cg == cg_nonce(p_inst, _); s_nonce_ccs = ccs_for_cg(s_nonce_cg); assert dec_ccs == append(cs_to_ccs(identifier(p_inst)), s_nonce_ccs); take_append(ID_SIZE, cs_to_ccs(identifier(p_inst)), s_nonce_ccs); drop_append(ID_SIZE, cs_to_ccs(identifier(p_inst)), s_nonce_ccs); cs_to_ccs_inj(identifier(p_inst), identifier(sender)); assert identifier(p_inst) == identifier(sender); equal_identifiers(p_inst, sender); close cryptogram(s_nonce, NONCE_SIZE, s_nonce_ccs, s_nonce_cg); } } else { crypto_chars_to_chars(s_nonce, NONCE_SIZE); chars_to_crypto_chars(s_nonce, NONCE_SIZE); } @*/ //@ close receiver_inter(p, c, p_inst, s_nonce_ccs, s_nonce_cg); //@ crypto_chars_to_chars(message, ID_SIZE); zeroize((void*) message + ID_SIZE, NONCE_SIZE); //@ public_cryptogram(encrypted, enc_cg); //@ close principal(receiver, _); }
void sender_msg2(int* socket, havege_state* havege_state, pk_context* s_context, int sender, int recvr, char* s_nonce, char* r_nonce) /*@ requires GENERAL_PRE(sender) &*& pk_context_with_key(s_context, pk_private, sender, ?s_id, 8 * KEY_SIZE) &*& pk_context_with_key(?r_context, pk_public, recvr, ?r_id, 8 * KEY_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(recvr, r_id)) &*& chars(r_nonce, NONCE_SIZE, _); @*/ /*@ ensures GENERAL_POST(sender) &*& pk_context_with_key(s_context, pk_private, sender, s_id, 8 * KEY_SIZE) &*& pk_context_with_key(r_context, pk_public, recvr, r_id, 8 * KEY_SIZE) &*& cryptogram(s_nonce, NONCE_SIZE, s_nonce_ccs, s_nonce_cg) &*& SENDER_INTER; @*/ { //@ open principal(sender, _); unsigned int size; char message[MSG2_SIZE]; char encrypted[KEY_SIZE]; // Receive the message net_recv(socket, encrypted, KEY_SIZE); //@ assert chars(encrypted, KEY_SIZE, ?enc_cs); //@ interpret_asym_encrypted(encrypted, KEY_SIZE); //@ assert cryptogram(encrypted, KEY_SIZE, ?enc_ccs, ?enc_cg); // Decrypt the message /*@ produce_function_pointer_chunk random_function(random_stub_nsl) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ close random_state_predicate(havege_state_initialized); //@ structure st = known_value(0, cs_to_ccs(identifier(recvr))); //@ close decryption_pre(false, false, sender, st, enc_ccs); if (pk_decrypt(s_context, encrypted, KEY_SIZE, message, &size, MSG2_SIZE, random_stub_nsl, havege_state) != 0) abort(); if (size != MSG2_SIZE) abort(); //@ public_cryptogram(encrypted, enc_cg); //@ assert enc_cg == cg_asym_encrypted(?p, ?c, ?pay, ?ent); //@ assert u_integer(&size, MSG2_SIZE); /*@ open decryption_post(false, ?garbage, sender, st, sender, s_id, ?dec_ccs); @*/ //@ assert crypto_chars(?kind, message, MSG2_SIZE, dec_ccs); //@ crypto_chars_split(message, ID_SIZE); //@ crypto_chars_split((void*) message + ID_SIZE, NONCE_SIZE); //@ assert crypto_chars(kind, message, ID_SIZE, ?id_ccs); //@ assert crypto_chars(kind, (void*) message + ID_SIZE, NONCE_SIZE, ?s_ccs); /*@ assert crypto_chars(kind, (void*) message + ID_SIZE + NONCE_SIZE, NONCE_SIZE, ?r_ccs); @*/ //@ append_assoc(id_ccs, s_ccs, r_ccs); //@ take_append(ID_SIZE, id_ccs, append(s_ccs, r_ccs)); //@ drop_append(ID_SIZE, id_ccs, append(s_ccs, r_ccs)); //@ take_append(NONCE_SIZE, s_ccs, r_ccs); //@ drop_append(NONCE_SIZE, s_ccs, r_ccs); // Interpret the message //@ open [_]nsl_pub(enc_cg); //@ assert [_]nsl_pub_msg_sender(?recvr2); /*@ if (col || garbage) { crypto_chars_to_chars(message, ID_SIZE); crypto_chars_to_chars((void*) message + ID_SIZE, NONCE_SIZE); chars_to_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); crypto_chars_to_chars((void*) message + ID_SIZE + NONCE_SIZE, NONCE_SIZE); chars_to_crypto_chars((void*) message + ID_SIZE + NONCE_SIZE, NONCE_SIZE); } else { if (bad(sender) || bad(recvr2)) { assert [_]public_ccs(dec_ccs); public_ccs_split(dec_ccs, ID_SIZE); public_ccs_split(append(s_ccs, r_ccs), NONCE_SIZE); public_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); chars_to_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); } else { assert [_]nsl_pub_msg2(sender, recvr2, ?s_nonce_cg2, ?s_nonce_ccs2, ?r_nonce_cg, _, _, _, ?pub_ns); take_append(ID_SIZE, cs_to_ccs(identifier(recvr2)), append(s_nonce_ccs2, ccs_for_cg(r_nonce_cg))); drop_append(ID_SIZE, cs_to_ccs(identifier(recvr2)), append(s_nonce_ccs2, ccs_for_cg(r_nonce_cg))); take_append(NONCE_SIZE, s_nonce_ccs2, ccs_for_cg(r_nonce_cg)); drop_append(NONCE_SIZE, s_nonce_ccs2, ccs_for_cg(r_nonce_cg)); if (pub_ns) { public_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); chars_to_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); } else { close memcmp_secret((void*) message + ID_SIZE, NONCE_SIZE, ccs_for_cg(s_nonce_cg2), s_nonce_cg2); } } public_crypto_chars(message, ID_SIZE); } @*/ //@ chars_to_crypto_chars(message, ID_SIZE); /*@ close check_identifier_ghost_args(false, garbage, sender, s_id, append(s_ccs, r_ccs)); @*/ check_identifier(message, recvr); //@ open cryptogram(s_nonce, NONCE_SIZE, s_nonce_ccs, s_nonce_cg); //@ close memcmp_secret(s_nonce, NONCE_SIZE, s_nonce_ccs, s_nonce_cg); if (memcmp((void*) message + ID_SIZE, s_nonce, NONCE_SIZE) != 0) abort(); memcpy(r_nonce, (void*) message + ID_SIZE + NONCE_SIZE, NONCE_SIZE); //@ assert id_ccs == cs_to_ccs(identifier(recvr)); //@ assert s_ccs == s_nonce_ccs; //@ cryptogram r_nonce_cg = ccs_for_cg_sur(r_ccs, tag_nonce); //@ close sender_inter(r_ccs, r_nonce_cg); /*@ if (!col && !garbage) { if (bad(sender) || bad(recvr2)) { assert [_]public_ccs(dec_ccs); public_ccs_split(dec_ccs, ID_SIZE); public_ccs_split(append(s_nonce_ccs, r_ccs), NONCE_SIZE); public_crypto_chars(r_nonce, NONCE_SIZE); chars_to_crypto_chars(r_nonce, NONCE_SIZE); public_ccs_cg(s_nonce_cg); open [_]nsl_pub(s_nonce_cg); crypto_chars_to_chars((void*) message + ID_SIZE, NONCE_SIZE); chars_to_secret_crypto_chars((void*) message + ID_SIZE, NONCE_SIZE); } else { assert dec_ccs == pay; assert sender == p; assert s_id == c; assert [_]nsl_pub_msg2(sender, recvr2, ?s_nonce_cg2, ?s_nonce_ccs2, ?r_nonce_cg2, ?p_inst, ?p2, ?c2, ?pub_ns); cs_to_ccs_inj(identifier(recvr2), identifier(recvr)); assert identifier(recvr) == identifier(recvr2); equal_identifiers(recvr, recvr2); if (pub_ns) { public_ccs_cg(s_nonce_cg); open [_]nsl_pub(s_nonce_cg); assert false; } ccs_for_cg_inj(r_nonce_cg2, r_nonce_cg); close cryptogram(r_nonce, NONCE_SIZE, r_ccs, r_nonce_cg2); ccs_for_cg_inj(s_nonce_cg, s_nonce_cg2); assert c2 == r_id; } } @*/ //@ close cryptogram(s_nonce, NONCE_SIZE, s_nonce_ccs, s_nonce_cg); //@ crypto_chars_join((void*) message + ID_SIZE); zeroize((void*) message + ID_SIZE, 2 * NONCE_SIZE); //@ crypto_chars_to_chars(message, ID_SIZE); //@ chars_join(message); //@ close principal(sender, _); }
int mix2_decrypt(BUFFER *m) /* 0: ok * -1: error * -2: old message */ { int err = 0; int i,rsalen,rsalen_as_byte; BUFFER *privkey; BUFFER *keyid; BUFFER *dec, *deskey; BUFFER *packetid, *mid, *digest, *addr, *temp, *iv, *ivvec; int type, packet = 0, numpackets = 0, timestamp = 0; BUFFER *body; BUFFER *header, *out; BUFFER *otherdigest, *bodydigest, *antitag, *extract; BUFFER *ttedigest, *hkey, *aes_pre_key, *aes_header_key, *aes_body_key, *aes_tte_key, *aes_iv; BUFFER *trail; privkey = buf_new(); keyid = buf_new(); dec = buf_new(); deskey = buf_new(); packetid = buf_new(); mid = buf_new(); digest = buf_new(); addr = buf_new(); temp = buf_new(); iv = buf_new(); ivvec = buf_new(); body = buf_new(); header = buf_new(); out = buf_new(); otherdigest = buf_new(); bodydigest = buf_new(); antitag = buf_new(); extract = buf_new(); ttedigest = buf_new(); hkey = buf_new(); aes_pre_key = buf_new(); aes_header_key = buf_new(); aes_body_key = buf_new(); aes_tte_key = buf_new(); aes_iv = buf_new(); trail=buf_new(); aes_pre_key->sensitive=1; aes_body_key->sensitive=1; aes_tte_key->sensitive=1; dec->sensitive=1; deskey->sensitive=1; extract->sensitive=1; hkey->sensitive=1; privkey->sensitive=1; buf_get(m, keyid, 16); err = db_getseckey(keyid->data, privkey); if (err == -1) { errlog(WARNING, "rem2.c mix2_decrypt not found keyid %s\n", showdata(keyid,0)); goto end; } rsalen_as_byte=buf_getc(m); switch(rsalen_as_byte) { case 128: /* legacy 1024-bit */ rsalen_as_byte=1; rsalen=128; break; case 2: rsalen_as_byte=2; rsalen=256; break; case 3: rsalen_as_byte=3; rsalen=384; break; case 4: rsalen_as_byte=4; rsalen=512; break; default: err = -1; errlog(NOTICE, "problem with RSA key size encoded as %d\n", rsalen_as_byte); goto end; break; } assert(128==rsalen || 256==rsalen || 384==rsalen || 512==rsalen); buf_get(m, extract, rsalen); /* 3DES key and maybe more */ err = pk_decrypt(extract, privkey); if (err == -1) { err = -1; errlog(NOTICE, "Cannot decrypt message.\n"); goto end; } buf_append(body, m->data + 20 * 512, 10240); buf_get(m, iv, 8); buf_get(m, dec, 328); if (128==rsalen) { if (extract->length != 24) { err = -1; errlog(NOTICE, "Cannot decrypt message - RSA 1024 data has wrong length %d not 24.\n", extract->length); /* If this length is greater someone may have wrongly sent digests under 1k RSA. */ goto end; } buf_cat(deskey, extract); } else { if (extract->length != 216) { err = -1; errlog(NOTICE, "Cannot decrypt message - RSA (large key) data has wrong length %d.\n", extract->length); /* supposed to be: * 3DES * hmac key * hmac-sha256(18*512 headers) * hmac-sha256(body) * hmac-sha256(328-block) * aes_pre_key */ goto end; } /* antitagging measure */ buf_get(extract, deskey, 24); buf_get(extract, hkey, 64); buf_get(extract, otherdigest, 32); buf_get(extract, bodydigest, 32); buf_get(extract, ttedigest, 32); buf_get(extract, aes_pre_key, 32); buf_reset(temp); hmac_sha256(body, hkey, temp); if (!buf_eq(bodydigest, temp)) { errlog(NOTICE, "Antitagging test - wrong digest on body.\n"); err = -1; goto end; } buf_reset(temp); hmac_sha256(dec, hkey, temp); if (!buf_eq(ttedigest, temp)) { errlog(NOTICE, "Antitagging test - wrong digest on 328-block.\n"); err = -1; goto end; } /* There is one more test applicable if packet type is 0. */ derive_aes_keys(aes_pre_key, hkey, aes_header_key, aes_body_key, aes_tte_key, aes_iv); buf_aescrypt(dec, aes_tte_key, aes_iv, DECRYPT); } buf_crypt(dec, deskey, iv, DECRYPT); buf_get(dec, packetid, 16); buf_get(dec, deskey, 24); type = buf_getc(dec); switch (type) { case 0: if (rsalen>=256) { buf_append(antitag, m->data + 2*512, 2*512); buf_reset(temp); hmac_sha256(antitag, hkey, temp); if (!buf_eq(otherdigest, temp)) { errlog(NOTICE, "Antitagging test - wrong digest on later header\n"); err = -1; goto end; } } buf_get(dec, ivvec, 152); buf_get(dec, addr, 80); break; case 1: buf_get(dec, mid, 16); buf_get(dec, iv, 8); break; case 2: packet = buf_getc(dec); numpackets = buf_getc(dec); buf_get(dec, mid, 16); buf_get(dec, iv, 8); break; default: errlog(WARNING, "Unknown message type.\n"); err = -1; goto end; } if (dec->data[dec->ptr] == '0' && dec->data[dec->ptr + 1] == '0' && dec->data[dec->ptr + 2] == '0' && dec->data[dec->ptr + 3] == '0' && dec->data[dec->ptr + 4] == '\0') { dec->ptr += 5; timestamp = buf_geti_lo(dec); } else { errlog(LOG, "Ignoring message without timestamp.\n"); err = -1; goto end; } buf_get(dec, digest, 16); /* digest of this block, but not so far as to include the digest */ dec->length = dec->ptr - 16; /* ignore digest */ dec->ptr = dec->length; /* If using 1024-bit RSA this is the only integrity protection. (It is still present but less important with larger key sizes.) if (!isdigest_md5(dec, digest)) { errlog(NOTICE, "Message digest does not match.\n"); err = -1; goto end; } /* Statistics are gathered in the isnewid() function. */ switch (isnewid(packetid, rsalen_as_byte, timestamp * SECONDSPERDAY)) { case 0: err = -2; /* redundant message */ goto end; case -1: err = -1; /* future timestamp */ goto end; } if (rsalen == 128) { /* skip either 1 or 2 blocks of 512 bytes */ buf_append(trail, m->data + 512, 19*512); } else { /* and AES */ buf_aescrypt(body, aes_body_key, aes_iv, DECRYPT); buf_append(trail, m->data + 2*512, 19*512); buf_aescrypt(trail, aes_header_key, aes_iv, DECRYPT); } switch (type) { case 0: buf_chop(addr); buf_cat(out, addr); buf_nl(out); for (i = 0; i < 19; i++) { buf_reset(header); buf_append(header, trail->data + i * 512, 512); buf_reset(iv); buf_append(iv, ivvec->data + i * 8, 8); buf_crypt(header, deskey, iv, DECRYPT); buf_cat(out, header); } buf_reset(header); buf_pad(header, 512); /* one block of 512 random data regardless of RSA key size */ buf_cat(out, header); buf_reset(iv); buf_append(iv, ivvec->data + 144, 8); buf_crypt(body, deskey, iv, DECRYPT); buf_cat(out, body); mix_pool(out, INTERMEDIATE, -1); break; case 1: buf_crypt(body, deskey, iv, DECRYPT); err = v2body_setlen(body); if (err == -1) goto end; assert(body->ptr == 4); v2body(body); break; case 2: buf_crypt(body, deskey, iv, DECRYPT); v2partial(body, mid, packet, numpackets); break; } end: buf_free(addr); buf_free(aes_body_key); buf_free(aes_header_key); buf_free(aes_iv); buf_free(aes_pre_key); buf_free(aes_tte_key); buf_free(antitag); buf_free(body); buf_free(bodydigest); buf_free(dec); buf_free(deskey); buf_free(digest); buf_free(extract); buf_free(header); buf_free(hkey); buf_free(iv); buf_free(ivvec); buf_free(keyid); buf_free(mid); buf_free(otherdigest); buf_free(out); buf_free(packetid); buf_free(privkey); buf_free(temp); buf_free(trail); buf_free(ttedigest); return (err); }
int main( int argc, char *argv[] ) { FILE *f; int ret, c; size_t i, olen = 0; pk_context pk; entropy_context entropy; ctr_drbg_context ctr_drbg; unsigned char result[1024]; unsigned char buf[512]; const char *pers = "pk_decrypt"; ((void) argv); memset(result, 0, sizeof( result ) ); ret = 1; if( argc != 2 ) { printf( "usage: pk_decrypt <key_file>\n" ); #if defined(_WIN32) printf( "\n" ); #endif goto exit; } 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 %d\n", ret ); goto exit; } printf( "\n . Reading private key from '%s'", argv[1] ); fflush( stdout ); pk_init( &pk ); if( ( ret = pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 ) { printf( " failed\n ! pk_parse_keyfile returned -0x%04x\n", -ret ); goto exit; } /* * Extract the RSA encrypted value from the text file */ ret = 1; if( ( f = fopen( "result-enc.txt", "rb" ) ) == NULL ) { printf( "\n ! Could not open %s\n\n", "result-enc.txt" ); goto exit; } i = 0; while( fscanf( f, "%02X", &c ) > 0 && i < (int) sizeof( buf ) ) buf[i++] = (unsigned char) c; fclose( f ); /* * Decrypt the encrypted RSA data and print the result. */ printf( "\n . Decrypting the encrypted data" ); fflush( stdout ); if( ( ret = pk_decrypt( &pk, buf, i, result, &olen, sizeof(result), ctr_drbg_random, &ctr_drbg ) ) != 0 ) { printf( " failed\n ! pk_decrypt returned -0x%04x\n", -ret ); goto exit; } printf( "\n . OK\n\n" ); printf( "The decrypted result is: '%s'\n\n", result ); ret = 0; exit: entropy_free( &entropy ); #if defined(POLARSSL_ERROR_C) polarssl_strerror( ret, (char *) buf, sizeof(buf) ); printf( " ! Last error was: %s\n", buf ); #endif #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
void attacker_send_asym_decrypted(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; unsigned int osize; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[MAX_MESSAGE_SIZE]; pk_context context; //@ 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; } //@ close pk_context(&context); pk_init(&context); //@ interpret_private_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key); //@ assert cg_key == cg_private_key(?p, ?c); if (pk_parse_key(&context, buffer1, (unsigned int) size1, NULL, 0) == 0) { if (size2 * 8 <= size1) { //@ close random_state_predicate(havege_state_initialized); /*@ produce_function_pointer_chunk random_function( attacker_key_item_havege_random_stub) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ interpret_asym_encrypted(buffer2, size2); //@ assert cryptogram(buffer2, size2, ?ccs2, ?cg_enc); //@ assert cg_enc == cg_asym_encrypted(?p2, ?c2, ?ccs_output2, ?ent); //@ structure s = known_value(0, nil); //@ close decryption_pre(false, false, attacker, s, ccs2); int success = pk_decrypt(&context, buffer2, (unsigned int) size2, buffer3, &osize, MAX_MESSAGE_SIZE, attacker_key_item_havege_random_stub, havege_state); //@ open decryption_post(false, ?garbage, attacker, s, p, c, ?ccs_output); //@ assert crypto_chars(?kind, buffer3, ?osize_val, ccs_output); /*@ if (garbage) { assert is_public_key_classifier(?proof, _, _, _); proof(cg_key, p, c, false); decryption_garbage(buffer3, osize_val, s); } else if (success == 0) { assert [_]pub(cg_enc); assert is_public_asym_decryption_is_public(?proof, pub, pred); proof(cg_key, cg_enc); public_crypto_chars(buffer3, osize_val); chars_to_crypto_chars(buffer3, osize_val); } @*/ //@ crypto_chars_to_chars(buffer3, osize_val); if (success == 0) net_send(socket, buffer3, osize); //@ chars_join(buffer3); //@ open cryptogram(buffer2, size2, ccs2, cg_enc); //@ public_crypto_chars(buffer2, size2); } //@ pk_release_context_with_key(&context); } pk_free(&context); //@ open pk_context(&context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_key); }