void BundleAuthenticationBlock::auth(dtn::data::Bundle &bundle, const dtn::security::SecurityKey &key) { BundleAuthenticationBlock& bab_begin = bundle.push_front<BundleAuthenticationBlock>(); bab_begin.set(dtn::data::Block::DISCARD_IF_NOT_PROCESSED, true); // set security source if (!key.reference.sameHost(bundle.source)) bab_begin.setSecuritySource( key.reference ); dtn::data::Number correlator = createCorrelatorValue(bundle); bab_begin.setCorrelator(correlator); bab_begin.setCiphersuiteId(BAB_HMAC); BundleAuthenticationBlock& bab_end = bundle.push_back<BundleAuthenticationBlock>(); bab_end.set(dtn::data::Block::DISCARD_IF_NOT_PROCESSED, true); bab_end.setCorrelator(correlator); bab_end._ciphersuite_flags |= CONTAINS_SECURITY_RESULT; std::string sizehash_hash = calcMAC(bundle, key); bab_end._security_result.set(SecurityBlock::integrity_signature, sizehash_hash); }
void PayloadConfidentialBlock::encrypt(dtn::data::Bundle& bundle, const dtn::security::SecurityKey &long_key, const dtn::data::EID& source) { // contains the random salt uint32_t salt; // contains the random key unsigned char ephemeral_key[ibrcommon::AES128Stream::key_size_in_bytes]; unsigned char iv[ibrcommon::AES128Stream::iv_len]; unsigned char tag[ibrcommon::AES128Stream::tag_len]; // create a new correlator value dtn::data::Number correlator = createCorrelatorValue(bundle); // create a random salt and key createSaltAndKey(salt, ephemeral_key, ibrcommon::AES128Stream::key_size_in_bytes); // count all PCBs dtn::data::Size pcbs_size = std::count(bundle.begin(), bundle.end(), PayloadConfidentialBlock::BLOCK_TYPE); // count all PIBs dtn::data::Size pibs_size = std::count(bundle.begin(), bundle.end(), PayloadIntegrityBlock::BLOCK_TYPE); // encrypt PCBs and PIBs dtn::data::Bundle::find_iterator find_pcb(bundle.begin(), PayloadConfidentialBlock::BLOCK_TYPE); while (find_pcb.next(bundle.end())) { SecurityBlock::encryptBlock<PayloadConfidentialBlock>(bundle, find_pcb, salt, ephemeral_key).setCorrelator(correlator); } dtn::data::Bundle::find_iterator find_pib(bundle.begin(), PayloadIntegrityBlock::BLOCK_TYPE); while (find_pib.next(bundle.end())) { SecurityBlock::encryptBlock<PayloadConfidentialBlock>(bundle, find_pib, salt, ephemeral_key).setCorrelator(correlator); } // create a new payload confidential block PayloadConfidentialBlock& pcb = bundle.push_front<PayloadConfidentialBlock>(); // set the correlator if (pcbs_size > 0 || pibs_size > 0) pcb.setCorrelator(correlator); // get reference to the payload block dtn::data::PayloadBlock& plb = bundle.find<dtn::data::PayloadBlock>(); ibrcommon::BLOB::Reference blobref = plb.getBLOB(); // encrypt payload - BEGIN { ibrcommon::BLOB::iostream stream = blobref.iostream(); ibrcommon::AES128Stream aes_stream(ibrcommon::CipherStream::CIPHER_ENCRYPT, *stream, ephemeral_key, salt); // encrypt in place ((ibrcommon::CipherStream&)aes_stream).encrypt(*stream); // check if this is a fragment if (bundle.get(dtn::data::PrimaryBlock::FRAGMENT)) { // ... and set the corresponding cipher suit params addFragmentRange(pcb._ciphersuite_params, bundle.fragmentoffset, stream.size()); } // get the IV aes_stream.getIV(iv); // get the tag aes_stream.getTag(tag); } // encrypt payload - END // set the source and destination address of the new block if (source != bundle.source.getNode()) pcb.setSecuritySource( source ); if (long_key.reference != bundle.destination.getNode()) pcb.setSecurityDestination( long_key.reference ); // set replicate in every fragment to true pcb.set(REPLICATE_IN_EVERY_FRAGMENT, true); // store encypted key, tag, iv and salt addSalt(pcb._ciphersuite_params, salt); // get the RSA key RSA *rsa_key = long_key.getRSA(); // encrypt the random key and add it to the ciphersuite params addKey(pcb._ciphersuite_params, ephemeral_key, ibrcommon::AES128Stream::key_size_in_bytes, rsa_key); // free the RSA key long_key.free(rsa_key); pcb._ciphersuite_params.set(SecurityBlock::initialization_vector, iv, ibrcommon::AES128Stream::iv_len); pcb._ciphersuite_flags |= SecurityBlock::CONTAINS_CIPHERSUITE_PARAMS; pcb._security_result.set(SecurityBlock::PCB_integrity_check_value, tag, ibrcommon::AES128Stream::tag_len); pcb._ciphersuite_flags |= SecurityBlock::CONTAINS_SECURITY_RESULT; }