From 0f3bfe26875dac4a53559da0651f1629fd0b64ef Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Thu, 12 Dec 2019 16:08:32 -0500 Subject: [PATCH 01/23] Add crypto extern --- targets/simple_switch/externs/crypto/basic.p4 | 453 ++++++++++++++++ .../simple_switch/externs/crypto/crypto.cpp | 512 ++++++++++++++++++ 2 files changed, 965 insertions(+) create mode 100644 targets/simple_switch/externs/crypto/basic.p4 create mode 100644 targets/simple_switch/externs/crypto/crypto.cpp diff --git a/targets/simple_switch/externs/crypto/basic.p4 b/targets/simple_switch/externs/crypto/basic.p4 new file mode 100644 index 000000000..3463c6d07 --- /dev/null +++ b/targets/simple_switch/externs/crypto/basic.p4 @@ -0,0 +1,453 @@ +/* -*- P4_16 -*- */ +#include +#include + +#define CONTROLLER_PORT 16 + +const bit<16> TYPE_IPV4 = 0x800; +const bit<16> TYPE_ARP = 0x806; +const bit<16> TYPE_LLDP = 0x88cc; +const bit<16> TYPE_MACSEC = 0x88e5; +const bit<16> TYPE_BDDP = 0x8999; + +const bit<16> DST_MAC_UNKNOWN = 1; +const bit<16> SRC_MAC_UNKNOWN = 2; +const bit<16> SRC_MAC_TIMEOUT = 3; +const bit<16> SRC_MAC_CHANGED_PORT = 4; +const bit<16> ARP_IN = 10; +const bit<16> LLDP_IN = 11; +const bit<16> PACKET_OUT_ON_PORT = 60001; +const bit<16> FULL_PROCESS = 60002; + + +/************************************************************************* +*********************** H E A D E R S *********************************** +*************************************************************************/ + +typedef bit<9> egressSpec_t; +typedef bit<48> macAddr_t; +typedef bit<32> ip4Addr_t; + +header cpu_header_t { + bit<64> zeros; + bit<16> reason; + bit<16> port; + bit<48> timestamp; +} + +header ethernet_t { + macAddr_t dstAddr; + macAddr_t srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + ip4Addr_t srcAddr; + ip4Addr_t dstAddr; +} + +header sectag_t { + bit<1> tci_v; + bit<1> tci_es; + bit<1> tci_sc; + bit<1> tci_scb; + bit<1> tci_e; + bit<1> tci_c; + bit<2> an; + bit<8> sl; + bit<32> pn; + bit<64> sci; +} + +struct user_metadata_t { + bit<128> SAK; + bit<48> SYSTEM_ID; + bit<8> REGISTER_NUMBER; + bit<48> src_mac_timeout; + egressSpec_t src_mac_table_port; + bool from_controller; + bool recirculated; +} + +struct intrinsic_metadata_t { + bit<16> recirculate_flag; + bit<48> ingress_global_timestamp; +} + +struct metadata { + @metadata @name("intrinsic_metadata") + intrinsic_metadata_t intrinsic_metadata; + user_metadata_t user_metadata; +} + +struct headers { + cpu_header_t cpu_header; + ethernet_t ethernet; + sectag_t sectag; + ipv4_t ipv4; +} + +/************************************************************************* +*********************** P A R S E R *********************************** +*************************************************************************/ + +parser MyParser(packet_in packet, + out headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + + state start { + transition select(packet.lookahead().zeros) { + (bit<64>)0 : parse_cpu_header; + default: parse_ethernet; + } + } + + state parse_cpu_header { + packet.extract(hdr.cpu_header); + transition parse_ethernet; + } + + state parse_ethernet { + packet.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + TYPE_IPV4: parse_ipv4; + TYPE_MACSEC: parse_sectag; + TYPE_LLDP: accept; + TYPE_BDDP: accept; + default: accept; + } + } + + state parse_ipv4 { + packet.extract(hdr.ipv4); + transition accept; + } + + state parse_sectag { + packet.extract(hdr.sectag); + transition accept; + } + +} + +/************************************************************************* +************ C H E C K S U M V E R I F I C A T I O N ************* +*************************************************************************/ + +control MyVerifyChecksum(inout headers hdr, inout metadata meta) { + apply { } +} + + +/************************************************************************* +************** I N G R E S S P R O C E S S I N G ******************* +*************************************************************************/ + +extern ExternCrypt { + ExternCrypt(); + void protect(in bit<128> SAK, + in bit<64> SCI, + in bit<32> PN, + in bit<48> src_addr, + in bit<48> dst_addr, + in bit<128> sectag, + in bit<16> ethertype, + in bit<8> prepend_ipv4_hdr, + in bit<160> ipv4_hdr); + void validate(in bit<128> SAK, + in bit<64> SCI, + in bit<32> PN, + in bit<48> src_addr, + in bit<48> dst_addr, + in bit<128> sectag, + out bit<8> valid, + out bit<16> ethertype); +} + +ExternCrypt() crypt; + + +control MyIngress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + action drop() { + mark_to_drop(); + } + + action send_to_controller(bit<16> reason, egressSpec_t port){ + standard_metadata.egress_spec = CONTROLLER_PORT; + hdr.cpu_header.setValid(); + hdr.cpu_header.reason = reason; + hdr.cpu_header.port = (bit<16>)port; + hdr.cpu_header.timestamp = standard_metadata.ingress_global_timestamp; + } + + action l2_forward(egressSpec_t port) { + standard_metadata.egress_spec = port; + } + + action flood() { + send_to_controller(DST_MAC_UNKNOWN, standard_metadata.ingress_port); + } + + action learn_src_mac() { + send_to_controller(SRC_MAC_UNKNOWN, standard_metadata.ingress_port); + } + + action src_known(egressSpec_t port, bit<48> timestamp) { + meta.user_metadata.src_mac_table_port = port; + meta.user_metadata.src_mac_timeout = timestamp; + } + + action validate_packet(bit<128> key) { + meta.user_metadata.SAK = key; + } + + table mac_src { + key = { + hdr.ethernet.srcAddr: exact; + } + actions = { + learn_src_mac; + src_known; + } + size = 1024; + default_action = learn_src_mac(); + } + + table mac_dst { + key = { + hdr.ethernet.dstAddr: exact; + } + actions = { + l2_forward; + flood; + drop; + } + size = 1024; + default_action = flood(); + } + + table validate_tbl { + key = { + standard_metadata.ingress_port: exact; + } + actions = { + NoAction; + validate_packet; + } + } + + apply { + //packet from controller, go through full pipeline + if (hdr.cpu_header.isValid() && hdr.cpu_header.reason == FULL_PROCESS) { + hdr.cpu_header.setInvalid(); + meta.user_metadata.from_controller = true; + } + else { + meta.user_metadata.from_controller = false; + } + + // packet from controller, send out on specified port + if (hdr.cpu_header.isValid() && hdr.cpu_header.reason == PACKET_OUT_ON_PORT) { + standard_metadata.egress_spec = (bit<9>)hdr.cpu_header.port; + hdr.cpu_header.setInvalid(); + } + + // packet encrypted with macsec + else if (hdr.sectag.isValid()) { + if (validate_tbl.apply().hit) { + //key found, decrypt the packet + bit<128> SAK = meta.user_metadata.SAK; + bit<64> SCI = hdr.sectag.sci; + bit<32> PN = hdr.sectag.pn; + bit<128> sectag = TYPE_MACSEC ++ hdr.sectag.tci_v ++ hdr.sectag.tci_es ++ hdr.sectag.tci_sc ++ hdr.sectag.tci_scb ++ hdr.sectag.tci_e ++ hdr.sectag.tci_c ++ hdr.sectag.an ++ hdr.sectag.sl ++ hdr.sectag.pn ++ hdr.sectag.sci; + bit<48> src_addr = hdr.ethernet.srcAddr; + bit<48> dst_addr = hdr.ethernet.dstAddr; + bit<8> valid; + bit<16> ethertype; + + crypt.validate(SAK, SCI, PN, src_addr, dst_addr, sectag, valid, ethertype); + + hdr.ethernet.etherType = ethertype; + hdr.sectag.setInvalid(); + + //headers from decrypted payload not parsed -> recirculate packet + meta.user_metadata.recirculated = true; + recirculate({meta.intrinsic_metadata, standard_metadata, meta.user_metadata}); + } + } + + // LLDP or BDDP packet, send to controller + else if (hdr.ethernet.isValid() && (hdr.ethernet.etherType == TYPE_LLDP || hdr.ethernet.etherType == TYPE_BDDP)) { + send_to_controller(LLDP_IN, standard_metadata.ingress_port); + } + + // ARP packet, send to controller + else if (hdr.ethernet.isValid() && hdr.ethernet.etherType == TYPE_ARP) { + send_to_controller(ARP_IN, standard_metadata.ingress_port); + } + + // all other ethernet packets + else if (hdr.ethernet.isValid()) { + // refresh source mac entry + if(!meta.user_metadata.from_controller && mac_src.apply().hit) { + if(standard_metadata.ingress_global_timestamp > meta.user_metadata.src_mac_timeout) { + send_to_controller(SRC_MAC_TIMEOUT, standard_metadata.ingress_port); + } + else if (meta.user_metadata.src_mac_table_port != standard_metadata.ingress_port) { + send_to_controller(SRC_MAC_CHANGED_PORT, standard_metadata.ingress_port); + } + } + + // get port for dst amc + // drop if port unknown and packet was decrypted (=recirculated) + // (prevents flooding decrypted packet) + if(!hdr.cpu_header.isValid()) { + if(!mac_dst.apply().hit && meta.user_metadata.recirculated) { + drop(); + } + } + + // drop packet if premilinary egress port + if (standard_metadata.egress_spec == 0x1FF) { + drop(); + } + + // drop packet if ingress port == egress port + if (standard_metadata.egress_spec != CONTROLLER_PORT && standard_metadata.egress_spec == standard_metadata.ingress_port) { + drop(); + } + } + } +} + +/************************************************************************* +**************** E G R E S S P R O C E S S I N G ******************* +*************************************************************************/ + +//16 register, bei mehr Ports entsprechend anpassen +register>(32w64) outgoing_packet_numbers; + +control MyEgress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + action protect_packet(bit<128> key, bit<48> system_id, bit<8> reg) { + meta.user_metadata.SAK = key; + meta.user_metadata.SYSTEM_ID = system_id; + meta.user_metadata.REGISTER_NUMBER = reg; + } + + table protect_tbl { + key = { + standard_metadata.egress_port: exact; + } + actions = { + NoAction; + protect_packet; + } + } + + apply { + if (!hdr.cpu_header.isValid() && hdr.ethernet.isValid() && hdr.ethernet.etherType != TYPE_ARP + && hdr.ethernet.etherType != TYPE_BDDP && protect_tbl.apply().hit){ + bit<128> SAK = meta.user_metadata.SAK; + //get the PN from the corresponding counter + bit<32> PN; + outgoing_packet_numbers.read(PN, (bit<32>) meta.user_metadata.REGISTER_NUMBER); + outgoing_packet_numbers.write((bit<32>) meta.user_metadata.REGISTER_NUMBER, PN + 1); + + //combine the System and Port Id to get the SCI + bit<64> SCI = meta.user_metadata.SYSTEM_ID ++ (bit<16>) standard_metadata.egress_port; + + //set the macsec Header fragments to valid + hdr.sectag.setValid(); + + //set the neccesary data for the sectag and the new ethertype + hdr.sectag.tci_v = 0; + hdr.sectag.tci_es = 0; + hdr.sectag.tci_sc = 1; + hdr.sectag.tci_scb = 0; + hdr.sectag.tci_e = 1; + hdr.sectag.tci_c = 1; + hdr.sectag.an = 0; + hdr.sectag.sl = 0; + hdr.sectag.pn = PN; + hdr.sectag.sci = SCI; + bit<128> sectag = TYPE_MACSEC ++ hdr.sectag.tci_v ++ hdr.sectag.tci_es ++ hdr.sectag.tci_sc ++ hdr.sectag.tci_scb ++ hdr.sectag.tci_e ++ hdr.sectag.tci_c ++ hdr.sectag.an ++ hdr.sectag.sl ++ hdr.sectag.pn ++ hdr.sectag.sci; + + bit<8> prepend_ipv4 = 0x46; + bit<160> ipv4 = 0; + if (hdr.ipv4.isValid()) { + prepend_ipv4 = 0x54; + ipv4 = hdr.ipv4.version ++ hdr.ipv4.ihl ++ hdr.ipv4.diffserv ++ hdr.ipv4.totalLen ++ hdr.ipv4.identification ++ hdr.ipv4.flags ++ hdr.ipv4.fragOffset ++ hdr.ipv4.ttl ++ hdr.ipv4.protocol ++ hdr.ipv4.hdrChecksum ++ hdr.ipv4.srcAddr ++ hdr.ipv4.dstAddr; + hdr.ipv4.setInvalid(); + } + + crypt.protect(SAK, SCI, PN, hdr.ethernet.srcAddr, hdr.ethernet.dstAddr, sectag, hdr.ethernet.etherType, prepend_ipv4, ipv4); + + hdr.ethernet.etherType = TYPE_MACSEC; + } + } +} + +/************************************************************************* +************* C H E C K S U M C O M P U T A T I O N ************** +*************************************************************************/ + +control MyComputeChecksum(inout headers hdr, inout metadata meta) { + apply { + update_checksum( + hdr.ipv4.isValid(), + { hdr.ipv4.version, + hdr.ipv4.ihl, + hdr.ipv4.diffserv, + hdr.ipv4.totalLen, + hdr.ipv4.identification, + hdr.ipv4.flags, + hdr.ipv4.fragOffset, + hdr.ipv4.ttl, + hdr.ipv4.protocol, + hdr.ipv4.srcAddr, + hdr.ipv4.dstAddr }, + hdr.ipv4.hdrChecksum, + HashAlgorithm.csum16); + } +} + +/************************************************************************* +*********************** D E P A R S E R ******************************* +*************************************************************************/ + +control MyDeparser(packet_out packet, in headers hdr) { + apply { + packet.emit(hdr.cpu_header); + packet.emit(hdr.ethernet); + packet.emit(hdr.sectag); + packet.emit(hdr.ipv4); + } +} + +/************************************************************************* +*********************** S W I T C H ******************************* +*************************************************************************/ + +V1Switch( +MyParser(), +MyVerifyChecksum(), +MyIngress(), +MyEgress(), +MyComputeChecksum(), +MyDeparser() +) main; diff --git a/targets/simple_switch/externs/crypto/crypto.cpp b/targets/simple_switch/externs/crypto/crypto.cpp new file mode 100644 index 000000000..9d9819053 --- /dev/null +++ b/targets/simple_switch/externs/crypto/crypto.cpp @@ -0,0 +1,512 @@ +/* Copyright 2013-present Barefoot Networks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Antonin Bas (antonin@barefootnetworks.com) + * + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include + +//aes stuff +#include +#include +#include +#include +#include + +//needed for externs +#include + +#include "simple_switch.h" + +using namespace bm; +using std::endl; +using std::cout; +using std::string; +using std::vector; + + +class ExternCrypt : public ExternType { + public: + + BM_EXTERN_ATTRIBUTES { + + } + + void init() override { + } + void protect( const Data &in_sak, + const Data &in_sci, + const Data &in_pn, + const Data &in_src_addr, + const Data &in_dst_addr, + const Data &in_sectag, + const Data &in_ethertype, + const Data &in_prepend_ipv4_hdr, + const Data &in_ipv4_hdr) { + std::vector secure_association_key = get_char_vector(in_sak.get_string(), SAK_SIZE); + //cout << "[p4sec] secure_association_key" << std::endl; + //hexdump((char*)&secure_association_key[0], secure_association_key.size()); + + std::vector secure_channel_identifier = get_char_vector(in_sci.get_string(), SCI_SIZE); + //cout << "[p4sec] secure_channel_identifier" << std::endl; + //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); + + std::vector packet_number = get_char_vector(in_pn.get_string(), PN_SIZE); + //cout << "[p4sec] packet_number" << std::endl; + //hexdump((char*)&packet_number[0], packet_number.size()); + + std::vector source_mac_address = get_char_vector(in_src_addr.get_string(), ADDR_SIZE); + //cout << "[p4sec] source_mac_address" << std::endl; + //hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + std::vector destionation_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + //cout << "[p4sec] destionation_mac_address" << std::endl; + //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); + + std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); + //cout << "[p4sec] security_tag" << std::endl; + //hexdump((char*)&security_tag[0], security_tag.size()); + + std::vector ethertype = get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); + //cout << "[p4sec] EtherType" << std::endl; + //hexdump((char*)ðertype[0], ethertype.size()); + + bool prepend_ipv4 = false; + // must pass byte to external function + // use 0x54 T as true + // use 0x46 F as false + //cout << "[p4sec] prepend IPv4 Header ? " << in_prepend_ipv4_hdr.get_string() << std::endl; + if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { + prepend_ipv4 = true; + //cout << "[p4sec] prepend IPv4 Header" << std::endl; + } + else{ + //cout << "[p4sec] do not prepend IPv4 Header" << std::endl; + } + + std::vector ipv4_hdr; + if (prepend_ipv4) { + ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); + //cout << "[p4sec] IPv4 Header" << std::endl; + //hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); + } + + + vector raw_packet_data; + // calculate secure data length + int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; + if (prepend_ipv4) { + raw_packet_size += IPV4_HDR_SIZE; + } + raw_packet_data.resize(raw_packet_size, '\0'); + // copy EtherType + vector::iterator copy_pointer = raw_packet_data.begin(); + std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, + copy_pointer); + copy_pointer += ETHERTYPE_SIZE; + // copy IPv4 Header if necessary + if (prepend_ipv4) { + std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, + copy_pointer); + copy_pointer += IPV4_HDR_SIZE; + } + // copy payload + std::copy(get_packet().data(), + get_packet().data() + get_packet().get_data_size(), + copy_pointer); + + + std::vector secure_data; + secure_data.reserve(raw_packet_size); + std::vector integrity_check_value; + integrity_check_value.reserve(ICV_SIZE); + + protection_function(secure_association_key, secure_channel_identifier, packet_number, destionation_mac_address, source_mac_address, + security_tag, raw_packet_data, secure_data, integrity_check_value); + + //cout << "[p4sec] secure_data" << std::endl; + //hexdump((char*)&secure_data[0], secure_data.size()); + + //cout << "[p4sec] integrity_check_value" << std::endl; + //hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + + //replace payload + //first, remove all the data + get_packet().remove(get_packet().get_data_size()); + //make room for the ciphertext and write the ciphertext in it + char *payload_start = get_packet().prepend( + (unsigned long int) (secure_data.size() + integrity_check_value.size())); + for (uint i = 0; i < secure_data.size(); i++) { + payload_start[i] = secure_data[i]; + } + for (uint i = 0; i < integrity_check_value.size(); i++) { + payload_start[i + secure_data.size()] = integrity_check_value[i]; + } + } + + void validate(const Data &in_sak, + const Data &in_sci, + const Data &in_pn, + const Data &in_src_addr, + const Data &in_dst_addr, + const Data &in_sectag, + Data &out_valid, + Data &out_ethertype) { + + std::vector secure_association_key = get_char_vector(in_sak.get_string(), SAK_SIZE); + //cout << "[p4sec] secure_association_key" << std::endl; + //hexdump((char*)&secure_association_key[0], secure_association_key.size()); + + std::vector secure_channel_identifier = get_char_vector(in_sci.get_string(), SCI_SIZE); + //cout << "[p4sec] secure_channel_identifier" << std::endl; + //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); + + std::vector packet_number = get_char_vector(in_pn.get_string(), PN_SIZE); + //cout << "[p4sec] packet_number" << std::endl; + //hexdump((char*)&packet_number[0], packet_number.size()); + + std::vector source_mac_address = get_char_vector(in_src_addr.get_string(), ADDR_SIZE); + //cout << "[p4sec] source_mac_address" << std::endl; + //hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + std::vector destionation_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + //cout << "[p4sec] destionation_mac_address" << std::endl; + //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); + + std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); + //cout << "[p4sec] security_tag" << std::endl; + //hexdump((char*)&security_tag[0], security_tag.size()); + + std::vector secure_data; + // calculate secure data length + int secure_data_size = get_packet().get_data_size() - ICV_SIZE; + secure_data.resize(secure_data_size, '\0'); + + std::vector integrity_check_value; + integrity_check_value.resize(ICV_SIZE, '\0'); + + // copy secure data + std::copy(get_packet().data(), + get_packet().data() + get_packet().get_data_size() - ICV_SIZE, + secure_data.begin()); + + // copy ICV + std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, + get_packet().data() + get_packet().get_data_size(), + integrity_check_value.begin()); + + //cout << "[p4sec] secure_data" << std::endl; + //hexdump((char*)&secure_data[0], secure_data.size()); + + //cout << "[p4sec] integrity_check_value" << std::endl; + //hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + + std::vector user_data; + user_data.reserve(secure_data_size); + + int valid = validation_function(secure_association_key, secure_channel_identifier, packet_number, destionation_mac_address, source_mac_address, + security_tag, secure_data, integrity_check_value, user_data); + + + //cout << "[p4sec] user_data" << std::endl; + //hexdump((char*)&user_data[0], user_data.size()); + + //cout << "[p4sec] Ethertype" << std::endl; + //hexdump((char*)&user_data[0], ETHERTYPE_SIZE); + + //cout << "[p4sec] decrypted payload" << std::endl; + //hexdump((char*)&user_data[ETHERTYPE_SIZE], user_data.size() - ETHERTYPE_SIZE); + + //replace payload + //first, remove all the data + get_packet().remove(get_packet().get_data_size()); + //make room for the ciphertext and write the ciphertext in it + char *payload_start = get_packet().prepend((unsigned long int) user_data.size()); + for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { + payload_start[i] = user_data[i + ETHERTYPE_SIZE]; + } + + //copy ethertype from encrypted packet + std::stringstream ss_ethertype; + for(uint i=0; i get_char_vector(string str, uint size) { + //string fitted_str = fit_string(str, size); + std::vector vec(size,'\0'); + if (str.length() > size) { + //cout << "[p4sec] given string was too long" << std::endl; + str.resize(size); + } + vec.insert(vec.cend()-size, str.begin(), str.end()); + + return vec; + } + + void protection_function(std::vector secure_association_key, // + std::vector secure_channel_identifier, // + std::vector packet_number, // + std::vector destionation_mac_address, // + std::vector source_mac_address, // + std::vector security_tag, // + std::vector user_data, // + std::vector& out_secure_data, + std::vector& out_integrity_check_value + ) { + //hier evtl assertions fuer die Laenge der Parameter + // + //std::cout << "[p4sec] secure_association_key size " << secure_association_key.size() << std::endl; + //hexdump((char*)&secure_association_key[0], secure_association_key.size()); + + //std::cout << "[p4sec] secure_channel_identifier size " << secure_channel_identifier.size() << std::endl; + //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); + + //std::cout << "[p4sec] packet_number size " << packet_number.size() << std::endl; + //hexdump((char*)&packet_number[0], packet_number.size()); + + //std::cout << "[p4sec] destionation_mac_address size " << destionation_mac_address.size() << std::endl; + //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); + + //std::cout << "[p4sec] source_mac_address size " << source_mac_address.size() << std::endl; + //hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + //std::cout << "[p4sec] security_tag size " << security_tag.size() << std::endl; + //hexdump((char*)&security_tag[0], security_tag.size()); + + //std::cout << "[p4sec] user_data size " << user_data.size() << std::endl; + //hexdump((char*)&user_data[0], user_data.size()); + + + //terms K, IV, A, P, C, T used in section 2.1 of the GCM specification ( GCM ) as submitted to NIST + + //128 bit key + std::vector K; + K.reserve(secure_association_key.size()); + K.insert( K.cend(), secure_association_key.cbegin(), secure_association_key.cend() ); + + //std::cout << "[p4sec] K size " << K.size() << std::endl; + //hexdump((char*)&K[0], K.size()); + + //12 byte IV + std::vector IV; + IV.reserve(secure_channel_identifier.size() + packet_number.size()); + //The 64 most significant bits of the 96-bit IV are the octets of the SCI, encoded as a binary number (9.1). + IV.insert( IV.cend(), secure_channel_identifier.cbegin(), secure_channel_identifier.cend() ); + //The 32 least significant bits of the 96-bit IV are the octets of the PN, encoded as a binary number + IV.insert( IV.cend(), packet_number.cbegin(), packet_number.cend() ); + + //std::cout << "[p4sec] IV size " << IV.size() << std::endl; + //hexdump((char*)&IV[0], IV.size()); + + + //A is the Destination MAC Address, Source MAC Address, and the octets of the SecTAG concatenated in that order + std::vector A; + A.reserve(destionation_mac_address.size() + source_mac_address.size() + security_tag.size()); + A.insert( A.cend(), destionation_mac_address.cbegin(), destionation_mac_address.cend() ); + A.insert( A.cend(), source_mac_address.cbegin(), source_mac_address.cend() ); + A.insert( A.cend(), security_tag.cbegin(), security_tag.cend() ); + + //P is the octets of the User Data + std::vector P; + P.reserve(user_data.size()); + P.insert( P.cend(), user_data.cbegin(), user_data.cend() ); + + + out_secure_data.resize(P.size(), '\0'); + out_integrity_check_value.resize(16, '\0'); + + + //std::cout << "[p4sec] out_secure_data size " << out_secure_data.size() << std::endl; + //hexdump((char*)&out_secure_data[0], out_secure_data.size()); + + //std::cout << "[p4sec] out_integrity_check_value size " << out_integrity_check_value.size() << std::endl; + //hexdump((char*)&out_integrity_check_value[0], out_integrity_check_value.size()); + + //std::cout << "[p4sec] initilalizing encryption" << std::endl; + int actual_size=0, final_size=0; + EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); + + // Set the IV length, kann man machen, muss man aber nicht da standard 12 + // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); + //https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode + //To specify any additional authenticated data (AAD) a call to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made with the output parameter out set to NULL + EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); + EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, &P[0], P.size() ); + EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); + EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, &out_integrity_check_value[0]); + EVP_CIPHER_CTX_free(e_ctx); + } + + int validation_function(std::vector secure_association_key, // + std::vector secure_channel_identifier, // + std::vector packet_number, // + std::vector destionation_mac_address, // + std::vector source_mac_address, // + std::vector security_tag, // + std::vector secure_data, // + std::vector integrity_check_value, + std::vector& out_user_data) { + //std::cout << "[p4sec] secure_association_key size " << secure_association_key.size() << std::endl; + //hexdump((char*)&secure_association_key[0], secure_association_key.size()); + + //std::cout << "[p4sec] secure_channel_identifier size " << secure_channel_identifier.size() << std::endl; + //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); + + //std::cout << "[p4sec] packet_number size " << packet_number.size() << std::endl; + //hexdump((char*)&packet_number[0], packet_number.size()); + + //std::cout << "[p4sec] destionation_mac_address size " << destionation_mac_address.size() << std::endl; + //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); + + //std::cout << "[p4sec] source_mac_address size " << source_mac_address.size() << std::endl; + //hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + //std::cout << "[p4sec] security_tag size " << security_tag.size() << std::endl; + //hexdump((char*)&security_tag[0], security_tag.size()); + + //std::cout << "[p4sec] secure_data size " << secure_data.size() << std::endl; + //hexdump((char*)&secure_data[0], secure_data.size()); + + //std::cout << "[p4sec] integrity_check_value size " << integrity_check_value.size() << std::endl; + //hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + + + //terms K, IV, A, P, C, T used in section 2.1 of the GCM specification ( GCM ) as submitted to NIST + + //128 bit key + std::vector K; + K.reserve(secure_association_key.size()); + K.insert( K.cend(), secure_association_key.cbegin(), secure_association_key.cend() ); + + //std::cout << "[p4sec] K size " << K.size() << std::endl; + //hexdump((char*)&K[0], K.size()); + + //12 byte IV + std::vector IV; + IV.reserve(secure_channel_identifier.size() + packet_number.size()); + //The 64 most significant bits of the 96-bit IV are the octets of the SCI, encoded as a binary number (9.1). + IV.insert( IV.cend(), secure_channel_identifier.cbegin(), secure_channel_identifier.cend() ); + //The 32 least significant bits of the 96-bit IV are the octets of the PN, encoded as a binary number + IV.insert( IV.cend(), packet_number.cbegin(), packet_number.cend() ); + + //std::cout << "[p4sec] IV size " << IV.size() << std::endl; + //hexdump((char*)&IV[0], IV.size()); + + + //A is the Destination MAC Address, Source MAC Address, and the octets of the SecTAG concatenated in that order + std::vector A; + A.reserve(destionation_mac_address.size() + source_mac_address.size() + security_tag.size()); + A.insert( A.cend(), destionation_mac_address.cbegin(), destionation_mac_address.cend() ); + A.insert( A.cend(), source_mac_address.cbegin(), source_mac_address.cend() ); + A.insert( A.cend(), security_tag.cbegin(), security_tag.cend() ); + + //P is the octets of the User Data + std::vector P; + P.reserve(secure_data.size()); + P.insert( P.cend(), secure_data.cbegin(), secure_data.cend() ); + + out_user_data.resize(P.size(), '\0'); + + int actual_size=0, final_size=0; + EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); + + //https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode + //To specify any additional authenticated data (AAD) a call to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made with the output parameter out set to NULL + EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); + + EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, &P[0], P.size() ); + EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, &integrity_check_value[0]); + int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], &final_size); + + if(result == 1) { + //valid result + } else { + //decryption failed + //-> abprt/drop packet? + } + + //std::cout << "result of decryption: " << result << std::endl; + + + EVP_CIPHER_CTX_free(d_ctx); + + return result; + } + + void hexDump (char *addr, int len) { + int i; + unsigned char buff[17]; + unsigned char *pc = (unsigned char*)addr; + // Process every byte in the data. + for (i = 0; i < len; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Just don't print ASCII for the zeroth line. + if (i != 0) + printf (" %s\n", buff); + + // Output the offset. + printf ("[p4sec] %04x ", i); + } + + // Now the hex code for the specific character. + printf (" %02x", pc[i]); + + // And store a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + while ((i % 16) != 0) { + printf (" "); + i++; + } + + // And print the final ASCII bit. + printf (" %s\n", buff); + } +}; + +// do not put these inside an anonymous namespace or some compilers may complain +BM_REGISTER_EXTERN(ExternCrypt); +BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &); +BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, Data &, Data &); + +BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); +BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &); +BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, Data &, Data &); From e9e1785d4ea15641bf8f5df741e91812a8eeea3c Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Thu, 12 Dec 2019 19:19:46 -0500 Subject: [PATCH 02/23] Fix cpplint issues in crypto.cpp; header file c/c++ issues remain --- .../simple_switch/externs/crypto/crypto.cpp | 557 ++++++++++-------- 1 file changed, 321 insertions(+), 236 deletions(-) diff --git a/targets/simple_switch/externs/crypto/crypto.cpp b/targets/simple_switch/externs/crypto/crypto.cpp index 9d9819053..f2456290b 100644 --- a/targets/simple_switch/externs/crypto/crypto.cpp +++ b/targets/simple_switch/externs/crypto/crypto.cpp @@ -17,6 +17,10 @@ * Antonin Bas (antonin@barefootnetworks.com) * */ +// aes stuff +#include +#include +#include #include #include @@ -24,22 +28,18 @@ #include +// needed for externs +#include +#include "simple_switch.h" + + #include #include #include #include - -//aes stuff -#include -#include -#include -#include #include - -//needed for externs -#include - -#include "simple_switch.h" +#include +#include using namespace bm; using std::endl; @@ -50,14 +50,12 @@ using std::vector; class ExternCrypt : public ExternType { public: - BM_EXTERN_ATTRIBUTES { - } void init() override { } - void protect( const Data &in_sak, + void protect(const Data &in_sak, const Data &in_sci, const Data &in_pn, const Data &in_src_addr, @@ -66,52 +64,62 @@ class ExternCrypt : public ExternType { const Data &in_ethertype, const Data &in_prepend_ipv4_hdr, const Data &in_ipv4_hdr) { - std::vector secure_association_key = get_char_vector(in_sak.get_string(), SAK_SIZE); - //cout << "[p4sec] secure_association_key" << std::endl; - //hexdump((char*)&secure_association_key[0], secure_association_key.size()); - - std::vector secure_channel_identifier = get_char_vector(in_sci.get_string(), SCI_SIZE); - //cout << "[p4sec] secure_channel_identifier" << std::endl; - //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); - - std::vector packet_number = get_char_vector(in_pn.get_string(), PN_SIZE); - //cout << "[p4sec] packet_number" << std::endl; - //hexdump((char*)&packet_number[0], packet_number.size()); - - std::vector source_mac_address = get_char_vector(in_src_addr.get_string(), ADDR_SIZE); - //cout << "[p4sec] source_mac_address" << std::endl; - //hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - std::vector destionation_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - //cout << "[p4sec] destionation_mac_address" << std::endl; - //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); - - std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); - //cout << "[p4sec] security_tag" << std::endl; - //hexdump((char*)&security_tag[0], security_tag.size()); - - std::vector ethertype = get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); - //cout << "[p4sec] EtherType" << std::endl; - //hexdump((char*)ðertype[0], ethertype.size()); + std::vector secure_association_key = get_char_vector( + in_sak.get_string(), SAK_SIZE); + // cout << "[p4sec] secure_association_key" << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + std::vector secure_channel_identifier = + get_char_vector(in_sci.get_string(), SCI_SIZE); + // cout << "[p4sec] secure_channel_identifier" << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + std::vector packet_number = + get_char_vector(in_pn.get_string(), PN_SIZE); + // cout << "[p4sec] packet_number" << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + std::vector source_mac_address = + get_char_vector(in_src_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] source_mac_address" << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + std::vector destionation_mac_address = + get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] destionation_mac_address" << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + std::vector security_tag = + get_char_vector(in_sectag.get_string(), SECTAG_SIZE); + // cout << "[p4sec] security_tag" << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); + + std::vector ethertype = + get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); + // cout << "[p4sec] EtherType" << std::endl; + // hexdump((char*)ðertype[0], ethertype.size()); bool prepend_ipv4 = false; // must pass byte to external function // use 0x54 T as true // use 0x46 F as false - //cout << "[p4sec] prepend IPv4 Header ? " << in_prepend_ipv4_hdr.get_string() << std::endl; + // cout << "[p4sec] prepend IPv4 Header ? " + // << in_prepend_ipv4_hdr.get_string() << std::endl; if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { prepend_ipv4 = true; - //cout << "[p4sec] prepend IPv4 Header" << std::endl; - } - else{ - //cout << "[p4sec] do not prepend IPv4 Header" << std::endl; + // cout << "[p4sec] prepend IPv4 Header" << std::endl; + } else { + // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; } std::vector ipv4_hdr; if (prepend_ipv4) { ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); - //cout << "[p4sec] IPv4 Header" << std::endl; - //hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); + // cout << "[p4sec] IPv4 Header" << std::endl; + // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); } @@ -144,21 +152,24 @@ class ExternCrypt : public ExternType { std::vector integrity_check_value; integrity_check_value.reserve(ICV_SIZE); - protection_function(secure_association_key, secure_channel_identifier, packet_number, destionation_mac_address, source_mac_address, - security_tag, raw_packet_data, secure_data, integrity_check_value); + protection_function(secure_association_key, secure_channel_identifier, + packet_number, destionation_mac_address, + source_mac_address, security_tag, raw_packet_data, + secure_data, integrity_check_value); - //cout << "[p4sec] secure_data" << std::endl; - //hexdump((char*)&secure_data[0], secure_data.size()); + // cout << "[p4sec] secure_data" << std::endl; + // hexdump((char*)&secure_data[0], secure_data.size()); - //cout << "[p4sec] integrity_check_value" << std::endl; - //hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + // cout << "[p4sec] integrity_check_value" << std::endl; + // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); - //replace payload - //first, remove all the data + // replace payload + // first, remove all the data get_packet().remove(get_packet().get_data_size()); - //make room for the ciphertext and write the ciphertext in it + // make room for the ciphertext and write the ciphertext in it char *payload_start = get_packet().prepend( - (unsigned long int) (secure_data.size() + integrity_check_value.size())); + static_cast (secure_data.size() + + integrity_check_value.size())); for (uint i = 0; i < secure_data.size(); i++) { payload_start[i] = secure_data[i]; } @@ -175,30 +186,38 @@ class ExternCrypt : public ExternType { const Data &in_sectag, Data &out_valid, Data &out_ethertype) { - - std::vector secure_association_key = get_char_vector(in_sak.get_string(), SAK_SIZE); - //cout << "[p4sec] secure_association_key" << std::endl; - //hexdump((char*)&secure_association_key[0], secure_association_key.size()); - - std::vector secure_channel_identifier = get_char_vector(in_sci.get_string(), SCI_SIZE); - //cout << "[p4sec] secure_channel_identifier" << std::endl; - //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); - - std::vector packet_number = get_char_vector(in_pn.get_string(), PN_SIZE); - //cout << "[p4sec] packet_number" << std::endl; - //hexdump((char*)&packet_number[0], packet_number.size()); - - std::vector source_mac_address = get_char_vector(in_src_addr.get_string(), ADDR_SIZE); - //cout << "[p4sec] source_mac_address" << std::endl; - //hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - std::vector destionation_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - //cout << "[p4sec] destionation_mac_address" << std::endl; - //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); - - std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); - //cout << "[p4sec] security_tag" << std::endl; - //hexdump((char*)&security_tag[0], security_tag.size()); + std::vector secure_association_key = + get_char_vector(in_sak.get_string(), SAK_SIZE); + // cout << "[p4sec] secure_association_key" << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + std::vector secure_channel_identifier = + get_char_vector(in_sci.get_string(), SCI_SIZE); + // cout << "[p4sec] secure_channel_identifier" << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + std::vector packet_number = get_char_vector( + in_pn.get_string(), PN_SIZE); + // cout << "[p4sec] packet_number" << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + std::vector source_mac_address = get_char_vector( + in_src_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] source_mac_address" << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + std::vector destionation_mac_address = + get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] destionation_mac_address" << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + std::vector security_tag = get_char_vector( + in_sectag.get_string(), SECTAG_SIZE); + // cout << "[p4sec] security_tag" << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); std::vector secure_data; // calculate secure data length @@ -218,41 +237,48 @@ class ExternCrypt : public ExternType { get_packet().data() + get_packet().get_data_size(), integrity_check_value.begin()); - //cout << "[p4sec] secure_data" << std::endl; - //hexdump((char*)&secure_data[0], secure_data.size()); + // cout << "[p4sec] secure_data" << std::endl; + // hexdump((char*)&secure_data[0], secure_data.size()); - //cout << "[p4sec] integrity_check_value" << std::endl; - //hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + // cout << "[p4sec] integrity_check_value" << std::endl; + // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); std::vector user_data; user_data.reserve(secure_data_size); - int valid = validation_function(secure_association_key, secure_channel_identifier, packet_number, destionation_mac_address, source_mac_address, - security_tag, secure_data, integrity_check_value, user_data); - + int valid = validation_function(secure_association_key, + secure_channel_identifier, + packet_number, + destionation_mac_address, + source_mac_address, + security_tag, secure_data, + integrity_check_value, user_data); - //cout << "[p4sec] user_data" << std::endl; - //hexdump((char*)&user_data[0], user_data.size()); + // cout << "[p4sec] user_data" << std::endl; + // hexdump((char*)&user_data[0], user_data.size()); - //cout << "[p4sec] Ethertype" << std::endl; - //hexdump((char*)&user_data[0], ETHERTYPE_SIZE); + // cout << "[p4sec] Ethertype" << std::endl; + // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); - //cout << "[p4sec] decrypted payload" << std::endl; - //hexdump((char*)&user_data[ETHERTYPE_SIZE], user_data.size() - ETHERTYPE_SIZE); + // cout << "[p4sec] decrypted payload" << std::endl; + // hexdump((char*)&user_data[ETHERTYPE_SIZE], + // user_data.size() - ETHERTYPE_SIZE); - //replace payload - //first, remove all the data + // replace payload + // first, remove all the data get_packet().remove(get_packet().get_data_size()); - //make room for the ciphertext and write the ciphertext in it - char *payload_start = get_packet().prepend((unsigned long int) user_data.size()); + // make room for the ciphertext and write the ciphertext in it + char *payload_start = get_packet().prepend(static_cast + user_data.size()); for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { payload_start[i] = user_data[i + ETHERTYPE_SIZE]; } - //copy ethertype from encrypted packet + // copy ethertype from encrypted packet std::stringstream ss_ethertype; - for(uint i=0; iuser_data[i]; std::string ethertype_hexstr = ss_ethertype.str(); out_ethertype.set(ethertype_hexstr); @@ -260,10 +286,10 @@ class ExternCrypt : public ExternType { } std::vector get_char_vector(string str, uint size) { - //string fitted_str = fit_string(str, size); - std::vector vec(size,'\0'); + // string fitted_str = fit_string(str, size); + std::vector vec(size, '\0'); if (str.length() > size) { - //cout << "[p4sec] given string was too long" << std::endl; + // cout << "[p4sec] given string was too long" << std::endl; str.resize(size); } vec.insert(vec.cend()-size, str.begin(), str.end()); @@ -271,191 +297,241 @@ class ExternCrypt : public ExternType { return vec; } - void protection_function(std::vector secure_association_key, // - std::vector secure_channel_identifier, // - std::vector packet_number, // - std::vector destionation_mac_address, // - std::vector source_mac_address, // - std::vector security_tag, // - std::vector user_data, // + void protection_function(std::vector secure_association_key, + std::vector secure_channel_identifier, + std::vector packet_number, + std::vector destionation_mac_address, + std::vector source_mac_address, + std::vector security_tag, + std::vector user_data, std::vector& out_secure_data, std::vector& out_integrity_check_value ) { - //hier evtl assertions fuer die Laenge der Parameter + // hier evtl assertions fuer die Laenge der Parameter // - //std::cout << "[p4sec] secure_association_key size " << secure_association_key.size() << std::endl; - //hexdump((char*)&secure_association_key[0], secure_association_key.size()); + // std::cout << "[p4sec] secure_association_key size " + // << secure_association_key.size() << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); - //std::cout << "[p4sec] secure_channel_identifier size " << secure_channel_identifier.size() << std::endl; - //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); + // std::cout << "[p4sec] secure_channel_identifier size " + // << secure_channel_identifier.size() << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); - //std::cout << "[p4sec] packet_number size " << packet_number.size() << std::endl; - //hexdump((char*)&packet_number[0], packet_number.size()); + // std::cout << "[p4sec] packet_number size " + // << packet_number.size() << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); - //std::cout << "[p4sec] destionation_mac_address size " << destionation_mac_address.size() << std::endl; - //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); + // std::cout << "[p4sec] destionation_mac_address size " + // << destionation_mac_address.size() << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); - //std::cout << "[p4sec] source_mac_address size " << source_mac_address.size() << std::endl; - //hexdump((char*)&source_mac_address[0], source_mac_address.size()); + // std::cout << "[p4sec] source_mac_address size " + // << source_mac_address.size() << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - //std::cout << "[p4sec] security_tag size " << security_tag.size() << std::endl; - //hexdump((char*)&security_tag[0], security_tag.size()); + // std::cout << "[p4sec] security_tag size " << + // security_tag.size() << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); - //std::cout << "[p4sec] user_data size " << user_data.size() << std::endl; - //hexdump((char*)&user_data[0], user_data.size()); + // std::cout << "[p4sec] user_data size " << + // user_data.size() << std::endl; + // hexdump((char*)&user_data[0], user_data.size()); - //terms K, IV, A, P, C, T used in section 2.1 of the GCM specification ( GCM ) as submitted to NIST + // terms K, IV, A, P, C, T used in section 2.1 of the GCM + // specification ( GCM ) as submitted to NIST - //128 bit key + // 128 bit key std::vector K; K.reserve(secure_association_key.size()); - K.insert( K.cend(), secure_association_key.cbegin(), secure_association_key.cend() ); + K.insert(K.cend(), secure_association_key.cbegin(), + secure_association_key.cend()); - //std::cout << "[p4sec] K size " << K.size() << std::endl; - //hexdump((char*)&K[0], K.size()); + // std::cout << "[p4sec] K size " << K.size() << std::endl; + // hexdump((char*)&K[0], K.size()); - //12 byte IV + // 12 byte IV std::vector IV; IV.reserve(secure_channel_identifier.size() + packet_number.size()); - //The 64 most significant bits of the 96-bit IV are the octets of the SCI, encoded as a binary number (9.1). - IV.insert( IV.cend(), secure_channel_identifier.cbegin(), secure_channel_identifier.cend() ); - //The 32 least significant bits of the 96-bit IV are the octets of the PN, encoded as a binary number - IV.insert( IV.cend(), packet_number.cbegin(), packet_number.cend() ); + // The 64 most significant bits of the 96-bit IV are the octets + // of the SCI, encoded as a binary number (9.1). + IV.insert(IV.cend(), secure_channel_identifier.cbegin(), + secure_channel_identifier.cend()); + // The 32 least significant bits of the 96-bit IV are the octets + // of the PN, encoded as a binary number + IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); - //std::cout << "[p4sec] IV size " << IV.size() << std::endl; - //hexdump((char*)&IV[0], IV.size()); + // std::cout << "[p4sec] IV size " << IV.size() << std::endl; + // hexdump((char*)&IV[0], IV.size()); - //A is the Destination MAC Address, Source MAC Address, and the octets of the SecTAG concatenated in that order + // A is the Destination MAC Address, Source MAC Address, + // and the octets of the SecTAG concatenated in that order std::vector A; - A.reserve(destionation_mac_address.size() + source_mac_address.size() + security_tag.size()); - A.insert( A.cend(), destionation_mac_address.cbegin(), destionation_mac_address.cend() ); - A.insert( A.cend(), source_mac_address.cbegin(), source_mac_address.cend() ); - A.insert( A.cend(), security_tag.cbegin(), security_tag.cend() ); - - //P is the octets of the User Data + A.reserve(destionation_mac_address.size() + + source_mac_address.size() + security_tag.size()); + A.insert(A.cend(), destionation_mac_address.cbegin(), + destionation_mac_address.cend()); + A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); + A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); + + // P is the octets of the User Data std::vector P; P.reserve(user_data.size()); - P.insert( P.cend(), user_data.cbegin(), user_data.cend() ); - + P.insert(P.cend(), user_data.cbegin(), user_data.cend()); out_secure_data.resize(P.size(), '\0'); out_integrity_check_value.resize(16, '\0'); - //std::cout << "[p4sec] out_secure_data size " << out_secure_data.size() << std::endl; - //hexdump((char*)&out_secure_data[0], out_secure_data.size()); + // std::cout << "[p4sec] out_secure_data size " << + // out_secure_data.size() << std::endl; + // hexdump((char*)&out_secure_data[0], out_secure_data.size()); - //std::cout << "[p4sec] out_integrity_check_value size " << out_integrity_check_value.size() << std::endl; - //hexdump((char*)&out_integrity_check_value[0], out_integrity_check_value.size()); + // std::cout << "[p4sec] out_integrity_check_value size " + // << out_integrity_check_value.size() << std::endl; + // hexdump((char*)&out_integrity_check_value[0], + // out_integrity_check_value.size()); - //std::cout << "[p4sec] initilalizing encryption" << std::endl; - int actual_size=0, final_size=0; + // std::cout << "[p4sec] initilalizing encryption" << std::endl; + int actual_size = 0, final_size = 0; EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); // Set the IV length, kann man machen, muss man aber nicht da standard 12 - // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); - //https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode - //To specify any additional authenticated data (AAD) a call to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made with the output parameter out set to NULL + // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); + // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode + // To specify any additional authenticated data (AAD) a call + // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() + // should be made with the output parameter out set to NULL EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); - EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, &P[0], P.size() ); + EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, + &P[0], P.size()); EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); - EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, &out_integrity_check_value[0]); + EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, + &out_integrity_check_value[0]); EVP_CIPHER_CTX_free(e_ctx); } - int validation_function(std::vector secure_association_key, // - std::vector secure_channel_identifier, // - std::vector packet_number, // - std::vector destionation_mac_address, // - std::vector source_mac_address, // - std::vector security_tag, // - std::vector secure_data, // - std::vector integrity_check_value, - std::vector& out_user_data) { - //std::cout << "[p4sec] secure_association_key size " << secure_association_key.size() << std::endl; - //hexdump((char*)&secure_association_key[0], secure_association_key.size()); - - //std::cout << "[p4sec] secure_channel_identifier size " << secure_channel_identifier.size() << std::endl; - //hexdump((char*)&secure_channel_identifier[0], secure_channel_identifier.size()); - - //std::cout << "[p4sec] packet_number size " << packet_number.size() << std::endl; - //hexdump((char*)&packet_number[0], packet_number.size()); - - //std::cout << "[p4sec] destionation_mac_address size " << destionation_mac_address.size() << std::endl; - //hexdump((char*)&destionation_mac_address[0], destionation_mac_address.size()); - - //std::cout << "[p4sec] source_mac_address size " << source_mac_address.size() << std::endl; - //hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - //std::cout << "[p4sec] security_tag size " << security_tag.size() << std::endl; - //hexdump((char*)&security_tag[0], security_tag.size()); - - //std::cout << "[p4sec] secure_data size " << secure_data.size() << std::endl; - //hexdump((char*)&secure_data[0], secure_data.size()); - - //std::cout << "[p4sec] integrity_check_value size " << integrity_check_value.size() << std::endl; - //hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); - - - //terms K, IV, A, P, C, T used in section 2.1 of the GCM specification ( GCM ) as submitted to NIST - - //128 bit key + int validation_function(std::vector secure_association_key, + std::vector secure_channel_identifier, + std::vector packet_number, + std::vector destionation_mac_address, + std::vector source_mac_address, + std::vector security_tag, + std::vector secure_data, + std::vector integrity_check_value, + std::vector& out_user_data) { + // std::cout << "[p4sec] secure_association_key size " + // << secure_association_key.size() << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + // std::cout << "[p4sec] secure_channel_identifier size " + // << secure_channel_identifier.size() << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + // std::cout << "[p4sec] packet_number size " + // << packet_number.size() << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + // std::cout << "[p4sec] destionation_mac_address size " + // << destionation_mac_address.size() << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + // std::cout << "[p4sec] source_mac_address size " + // << source_mac_address.size() << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + // std::cout << "[p4sec] security_tag size " + // << security_tag.size() << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); + + // std::cout << "[p4sec] secure_data size " + // << secure_data.size() << std::endl; + // hexdump((char*)&secure_data[0], secure_data.size()); + + // std::cout << "[p4sec] integrity_check_value size " + // << integrity_check_value.size() << std::endl; + // hexdump((char*)&integrity_check_value[0], + // integrity_check_value.size()); + + + // terms K, IV, A, P, C, T used in section 2.1 of the GCM + // specification ( GCM ) as submitted to NIST + + // 128 bit key std::vector K; K.reserve(secure_association_key.size()); - K.insert( K.cend(), secure_association_key.cbegin(), secure_association_key.cend() ); + K.insert(K.cend(), secure_association_key.cbegin(), + secure_association_key.cend()); - //std::cout << "[p4sec] K size " << K.size() << std::endl; - //hexdump((char*)&K[0], K.size()); + // std::cout << "[p4sec] K size " << K.size() << std::endl; + // hexdump((char*)&K[0], K.size()); - //12 byte IV + / /12 byte IV std::vector IV; IV.reserve(secure_channel_identifier.size() + packet_number.size()); - //The 64 most significant bits of the 96-bit IV are the octets of the SCI, encoded as a binary number (9.1). - IV.insert( IV.cend(), secure_channel_identifier.cbegin(), secure_channel_identifier.cend() ); - //The 32 least significant bits of the 96-bit IV are the octets of the PN, encoded as a binary number - IV.insert( IV.cend(), packet_number.cbegin(), packet_number.cend() ); + // The 64 most significant bits of the 96-bit IV are the octets of + // the SCI, encoded as a binary number (9.1). + IV.insert(IV.cend(), secure_channel_identifier.cbegin(), + secure_channel_identifier.cend()); + // The 32 least significant bits of the 96-bit IV are the octets of + // the PN, encoded as a binary number + IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); - //std::cout << "[p4sec] IV size " << IV.size() << std::endl; - //hexdump((char*)&IV[0], IV.size()); + // std::cout << "[p4sec] IV size " << IV.size() << std::endl; + // hexdump((char*)&IV[0], IV.size()); - //A is the Destination MAC Address, Source MAC Address, and the octets of the SecTAG concatenated in that order + // A is the Destination MAC Address, Source MAC Address, and + // the octets of the SecTAG concatenated in that order std::vector A; - A.reserve(destionation_mac_address.size() + source_mac_address.size() + security_tag.size()); - A.insert( A.cend(), destionation_mac_address.cbegin(), destionation_mac_address.cend() ); - A.insert( A.cend(), source_mac_address.cbegin(), source_mac_address.cend() ); - A.insert( A.cend(), security_tag.cbegin(), security_tag.cend() ); - - //P is the octets of the User Data + A.reserve(destionation_mac_address.size() + + source_mac_address.size() + security_tag.size()); + A.insert(A.cend(), destionation_mac_address.cbegin(), + destionation_mac_address.cend()); + A.insert(A.cend(), source_mac_address.cbegin(), + source_mac_address.cend()); + A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); + + // P is the octets of the User Data std::vector P; P.reserve(secure_data.size()); - P.insert( P.cend(), secure_data.cbegin(), secure_data.cend() ); + P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); out_user_data.resize(P.size(), '\0'); - int actual_size=0, final_size=0; + int actual_size = 0, final_size = 0; EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); - //https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode - //To specify any additional authenticated data (AAD) a call to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made with the output parameter out set to NULL + // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode + // To specify any additional authenticated data (AAD) a call to + // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should + // be made with the output parameter out set to NULL EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); - EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, &P[0], P.size() ); - EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, &integrity_check_value[0]); - int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], &final_size); + EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, + &P[0], P.size() ); + EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, + &integrity_check_value[0]); + int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], + &final_size); - if(result == 1) { - //valid result + if (result == 1) { + // valid result } else { - //decryption failed - //-> abprt/drop packet? + // decryption failed + // -> abprt/drop packet? } - //std::cout << "result of decryption: " << result << std::endl; + // std::cout << "result of decryption: " << result << std::endl; EVP_CIPHER_CTX_free(d_ctx); @@ -463,7 +539,7 @@ class ExternCrypt : public ExternType { return result; } - void hexDump (char *addr, int len) { + void hexDump(char *addr, int len) { int i; unsigned char buff[17]; unsigned char *pc = (unsigned char*)addr; @@ -474,14 +550,14 @@ class ExternCrypt : public ExternType { if ((i % 16) == 0) { // Just don't print ASCII for the zeroth line. if (i != 0) - printf (" %s\n", buff); + printf(" %s\n", buff); // Output the offset. - printf ("[p4sec] %04x ", i); + printf("[p4sec] %04x ", i); } // Now the hex code for the specific character. - printf (" %02x", pc[i]); + printf(" %02x", pc[i]); // And store a printable ASCII character for later. if ((pc[i] < 0x20) || (pc[i] > 0x7e)) @@ -493,20 +569,29 @@ class ExternCrypt : public ExternType { // Pad out last line if not exactly 16 characters. while ((i % 16) != 0) { - printf (" "); + printf(" "); i++; } // And print the final ASCII bit. - printf (" %s\n", buff); + printf(" %s\n", buff); } }; // do not put these inside an anonymous namespace or some compilers may complain BM_REGISTER_EXTERN(ExternCrypt); -BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &); -BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, Data &, Data &); - +BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &); +BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &, Data &, Data &); BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); -BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &); -BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, Data &, Data &); +BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &); +BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &, Data &, Data &); From 284799232748e11a166e5d3f824d8717c9ba39f6 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Fri, 13 Dec 2019 07:13:46 -0500 Subject: [PATCH 03/23] Fix headers and namespace cpplint issues --- targets/simple_switch/externs/crypto/crypto.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/targets/simple_switch/externs/crypto/crypto.cpp b/targets/simple_switch/externs/crypto/crypto.cpp index f2456290b..29052c074 100644 --- a/targets/simple_switch/externs/crypto/crypto.cpp +++ b/targets/simple_switch/externs/crypto/crypto.cpp @@ -25,23 +25,20 @@ #include #include #include - -#include - // needed for externs #include -#include "simple_switch.h" - +#include -#include -#include -#include #include #include #include +#include +#include +#include #include -using namespace bm; +#include "simple_switch.h" + using std::endl; using std::cout; using std::string; From 02c01d5cefc157520c8b8f0fe3da9e2c334447ae Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Fri, 13 Dec 2019 08:35:36 -0500 Subject: [PATCH 04/23] Fix compile issues --- .../simple_switch/externs/crypto/crypto.cpp | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/targets/simple_switch/externs/crypto/crypto.cpp b/targets/simple_switch/externs/crypto/crypto.cpp index 29052c074..6bf969991 100644 --- a/targets/simple_switch/externs/crypto/crypto.cpp +++ b/targets/simple_switch/externs/crypto/crypto.cpp @@ -39,11 +39,22 @@ #include "simple_switch.h" +using namespace bm; using std::endl; using std::cout; using std::string; using std::vector; +#define SAK_SIZE 16 +#define SCI_SIZE 8 +#define PN_SIZE 4 +#define ADDR_SIZE 6 +#define SECTAG_SIZE 16 +#define ICV_SIZE 16 +#define IPV4_HDR_SIZE 20 +#define ETHERTYPE_SIZE 2 + +#define SECURE_DATA_SIZE 123 class ExternCrypt : public ExternType { public: @@ -165,7 +176,7 @@ class ExternCrypt : public ExternType { get_packet().remove(get_packet().get_data_size()); // make room for the ciphertext and write the ciphertext in it char *payload_start = get_packet().prepend( - static_cast (secure_data.size() + + static_cast (secure_data.size() + integrity_check_value.size())); for (uint i = 0; i < secure_data.size(); i++) { payload_start[i] = secure_data[i]; @@ -265,8 +276,9 @@ class ExternCrypt : public ExternType { // first, remove all the data get_packet().remove(get_packet().get_data_size()); // make room for the ciphertext and write the ciphertext in it - char *payload_start = get_packet().prepend(static_cast - user_data.size()); + char *payload_start = get_packet().prepend( + static_cast (secure_data.size() + + user_data.size())); for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { payload_start[i] = user_data[i + ETHERTYPE_SIZE]; } @@ -274,8 +286,8 @@ class ExternCrypt : public ExternType { // copy ethertype from encrypted packet std::stringstream ss_ethertype; for (uint i = 0; i < ETHERTYPE_SIZE; ++i) - ss_ethertype << std::setfill('0') << std::setw(2) - << std::hex << static_castuser_data[i]; + ss_ethertype << std::setfill('0') << std::setw(2) << std::hex + << static_cast(user_data[i]); std::string ethertype_hexstr = ss_ethertype.str(); out_ethertype.set(ethertype_hexstr); @@ -471,7 +483,7 @@ class ExternCrypt : public ExternType { // std::cout << "[p4sec] K size " << K.size() << std::endl; // hexdump((char*)&K[0], K.size()); - / /12 byte IV + // 12 byte IV std::vector IV; IV.reserve(secure_channel_identifier.size() + packet_number.size()); // The 64 most significant bits of the 96-bit IV are the octets of From 4e9d5be51f5c3ae798105f09c358e99403080442 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Fri, 13 Dec 2019 09:29:09 -0500 Subject: [PATCH 05/23] Fix namspace cpplint issue --- targets/simple_switch/externs/crypto/crypto.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/simple_switch/externs/crypto/crypto.cpp b/targets/simple_switch/externs/crypto/crypto.cpp index 6bf969991..5db65e4e0 100644 --- a/targets/simple_switch/externs/crypto/crypto.cpp +++ b/targets/simple_switch/externs/crypto/crypto.cpp @@ -39,7 +39,6 @@ #include "simple_switch.h" -using namespace bm; using std::endl; using std::cout; using std::string; From fc1743424d2344837bd8e9170bd75ce0cb7fde30 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 11:21:32 -0500 Subject: [PATCH 06/23] Complete adding crypto to simple_switch, linking and building; also added README.md file --- targets/simple_switch/Makefile.am | 2 +- .../simple_switch/externs/sym_crypto/READE.md | 46 ++ .../externs/sym_crypto/README.md | 21 + .../externs/{crypto => sym_crypto}/basic.p4 | 0 .../externs/{crypto => sym_crypto}/crypto.cpp | 3 +- .../sym_crypto/diffs-simple_switch.cpp | 604 ++++++++++++++++++ targets/simple_switch/simple_switch.cpp | 579 +++++++++++++++++ 7 files changed, 1253 insertions(+), 2 deletions(-) create mode 100644 targets/simple_switch/externs/sym_crypto/READE.md create mode 100644 targets/simple_switch/externs/sym_crypto/README.md rename targets/simple_switch/externs/{crypto => sym_crypto}/basic.p4 (100%) rename targets/simple_switch/externs/{crypto => sym_crypto}/crypto.cpp (99%) create mode 100644 targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp diff --git a/targets/simple_switch/Makefile.am b/targets/simple_switch/Makefile.am index ee1bc7e09..3e06ae1cf 100644 --- a/targets/simple_switch/Makefile.am +++ b/targets/simple_switch/Makefile.am @@ -33,7 +33,7 @@ $(top_builddir)/src/bm_sim/libbmsim.la \ $(top_builddir)/src/bf_lpm_trie/libbflpmtrie.la \ $(top_builddir)/src/BMI/libbmi.la \ $(top_builddir)/third_party/jsoncpp/libjson.la \ --lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem +-lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -lcrypto -lz libsimpleswitch_runner_la_LIBADD = \ $(PI_LIB) \ diff --git a/targets/simple_switch/externs/sym_crypto/READE.md b/targets/simple_switch/externs/sym_crypto/READE.md new file mode 100644 index 000000000..1f2ccfc95 --- /dev/null +++ b/targets/simple_switch/externs/sym_crypto/READE.md @@ -0,0 +1,46 @@ +# ADD CRYPTO to behavioral-model + +Patch diffs-simple_switch.cpp to your behavioral-model repo + +# LINKING + +When crypto is incorporated in simple_switch.cpp, change the following Makefile.am to link crypto libs. + +diff --git a/targets/simple_switch/Makefile.am b/targets/simple_switch/Makefile.am +index ee1bc7e..3e06ae1 100644 +--- a/targets/simple_switch/Makefile.am ++++ b/targets/simple_switch/Makefile.am +@@ -33,7 +33,7 @@ $(top_builddir)/src/bm_sim/libbmsim.la \ + $(top_builddir)/src/bf_lpm_trie/libbflpmtrie.la \ + $(top_builddir)/src/BMI/libbmi.la \ + $(top_builddir)/third_party/jsoncpp/libjson.la \ +--lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem ++-lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -lcrypto -lz + + libsimpleswitch_runner_la_LIBADD = \ + $(PI_LIB) \ + +# BUILD + +Since targets/simple_switch/Makefile.am is changed, run "./configure" from root diretory +of behavioral-model + +# Compiling basic.p4 + +ARGS are: --emit-externs --p4runtime-file $(basename $@).p4info --p4runtime-format text + +# RUN simple_switch or simple_switch_grpc, TODO + +# P4 CODE + +In basic.p4, see crypt.validate() for decryption. + +Likewise, see crypt.protect() for encryption. + +extern ExternCrypt is also defined in basic.p4. + +Most args to encrypt and decrypt are self-explanatory. Also see this paper: + +https://arxiv.org/abs/1904.07088 + + diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/externs/sym_crypto/README.md new file mode 100644 index 000000000..59077bd80 --- /dev/null +++ b/targets/simple_switch/externs/sym_crypto/README.md @@ -0,0 +1,21 @@ +# ADD CRYPTO to SIMPLE_SWITCH + +Patch diffs-simple_switch.cpp to your behavioral-model repo + +# LINKING + +When crypto is incorporated in simple_switch.cpp, change the following Makefile.am to link crypto libs. + +diff --git a/targets/simple_switch/Makefile.am b/targets/simple_switch/Makefile.am +index ee1bc7e..3e06ae1 100644 +--- a/targets/simple_switch/Makefile.am ++++ b/targets/simple_switch/Makefile.am +@@ -33,7 +33,7 @@ $(top_builddir)/src/bm_sim/libbmsim.la \ + $(top_builddir)/src/bf_lpm_trie/libbflpmtrie.la \ + $(top_builddir)/src/BMI/libbmi.la \ + $(top_builddir)/third_party/jsoncpp/libjson.la \ +--lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem ++-lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -lcrypto -lz + + libsimpleswitch_runner_la_LIBADD = \ + $(PI_LIB) \ diff --git a/targets/simple_switch/externs/crypto/basic.p4 b/targets/simple_switch/externs/sym_crypto/basic.p4 similarity index 100% rename from targets/simple_switch/externs/crypto/basic.p4 rename to targets/simple_switch/externs/sym_crypto/basic.p4 diff --git a/targets/simple_switch/externs/crypto/crypto.cpp b/targets/simple_switch/externs/sym_crypto/crypto.cpp similarity index 99% rename from targets/simple_switch/externs/crypto/crypto.cpp rename to targets/simple_switch/externs/sym_crypto/crypto.cpp index 5db65e4e0..60a16ced5 100644 --- a/targets/simple_switch/externs/crypto/crypto.cpp +++ b/targets/simple_switch/externs/sym_crypto/crypto.cpp @@ -28,12 +28,13 @@ // needed for externs #include #include +#include #include #include #include #include -#include + #include #include diff --git a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp new file mode 100644 index 000000000..d0e28713c --- /dev/null +++ b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp @@ -0,0 +1,604 @@ +diff --git a/targets/simple_switch/simple_switch.cpp b/targets/simple_switch/simple_switch.cpp +index 469933d..9d79d2d 100644 +--- a/targets/simple_switch/simple_switch.cpp ++++ b/targets/simple_switch/simple_switch.cpp +@@ -25,12 +25,23 @@ + + #include + ++// aes stuff ++#include ++#include ++#include ++ ++// needed for externs ++#include ++ + #include + #include + #include + #include + #include + #include ++#include ++#include ++#include + + #include "simple_switch.h" + #include "register_access.h" +@@ -67,6 +78,574 @@ struct bmv2_hash { + REGISTER_HASH(hash_ex); + REGISTER_HASH(bmv2_hash); + ++// using namespace bm; ++using std::endl; ++using std::cout; ++using std::string; ++using std::vector; ++ ++#define SAK_SIZE 16 ++#define SCI_SIZE 8 ++#define PN_SIZE 4 ++#define ADDR_SIZE 6 ++#define SECTAG_SIZE 16 ++#define ICV_SIZE 16 ++#define IPV4_HDR_SIZE 20 ++#define ETHERTYPE_SIZE 2 ++ ++#define SECURE_DATA_SIZE 123 ++ ++namespace bm { ++class ExternCrypt : public ExternType { ++ public: ++ BM_EXTERN_ATTRIBUTES { ++ } ++ ++ void init() override { ++ } ++ void protect(const Data &in_sak, ++ const Data &in_sci, ++ const Data &in_pn, ++ const Data &in_src_addr, ++ const Data &in_dst_addr, ++ const Data &in_sectag, ++ const Data &in_ethertype, ++ const Data &in_prepend_ipv4_hdr, ++ const Data &in_ipv4_hdr) { ++ std::vector secure_association_key = get_char_vector( ++ in_sak.get_string(), SAK_SIZE); ++ // cout << "[p4sec] secure_association_key" << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ std::vector secure_channel_identifier = ++ get_char_vector(in_sci.get_string(), SCI_SIZE); ++ // cout << "[p4sec] secure_channel_identifier" << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ std::vector packet_number = ++ get_char_vector(in_pn.get_string(), PN_SIZE); ++ // cout << "[p4sec] packet_number" << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ std::vector source_mac_address = ++ get_char_vector(in_src_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] source_mac_address" << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ std::vector destionation_mac_address = ++ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] destionation_mac_address" << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ std::vector security_tag = ++ get_char_vector(in_sectag.get_string(), SECTAG_SIZE); ++ // cout << "[p4sec] security_tag" << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ std::vector ethertype = ++ get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); ++ // cout << "[p4sec] EtherType" << std::endl; ++ // hexdump((char*)ðertype[0], ethertype.size()); ++ ++ bool prepend_ipv4 = false; ++ // must pass byte to external function ++ // use 0x54 T as true ++ // use 0x46 F as false ++ // cout << "[p4sec] prepend IPv4 Header ? " ++ // << in_prepend_ipv4_hdr.get_string() << std::endl; ++ if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { ++ prepend_ipv4 = true; ++ // cout << "[p4sec] prepend IPv4 Header" << std::endl; ++ } else { ++ // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; ++ } ++ ++ std::vector ipv4_hdr; ++ if (prepend_ipv4) { ++ ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); ++ // cout << "[p4sec] IPv4 Header" << std::endl; ++ // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); ++ } ++ ++ ++ vector raw_packet_data; ++ // calculate secure data length ++ int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; ++ if (prepend_ipv4) { ++ raw_packet_size += IPV4_HDR_SIZE; ++ } ++ raw_packet_data.resize(raw_packet_size, '\0'); ++ // copy EtherType ++ vector::iterator copy_pointer = raw_packet_data.begin(); ++ std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, ++ copy_pointer); ++ copy_pointer += ETHERTYPE_SIZE; ++ // copy IPv4 Header if necessary ++ if (prepend_ipv4) { ++ std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, ++ copy_pointer); ++ copy_pointer += IPV4_HDR_SIZE; ++ } ++ // copy payload ++ std::copy(get_packet().data(), ++ get_packet().data() + get_packet().get_data_size(), ++ copy_pointer); ++ ++ ++ std::vector secure_data; ++ secure_data.reserve(raw_packet_size); ++ std::vector integrity_check_value; ++ integrity_check_value.reserve(ICV_SIZE); ++ ++ protection_function(secure_association_key, secure_channel_identifier, ++ packet_number, destionation_mac_address, ++ source_mac_address, security_tag, raw_packet_data, ++ secure_data, integrity_check_value); ++ ++ // cout << "[p4sec] secure_data" << std::endl; ++ // hexdump((char*)&secure_data[0], secure_data.size()); ++ ++ // cout << "[p4sec] integrity_check_value" << std::endl; ++ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); ++ ++ // replace payload ++ // first, remove all the data ++ get_packet().remove(get_packet().get_data_size()); ++ // make room for the ciphertext and write the ciphertext in it ++ char *payload_start = get_packet().prepend( ++ static_cast (secure_data.size() + ++ integrity_check_value.size())); ++ for (uint i = 0; i < secure_data.size(); i++) { ++ payload_start[i] = secure_data[i]; ++ } ++ for (uint i = 0; i < integrity_check_value.size(); i++) { ++ payload_start[i + secure_data.size()] = integrity_check_value[i]; ++ } ++ } ++ ++ void validate(const Data &in_sak, ++ const Data &in_sci, ++ const Data &in_pn, ++ const Data &in_src_addr, ++ const Data &in_dst_addr, ++ const Data &in_sectag, ++ Data &out_valid, ++ Data &out_ethertype) { ++ std::vector secure_association_key = ++ get_char_vector(in_sak.get_string(), SAK_SIZE); ++ // cout << "[p4sec] secure_association_key" << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ std::vector secure_channel_identifier = ++ get_char_vector(in_sci.get_string(), SCI_SIZE); ++ // cout << "[p4sec] secure_channel_identifier" << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ std::vector packet_number = get_char_vector( ++ in_pn.get_string(), PN_SIZE); ++ // cout << "[p4sec] packet_number" << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ std::vector source_mac_address = get_char_vector( ++ in_src_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] source_mac_address" << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ std::vector destionation_mac_address = ++ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] destionation_mac_address" << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ std::vector security_tag = get_char_vector( ++ in_sectag.get_string(), SECTAG_SIZE); ++ // cout << "[p4sec] security_tag" << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ std::vector secure_data; ++ // calculate secure data length ++ int secure_data_size = get_packet().get_data_size() - ICV_SIZE; ++ secure_data.resize(secure_data_size, '\0'); ++ ++ std::vector integrity_check_value; ++ integrity_check_value.resize(ICV_SIZE, '\0'); ++ ++ // copy secure data ++ std::copy(get_packet().data(), ++ get_packet().data() + get_packet().get_data_size() - ICV_SIZE, ++ secure_data.begin()); ++ ++ // copy ICV ++ std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, ++ get_packet().data() + get_packet().get_data_size(), ++ integrity_check_value.begin()); ++ ++ // cout << "[p4sec] secure_data" << std::endl; ++ // hexdump((char*)&secure_data[0], secure_data.size()); ++ ++ // cout << "[p4sec] integrity_check_value" << std::endl; ++ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); ++ ++ std::vector user_data; ++ user_data.reserve(secure_data_size); ++ ++ int valid = validation_function(secure_association_key, ++ secure_channel_identifier, ++ packet_number, ++ destionation_mac_address, ++ source_mac_address, ++ security_tag, secure_data, ++ integrity_check_value, user_data); ++ ++ // cout << "[p4sec] user_data" << std::endl; ++ // hexdump((char*)&user_data[0], user_data.size()); ++ ++ // cout << "[p4sec] Ethertype" << std::endl; ++ // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); ++ ++ // cout << "[p4sec] decrypted payload" << std::endl; ++ // hexdump((char*)&user_data[ETHERTYPE_SIZE], ++ // user_data.size() - ETHERTYPE_SIZE); ++ ++ // replace payload ++ // first, remove all the data ++ get_packet().remove(get_packet().get_data_size()); ++ // make room for the ciphertext and write the ciphertext in it ++ char *payload_start = get_packet().prepend( ++ static_cast (secure_data.size() ++ + user_data.size())); ++ for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { ++ payload_start[i] = user_data[i + ETHERTYPE_SIZE]; ++ } ++ ++ // copy ethertype from encrypted packet ++ std::stringstream ss_ethertype; ++ for (uint i = 0; i < ETHERTYPE_SIZE; ++i) ++ ss_ethertype << std::setfill('0') << std::setw(2) << std::hex ++ << static_cast(user_data[i]); ++ std::string ethertype_hexstr = ss_ethertype.str(); ++ ++ out_ethertype.set(ethertype_hexstr); ++ out_valid.set(valid); ++ } ++ ++ std::vector get_char_vector(string str, uint size) { ++ // string fitted_str = fit_string(str, size); ++ std::vector vec(size, '\0'); ++ if (str.length() > size) { ++ // cout << "[p4sec] given string was too long" << std::endl; ++ str.resize(size); ++ } ++ vec.insert(vec.cend()-size, str.begin(), str.end()); ++ ++ return vec; ++ } ++ ++ void protection_function(std::vector secure_association_key, ++ std::vector secure_channel_identifier, ++ std::vector packet_number, ++ std::vector destionation_mac_address, ++ std::vector source_mac_address, ++ std::vector security_tag, ++ std::vector user_data, ++ std::vector& out_secure_data, ++ std::vector& out_integrity_check_value ++ ) { ++ // hier evtl assertions fuer die Laenge der Parameter ++ // ++ // std::cout << "[p4sec] secure_association_key size " ++ // << secure_association_key.size() << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ // std::cout << "[p4sec] secure_channel_identifier size " ++ // << secure_channel_identifier.size() << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ // std::cout << "[p4sec] packet_number size " ++ // << packet_number.size() << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ // std::cout << "[p4sec] destionation_mac_address size " ++ // << destionation_mac_address.size() << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ // std::cout << "[p4sec] source_mac_address size " ++ // << source_mac_address.size() << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ // std::cout << "[p4sec] security_tag size " << ++ // security_tag.size() << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ // std::cout << "[p4sec] user_data size " << ++ // user_data.size() << std::endl; ++ // hexdump((char*)&user_data[0], user_data.size()); ++ ++ ++ // terms K, IV, A, P, C, T used in section 2.1 of the GCM ++ // specification ( GCM ) as submitted to NIST ++ ++ // 128 bit key ++ std::vector K; ++ K.reserve(secure_association_key.size()); ++ K.insert(K.cend(), secure_association_key.cbegin(), ++ secure_association_key.cend()); ++ ++ // std::cout << "[p4sec] K size " << K.size() << std::endl; ++ // hexdump((char*)&K[0], K.size()); ++ ++ // 12 byte IV ++ std::vector IV; ++ IV.reserve(secure_channel_identifier.size() + packet_number.size()); ++ // The 64 most significant bits of the 96-bit IV are the octets ++ // of the SCI, encoded as a binary number (9.1). ++ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), ++ secure_channel_identifier.cend()); ++ // The 32 least significant bits of the 96-bit IV are the octets ++ // of the PN, encoded as a binary number ++ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); ++ ++ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; ++ // hexdump((char*)&IV[0], IV.size()); ++ ++ ++ // A is the Destination MAC Address, Source MAC Address, ++ // and the octets of the SecTAG concatenated in that order ++ std::vector A; ++ A.reserve(destionation_mac_address.size() + ++ source_mac_address.size() + security_tag.size()); ++ A.insert(A.cend(), destionation_mac_address.cbegin(), ++ destionation_mac_address.cend()); ++ A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); ++ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); ++ ++ // P is the octets of the User Data ++ std::vector P; ++ P.reserve(user_data.size()); ++ P.insert(P.cend(), user_data.cbegin(), user_data.cend()); ++ ++ out_secure_data.resize(P.size(), '\0'); ++ out_integrity_check_value.resize(16, '\0'); ++ ++ ++ // std::cout << "[p4sec] out_secure_data size " << ++ // out_secure_data.size() << std::endl; ++ // hexdump((char*)&out_secure_data[0], out_secure_data.size()); ++ ++ // std::cout << "[p4sec] out_integrity_check_value size " ++ // << out_integrity_check_value.size() << std::endl; ++ // hexdump((char*)&out_integrity_check_value[0], ++ // out_integrity_check_value.size()); ++ ++ // std::cout << "[p4sec] initilalizing encryption" << std::endl; ++ int actual_size = 0, final_size = 0; ++ EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); ++ EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); ++ ++ // Set the IV length, kann man machen, muss man aber nicht da standard 12 ++ // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); ++ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode ++ // To specify any additional authenticated data (AAD) a call ++ // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() ++ // should be made with the output parameter out set to NULL ++ EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); ++ EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, ++ &P[0], P.size()); ++ EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); ++ EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, ++ &out_integrity_check_value[0]); ++ EVP_CIPHER_CTX_free(e_ctx); ++ } ++ ++ int validation_function(std::vector secure_association_key, ++ std::vector secure_channel_identifier, ++ std::vector packet_number, ++ std::vector destionation_mac_address, ++ std::vector source_mac_address, ++ std::vector security_tag, ++ std::vector secure_data, ++ std::vector integrity_check_value, ++ std::vector& out_user_data) { ++ // std::cout << "[p4sec] secure_association_key size " ++ // << secure_association_key.size() << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ // std::cout << "[p4sec] secure_channel_identifier size " ++ // << secure_channel_identifier.size() << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ // std::cout << "[p4sec] packet_number size " ++ // << packet_number.size() << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ // std::cout << "[p4sec] destionation_mac_address size " ++ // << destionation_mac_address.size() << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ // std::cout << "[p4sec] source_mac_address size " ++ // << source_mac_address.size() << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ // std::cout << "[p4sec] security_tag size " ++ // << security_tag.size() << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ // std::cout << "[p4sec] secure_data size " ++ // << secure_data.size() << std::endl; ++ // hexdump((char*)&secure_data[0], secure_data.size()); ++ ++ // std::cout << "[p4sec] integrity_check_value size " ++ // << integrity_check_value.size() << std::endl; ++ // hexdump((char*)&integrity_check_value[0], ++ // integrity_check_value.size()); ++ ++ ++ // terms K, IV, A, P, C, T used in section 2.1 of the GCM ++ // specification ( GCM ) as submitted to NIST ++ ++ // 128 bit key ++ std::vector K; ++ K.reserve(secure_association_key.size()); ++ K.insert(K.cend(), secure_association_key.cbegin(), ++ secure_association_key.cend()); ++ ++ // std::cout << "[p4sec] K size " << K.size() << std::endl; ++ // hexdump((char*)&K[0], K.size()); ++ ++ // 12 byte IV ++ std::vector IV; ++ IV.reserve(secure_channel_identifier.size() + packet_number.size()); ++ // The 64 most significant bits of the 96-bit IV are the octets of ++ // the SCI, encoded as a binary number (9.1). ++ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), ++ secure_channel_identifier.cend()); ++ // The 32 least significant bits of the 96-bit IV are the octets of ++ // the PN, encoded as a binary number ++ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); ++ ++ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; ++ // hexdump((char*)&IV[0], IV.size()); ++ ++ ++ // A is the Destination MAC Address, Source MAC Address, and ++ // the octets of the SecTAG concatenated in that order ++ std::vector A; ++ A.reserve(destionation_mac_address.size() + ++ source_mac_address.size() + security_tag.size()); ++ A.insert(A.cend(), destionation_mac_address.cbegin(), ++ destionation_mac_address.cend()); ++ A.insert(A.cend(), source_mac_address.cbegin(), ++ source_mac_address.cend()); ++ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); ++ ++ // P is the octets of the User Data ++ std::vector P; ++ P.reserve(secure_data.size()); ++ P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); ++ ++ out_user_data.resize(P.size(), '\0'); ++ ++ int actual_size = 0, final_size = 0; ++ EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); ++ EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); ++ ++ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode ++ // To specify any additional authenticated data (AAD) a call to ++ // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should ++ // be made with the output parameter out set to NULL ++ EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); ++ ++ EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, ++ &P[0], P.size() ); ++ EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, ++ &integrity_check_value[0]); ++ int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], ++ &final_size); ++ ++ if (result == 1) { ++ // valid result ++ } else { ++ // decryption failed ++ // -> abprt/drop packet? ++ } ++ ++ // std::cout << "result of decryption: " << result << std::endl; ++ ++ ++ EVP_CIPHER_CTX_free(d_ctx); ++ ++ return result; ++ } ++ ++ void hexDump(char *addr, int len) { ++ int i; ++ unsigned char buff[17]; ++ unsigned char *pc = (unsigned char*)addr; ++ // Process every byte in the data. ++ for (i = 0; i < len; i++) { ++ // Multiple of 16 means new line (with line offset). ++ ++ if ((i % 16) == 0) { ++ // Just don't print ASCII for the zeroth line. ++ if (i != 0) ++ printf(" %s\n", buff); ++ ++ // Output the offset. ++ printf("[p4sec] %04x ", i); ++ } ++ ++ // Now the hex code for the specific character. ++ printf(" %02x", pc[i]); ++ ++ // And store a printable ASCII character for later. ++ if ((pc[i] < 0x20) || (pc[i] > 0x7e)) ++ buff[i % 16] = '.'; ++ else ++ buff[i % 16] = pc[i]; ++ buff[(i % 16) + 1] = '\0'; ++ } ++ ++ // Pad out last line if not exactly 16 characters. ++ while ((i % 16) != 0) { ++ printf(" "); ++ i++; ++ } ++ ++ // And print the final ASCII bit. ++ printf(" %s\n", buff); ++ } ++}; ++ ++// do not put these inside an anonymous namespace or some compilers may complain ++BM_REGISTER_EXTERN(ExternCrypt); ++BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &); ++BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, Data &, Data &); ++BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); ++BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &); ++BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &, Data &, Data &); ++} // namespace bm ++ + extern int import_primitives(SimpleSwitch *simple_switch); + + packet_id_t SimpleSwitch::packet_id = 0; + diff --git a/targets/simple_switch/simple_switch.cpp b/targets/simple_switch/simple_switch.cpp index 469933d01..9d79d2dee 100644 --- a/targets/simple_switch/simple_switch.cpp +++ b/targets/simple_switch/simple_switch.cpp @@ -25,12 +25,23 @@ #include +// aes stuff +#include +#include +#include + +// needed for externs +#include + #include #include #include #include #include #include +#include +#include +#include #include "simple_switch.h" #include "register_access.h" @@ -67,6 +78,574 @@ struct bmv2_hash { REGISTER_HASH(hash_ex); REGISTER_HASH(bmv2_hash); +// using namespace bm; +using std::endl; +using std::cout; +using std::string; +using std::vector; + +#define SAK_SIZE 16 +#define SCI_SIZE 8 +#define PN_SIZE 4 +#define ADDR_SIZE 6 +#define SECTAG_SIZE 16 +#define ICV_SIZE 16 +#define IPV4_HDR_SIZE 20 +#define ETHERTYPE_SIZE 2 + +#define SECURE_DATA_SIZE 123 + +namespace bm { +class ExternCrypt : public ExternType { + public: + BM_EXTERN_ATTRIBUTES { + } + + void init() override { + } + void protect(const Data &in_sak, + const Data &in_sci, + const Data &in_pn, + const Data &in_src_addr, + const Data &in_dst_addr, + const Data &in_sectag, + const Data &in_ethertype, + const Data &in_prepend_ipv4_hdr, + const Data &in_ipv4_hdr) { + std::vector secure_association_key = get_char_vector( + in_sak.get_string(), SAK_SIZE); + // cout << "[p4sec] secure_association_key" << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + std::vector secure_channel_identifier = + get_char_vector(in_sci.get_string(), SCI_SIZE); + // cout << "[p4sec] secure_channel_identifier" << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + std::vector packet_number = + get_char_vector(in_pn.get_string(), PN_SIZE); + // cout << "[p4sec] packet_number" << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + std::vector source_mac_address = + get_char_vector(in_src_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] source_mac_address" << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + std::vector destionation_mac_address = + get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] destionation_mac_address" << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + std::vector security_tag = + get_char_vector(in_sectag.get_string(), SECTAG_SIZE); + // cout << "[p4sec] security_tag" << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); + + std::vector ethertype = + get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); + // cout << "[p4sec] EtherType" << std::endl; + // hexdump((char*)ðertype[0], ethertype.size()); + + bool prepend_ipv4 = false; + // must pass byte to external function + // use 0x54 T as true + // use 0x46 F as false + // cout << "[p4sec] prepend IPv4 Header ? " + // << in_prepend_ipv4_hdr.get_string() << std::endl; + if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { + prepend_ipv4 = true; + // cout << "[p4sec] prepend IPv4 Header" << std::endl; + } else { + // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; + } + + std::vector ipv4_hdr; + if (prepend_ipv4) { + ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); + // cout << "[p4sec] IPv4 Header" << std::endl; + // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); + } + + + vector raw_packet_data; + // calculate secure data length + int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; + if (prepend_ipv4) { + raw_packet_size += IPV4_HDR_SIZE; + } + raw_packet_data.resize(raw_packet_size, '\0'); + // copy EtherType + vector::iterator copy_pointer = raw_packet_data.begin(); + std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, + copy_pointer); + copy_pointer += ETHERTYPE_SIZE; + // copy IPv4 Header if necessary + if (prepend_ipv4) { + std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, + copy_pointer); + copy_pointer += IPV4_HDR_SIZE; + } + // copy payload + std::copy(get_packet().data(), + get_packet().data() + get_packet().get_data_size(), + copy_pointer); + + + std::vector secure_data; + secure_data.reserve(raw_packet_size); + std::vector integrity_check_value; + integrity_check_value.reserve(ICV_SIZE); + + protection_function(secure_association_key, secure_channel_identifier, + packet_number, destionation_mac_address, + source_mac_address, security_tag, raw_packet_data, + secure_data, integrity_check_value); + + // cout << "[p4sec] secure_data" << std::endl; + // hexdump((char*)&secure_data[0], secure_data.size()); + + // cout << "[p4sec] integrity_check_value" << std::endl; + // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + + // replace payload + // first, remove all the data + get_packet().remove(get_packet().get_data_size()); + // make room for the ciphertext and write the ciphertext in it + char *payload_start = get_packet().prepend( + static_cast (secure_data.size() + + integrity_check_value.size())); + for (uint i = 0; i < secure_data.size(); i++) { + payload_start[i] = secure_data[i]; + } + for (uint i = 0; i < integrity_check_value.size(); i++) { + payload_start[i + secure_data.size()] = integrity_check_value[i]; + } + } + + void validate(const Data &in_sak, + const Data &in_sci, + const Data &in_pn, + const Data &in_src_addr, + const Data &in_dst_addr, + const Data &in_sectag, + Data &out_valid, + Data &out_ethertype) { + std::vector secure_association_key = + get_char_vector(in_sak.get_string(), SAK_SIZE); + // cout << "[p4sec] secure_association_key" << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + std::vector secure_channel_identifier = + get_char_vector(in_sci.get_string(), SCI_SIZE); + // cout << "[p4sec] secure_channel_identifier" << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + std::vector packet_number = get_char_vector( + in_pn.get_string(), PN_SIZE); + // cout << "[p4sec] packet_number" << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + std::vector source_mac_address = get_char_vector( + in_src_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] source_mac_address" << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + std::vector destionation_mac_address = + get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] destionation_mac_address" << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + std::vector security_tag = get_char_vector( + in_sectag.get_string(), SECTAG_SIZE); + // cout << "[p4sec] security_tag" << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); + + std::vector secure_data; + // calculate secure data length + int secure_data_size = get_packet().get_data_size() - ICV_SIZE; + secure_data.resize(secure_data_size, '\0'); + + std::vector integrity_check_value; + integrity_check_value.resize(ICV_SIZE, '\0'); + + // copy secure data + std::copy(get_packet().data(), + get_packet().data() + get_packet().get_data_size() - ICV_SIZE, + secure_data.begin()); + + // copy ICV + std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, + get_packet().data() + get_packet().get_data_size(), + integrity_check_value.begin()); + + // cout << "[p4sec] secure_data" << std::endl; + // hexdump((char*)&secure_data[0], secure_data.size()); + + // cout << "[p4sec] integrity_check_value" << std::endl; + // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); + + std::vector user_data; + user_data.reserve(secure_data_size); + + int valid = validation_function(secure_association_key, + secure_channel_identifier, + packet_number, + destionation_mac_address, + source_mac_address, + security_tag, secure_data, + integrity_check_value, user_data); + + // cout << "[p4sec] user_data" << std::endl; + // hexdump((char*)&user_data[0], user_data.size()); + + // cout << "[p4sec] Ethertype" << std::endl; + // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); + + // cout << "[p4sec] decrypted payload" << std::endl; + // hexdump((char*)&user_data[ETHERTYPE_SIZE], + // user_data.size() - ETHERTYPE_SIZE); + + // replace payload + // first, remove all the data + get_packet().remove(get_packet().get_data_size()); + // make room for the ciphertext and write the ciphertext in it + char *payload_start = get_packet().prepend( + static_cast (secure_data.size() + + user_data.size())); + for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { + payload_start[i] = user_data[i + ETHERTYPE_SIZE]; + } + + // copy ethertype from encrypted packet + std::stringstream ss_ethertype; + for (uint i = 0; i < ETHERTYPE_SIZE; ++i) + ss_ethertype << std::setfill('0') << std::setw(2) << std::hex + << static_cast(user_data[i]); + std::string ethertype_hexstr = ss_ethertype.str(); + + out_ethertype.set(ethertype_hexstr); + out_valid.set(valid); + } + + std::vector get_char_vector(string str, uint size) { + // string fitted_str = fit_string(str, size); + std::vector vec(size, '\0'); + if (str.length() > size) { + // cout << "[p4sec] given string was too long" << std::endl; + str.resize(size); + } + vec.insert(vec.cend()-size, str.begin(), str.end()); + + return vec; + } + + void protection_function(std::vector secure_association_key, + std::vector secure_channel_identifier, + std::vector packet_number, + std::vector destionation_mac_address, + std::vector source_mac_address, + std::vector security_tag, + std::vector user_data, + std::vector& out_secure_data, + std::vector& out_integrity_check_value + ) { + // hier evtl assertions fuer die Laenge der Parameter + // + // std::cout << "[p4sec] secure_association_key size " + // << secure_association_key.size() << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + // std::cout << "[p4sec] secure_channel_identifier size " + // << secure_channel_identifier.size() << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + // std::cout << "[p4sec] packet_number size " + // << packet_number.size() << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + // std::cout << "[p4sec] destionation_mac_address size " + // << destionation_mac_address.size() << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + // std::cout << "[p4sec] source_mac_address size " + // << source_mac_address.size() << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + // std::cout << "[p4sec] security_tag size " << + // security_tag.size() << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); + + // std::cout << "[p4sec] user_data size " << + // user_data.size() << std::endl; + // hexdump((char*)&user_data[0], user_data.size()); + + + // terms K, IV, A, P, C, T used in section 2.1 of the GCM + // specification ( GCM ) as submitted to NIST + + // 128 bit key + std::vector K; + K.reserve(secure_association_key.size()); + K.insert(K.cend(), secure_association_key.cbegin(), + secure_association_key.cend()); + + // std::cout << "[p4sec] K size " << K.size() << std::endl; + // hexdump((char*)&K[0], K.size()); + + // 12 byte IV + std::vector IV; + IV.reserve(secure_channel_identifier.size() + packet_number.size()); + // The 64 most significant bits of the 96-bit IV are the octets + // of the SCI, encoded as a binary number (9.1). + IV.insert(IV.cend(), secure_channel_identifier.cbegin(), + secure_channel_identifier.cend()); + // The 32 least significant bits of the 96-bit IV are the octets + // of the PN, encoded as a binary number + IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); + + // std::cout << "[p4sec] IV size " << IV.size() << std::endl; + // hexdump((char*)&IV[0], IV.size()); + + + // A is the Destination MAC Address, Source MAC Address, + // and the octets of the SecTAG concatenated in that order + std::vector A; + A.reserve(destionation_mac_address.size() + + source_mac_address.size() + security_tag.size()); + A.insert(A.cend(), destionation_mac_address.cbegin(), + destionation_mac_address.cend()); + A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); + A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); + + // P is the octets of the User Data + std::vector P; + P.reserve(user_data.size()); + P.insert(P.cend(), user_data.cbegin(), user_data.cend()); + + out_secure_data.resize(P.size(), '\0'); + out_integrity_check_value.resize(16, '\0'); + + + // std::cout << "[p4sec] out_secure_data size " << + // out_secure_data.size() << std::endl; + // hexdump((char*)&out_secure_data[0], out_secure_data.size()); + + // std::cout << "[p4sec] out_integrity_check_value size " + // << out_integrity_check_value.size() << std::endl; + // hexdump((char*)&out_integrity_check_value[0], + // out_integrity_check_value.size()); + + // std::cout << "[p4sec] initilalizing encryption" << std::endl; + int actual_size = 0, final_size = 0; + EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); + + // Set the IV length, kann man machen, muss man aber nicht da standard 12 + // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); + // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode + // To specify any additional authenticated data (AAD) a call + // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() + // should be made with the output parameter out set to NULL + EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); + EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, + &P[0], P.size()); + EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); + EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, + &out_integrity_check_value[0]); + EVP_CIPHER_CTX_free(e_ctx); + } + + int validation_function(std::vector secure_association_key, + std::vector secure_channel_identifier, + std::vector packet_number, + std::vector destionation_mac_address, + std::vector source_mac_address, + std::vector security_tag, + std::vector secure_data, + std::vector integrity_check_value, + std::vector& out_user_data) { + // std::cout << "[p4sec] secure_association_key size " + // << secure_association_key.size() << std::endl; + // hexdump((char*)&secure_association_key[0], + // secure_association_key.size()); + + // std::cout << "[p4sec] secure_channel_identifier size " + // << secure_channel_identifier.size() << std::endl; + // hexdump((char*)&secure_channel_identifier[0], + // secure_channel_identifier.size()); + + // std::cout << "[p4sec] packet_number size " + // << packet_number.size() << std::endl; + // hexdump((char*)&packet_number[0], packet_number.size()); + + // std::cout << "[p4sec] destionation_mac_address size " + // << destionation_mac_address.size() << std::endl; + // hexdump((char*)&destionation_mac_address[0], + // destionation_mac_address.size()); + + // std::cout << "[p4sec] source_mac_address size " + // << source_mac_address.size() << std::endl; + // hexdump((char*)&source_mac_address[0], source_mac_address.size()); + + // std::cout << "[p4sec] security_tag size " + // << security_tag.size() << std::endl; + // hexdump((char*)&security_tag[0], security_tag.size()); + + // std::cout << "[p4sec] secure_data size " + // << secure_data.size() << std::endl; + // hexdump((char*)&secure_data[0], secure_data.size()); + + // std::cout << "[p4sec] integrity_check_value size " + // << integrity_check_value.size() << std::endl; + // hexdump((char*)&integrity_check_value[0], + // integrity_check_value.size()); + + + // terms K, IV, A, P, C, T used in section 2.1 of the GCM + // specification ( GCM ) as submitted to NIST + + // 128 bit key + std::vector K; + K.reserve(secure_association_key.size()); + K.insert(K.cend(), secure_association_key.cbegin(), + secure_association_key.cend()); + + // std::cout << "[p4sec] K size " << K.size() << std::endl; + // hexdump((char*)&K[0], K.size()); + + // 12 byte IV + std::vector IV; + IV.reserve(secure_channel_identifier.size() + packet_number.size()); + // The 64 most significant bits of the 96-bit IV are the octets of + // the SCI, encoded as a binary number (9.1). + IV.insert(IV.cend(), secure_channel_identifier.cbegin(), + secure_channel_identifier.cend()); + // The 32 least significant bits of the 96-bit IV are the octets of + // the PN, encoded as a binary number + IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); + + // std::cout << "[p4sec] IV size " << IV.size() << std::endl; + // hexdump((char*)&IV[0], IV.size()); + + + // A is the Destination MAC Address, Source MAC Address, and + // the octets of the SecTAG concatenated in that order + std::vector A; + A.reserve(destionation_mac_address.size() + + source_mac_address.size() + security_tag.size()); + A.insert(A.cend(), destionation_mac_address.cbegin(), + destionation_mac_address.cend()); + A.insert(A.cend(), source_mac_address.cbegin(), + source_mac_address.cend()); + A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); + + // P is the octets of the User Data + std::vector P; + P.reserve(secure_data.size()); + P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); + + out_user_data.resize(P.size(), '\0'); + + int actual_size = 0, final_size = 0; + EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); + + // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode + // To specify any additional authenticated data (AAD) a call to + // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should + // be made with the output parameter out set to NULL + EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); + + EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, + &P[0], P.size() ); + EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, + &integrity_check_value[0]); + int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], + &final_size); + + if (result == 1) { + // valid result + } else { + // decryption failed + // -> abprt/drop packet? + } + + // std::cout << "result of decryption: " << result << std::endl; + + + EVP_CIPHER_CTX_free(d_ctx); + + return result; + } + + void hexDump(char *addr, int len) { + int i; + unsigned char buff[17]; + unsigned char *pc = (unsigned char*)addr; + // Process every byte in the data. + for (i = 0; i < len; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Just don't print ASCII for the zeroth line. + if (i != 0) + printf(" %s\n", buff); + + // Output the offset. + printf("[p4sec] %04x ", i); + } + + // Now the hex code for the specific character. + printf(" %02x", pc[i]); + + // And store a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + while ((i % 16) != 0) { + printf(" "); + i++; + } + + // And print the final ASCII bit. + printf(" %s\n", buff); + } +}; + +// do not put these inside an anonymous namespace or some compilers may complain +BM_REGISTER_EXTERN(ExternCrypt); +BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &); +BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &, Data &, Data &); +BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); +BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &); +BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, + const Data &, const Data &, const Data &, + const Data &, const Data &, Data &, Data &); +} // namespace bm + extern int import_primitives(SimpleSwitch *simple_switch); packet_id_t SimpleSwitch::packet_id = 0; From 7d5a5a985ffc29c5e6ebdace50052ee5ddb61af6 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 11:22:13 -0500 Subject: [PATCH 07/23] Complete adding crypto to simple_switch, linking and building; also added README.md file --- .../simple_switch/externs/sym_crypto/READE.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 targets/simple_switch/externs/sym_crypto/READE.md diff --git a/targets/simple_switch/externs/sym_crypto/READE.md b/targets/simple_switch/externs/sym_crypto/READE.md deleted file mode 100644 index 1f2ccfc95..000000000 --- a/targets/simple_switch/externs/sym_crypto/READE.md +++ /dev/null @@ -1,46 +0,0 @@ -# ADD CRYPTO to behavioral-model - -Patch diffs-simple_switch.cpp to your behavioral-model repo - -# LINKING - -When crypto is incorporated in simple_switch.cpp, change the following Makefile.am to link crypto libs. - -diff --git a/targets/simple_switch/Makefile.am b/targets/simple_switch/Makefile.am -index ee1bc7e..3e06ae1 100644 ---- a/targets/simple_switch/Makefile.am -+++ b/targets/simple_switch/Makefile.am -@@ -33,7 +33,7 @@ $(top_builddir)/src/bm_sim/libbmsim.la \ - $(top_builddir)/src/bf_lpm_trie/libbflpmtrie.la \ - $(top_builddir)/src/BMI/libbmi.la \ - $(top_builddir)/third_party/jsoncpp/libjson.la \ ---lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -+-lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -lcrypto -lz - - libsimpleswitch_runner_la_LIBADD = \ - $(PI_LIB) \ - -# BUILD - -Since targets/simple_switch/Makefile.am is changed, run "./configure" from root diretory -of behavioral-model - -# Compiling basic.p4 - -ARGS are: --emit-externs --p4runtime-file $(basename $@).p4info --p4runtime-format text - -# RUN simple_switch or simple_switch_grpc, TODO - -# P4 CODE - -In basic.p4, see crypt.validate() for decryption. - -Likewise, see crypt.protect() for encryption. - -extern ExternCrypt is also defined in basic.p4. - -Most args to encrypt and decrypt are self-explanatory. Also see this paper: - -https://arxiv.org/abs/1904.07088 - - From 30f28794407e3188f546735d58d416bdbad8d846 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 11:38:05 -0500 Subject: [PATCH 08/23] Restore simple_switch and Makefile.am, add to README.md --- targets/simple_switch/Makefile.am | 2 +- .../externs/sym_crypto/README.md | 25 + targets/simple_switch/simple_switch.cpp | 579 ------------------ 3 files changed, 26 insertions(+), 580 deletions(-) diff --git a/targets/simple_switch/Makefile.am b/targets/simple_switch/Makefile.am index 3e06ae1cf..ee1bc7e09 100644 --- a/targets/simple_switch/Makefile.am +++ b/targets/simple_switch/Makefile.am @@ -33,7 +33,7 @@ $(top_builddir)/src/bm_sim/libbmsim.la \ $(top_builddir)/src/bf_lpm_trie/libbflpmtrie.la \ $(top_builddir)/src/BMI/libbmi.la \ $(top_builddir)/third_party/jsoncpp/libjson.la \ --lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -lcrypto -lz +-lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem libsimpleswitch_runner_la_LIBADD = \ $(PI_LIB) \ diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/externs/sym_crypto/README.md index 59077bd80..f59a045f9 100644 --- a/targets/simple_switch/externs/sym_crypto/README.md +++ b/targets/simple_switch/externs/sym_crypto/README.md @@ -19,3 +19,28 @@ index ee1bc7e..3e06ae1 100644 libsimpleswitch_runner_la_LIBADD = \ $(PI_LIB) \ + +# BUILD + +Since Makefile.am is changed, run "./configure" from root directory of behavioral-model. + +# P4 CODE + +See basic.p4. + +1. crypt.validate() is decryption. + +2. crypt.protect() is encryption. + +3. See extern ExternCrypt definition in the same file. + +4. Args to validate() and protect can be understood from P4 code and also this + paper: https://arxiv.org/abs/1904.07088 + +# COMPILING P4 CODE + +Use following args with p4c-bm2-ss + +--emit-externs --p4runtime-file $(basename $@).p4info --p4runtime-format text + +# HOW to run simple_switch/simple_switch_grpc is TODO diff --git a/targets/simple_switch/simple_switch.cpp b/targets/simple_switch/simple_switch.cpp index 9d79d2dee..469933d01 100644 --- a/targets/simple_switch/simple_switch.cpp +++ b/targets/simple_switch/simple_switch.cpp @@ -25,23 +25,12 @@ #include -// aes stuff -#include -#include -#include - -// needed for externs -#include - #include #include #include #include #include #include -#include -#include -#include #include "simple_switch.h" #include "register_access.h" @@ -78,574 +67,6 @@ struct bmv2_hash { REGISTER_HASH(hash_ex); REGISTER_HASH(bmv2_hash); -// using namespace bm; -using std::endl; -using std::cout; -using std::string; -using std::vector; - -#define SAK_SIZE 16 -#define SCI_SIZE 8 -#define PN_SIZE 4 -#define ADDR_SIZE 6 -#define SECTAG_SIZE 16 -#define ICV_SIZE 16 -#define IPV4_HDR_SIZE 20 -#define ETHERTYPE_SIZE 2 - -#define SECURE_DATA_SIZE 123 - -namespace bm { -class ExternCrypt : public ExternType { - public: - BM_EXTERN_ATTRIBUTES { - } - - void init() override { - } - void protect(const Data &in_sak, - const Data &in_sci, - const Data &in_pn, - const Data &in_src_addr, - const Data &in_dst_addr, - const Data &in_sectag, - const Data &in_ethertype, - const Data &in_prepend_ipv4_hdr, - const Data &in_ipv4_hdr) { - std::vector secure_association_key = get_char_vector( - in_sak.get_string(), SAK_SIZE); - // cout << "[p4sec] secure_association_key" << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - - std::vector secure_channel_identifier = - get_char_vector(in_sci.get_string(), SCI_SIZE); - // cout << "[p4sec] secure_channel_identifier" << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); - - std::vector packet_number = - get_char_vector(in_pn.get_string(), PN_SIZE); - // cout << "[p4sec] packet_number" << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); - - std::vector source_mac_address = - get_char_vector(in_src_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] source_mac_address" << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - std::vector destionation_mac_address = - get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] destionation_mac_address" << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); - - std::vector security_tag = - get_char_vector(in_sectag.get_string(), SECTAG_SIZE); - // cout << "[p4sec] security_tag" << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); - - std::vector ethertype = - get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); - // cout << "[p4sec] EtherType" << std::endl; - // hexdump((char*)ðertype[0], ethertype.size()); - - bool prepend_ipv4 = false; - // must pass byte to external function - // use 0x54 T as true - // use 0x46 F as false - // cout << "[p4sec] prepend IPv4 Header ? " - // << in_prepend_ipv4_hdr.get_string() << std::endl; - if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { - prepend_ipv4 = true; - // cout << "[p4sec] prepend IPv4 Header" << std::endl; - } else { - // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; - } - - std::vector ipv4_hdr; - if (prepend_ipv4) { - ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); - // cout << "[p4sec] IPv4 Header" << std::endl; - // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); - } - - - vector raw_packet_data; - // calculate secure data length - int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; - if (prepend_ipv4) { - raw_packet_size += IPV4_HDR_SIZE; - } - raw_packet_data.resize(raw_packet_size, '\0'); - // copy EtherType - vector::iterator copy_pointer = raw_packet_data.begin(); - std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, - copy_pointer); - copy_pointer += ETHERTYPE_SIZE; - // copy IPv4 Header if necessary - if (prepend_ipv4) { - std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, - copy_pointer); - copy_pointer += IPV4_HDR_SIZE; - } - // copy payload - std::copy(get_packet().data(), - get_packet().data() + get_packet().get_data_size(), - copy_pointer); - - - std::vector secure_data; - secure_data.reserve(raw_packet_size); - std::vector integrity_check_value; - integrity_check_value.reserve(ICV_SIZE); - - protection_function(secure_association_key, secure_channel_identifier, - packet_number, destionation_mac_address, - source_mac_address, security_tag, raw_packet_data, - secure_data, integrity_check_value); - - // cout << "[p4sec] secure_data" << std::endl; - // hexdump((char*)&secure_data[0], secure_data.size()); - - // cout << "[p4sec] integrity_check_value" << std::endl; - // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); - - // replace payload - // first, remove all the data - get_packet().remove(get_packet().get_data_size()); - // make room for the ciphertext and write the ciphertext in it - char *payload_start = get_packet().prepend( - static_cast (secure_data.size() + - integrity_check_value.size())); - for (uint i = 0; i < secure_data.size(); i++) { - payload_start[i] = secure_data[i]; - } - for (uint i = 0; i < integrity_check_value.size(); i++) { - payload_start[i + secure_data.size()] = integrity_check_value[i]; - } - } - - void validate(const Data &in_sak, - const Data &in_sci, - const Data &in_pn, - const Data &in_src_addr, - const Data &in_dst_addr, - const Data &in_sectag, - Data &out_valid, - Data &out_ethertype) { - std::vector secure_association_key = - get_char_vector(in_sak.get_string(), SAK_SIZE); - // cout << "[p4sec] secure_association_key" << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - - std::vector secure_channel_identifier = - get_char_vector(in_sci.get_string(), SCI_SIZE); - // cout << "[p4sec] secure_channel_identifier" << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); - - std::vector packet_number = get_char_vector( - in_pn.get_string(), PN_SIZE); - // cout << "[p4sec] packet_number" << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); - - std::vector source_mac_address = get_char_vector( - in_src_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] source_mac_address" << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - std::vector destionation_mac_address = - get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] destionation_mac_address" << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); - - std::vector security_tag = get_char_vector( - in_sectag.get_string(), SECTAG_SIZE); - // cout << "[p4sec] security_tag" << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); - - std::vector secure_data; - // calculate secure data length - int secure_data_size = get_packet().get_data_size() - ICV_SIZE; - secure_data.resize(secure_data_size, '\0'); - - std::vector integrity_check_value; - integrity_check_value.resize(ICV_SIZE, '\0'); - - // copy secure data - std::copy(get_packet().data(), - get_packet().data() + get_packet().get_data_size() - ICV_SIZE, - secure_data.begin()); - - // copy ICV - std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, - get_packet().data() + get_packet().get_data_size(), - integrity_check_value.begin()); - - // cout << "[p4sec] secure_data" << std::endl; - // hexdump((char*)&secure_data[0], secure_data.size()); - - // cout << "[p4sec] integrity_check_value" << std::endl; - // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); - - std::vector user_data; - user_data.reserve(secure_data_size); - - int valid = validation_function(secure_association_key, - secure_channel_identifier, - packet_number, - destionation_mac_address, - source_mac_address, - security_tag, secure_data, - integrity_check_value, user_data); - - // cout << "[p4sec] user_data" << std::endl; - // hexdump((char*)&user_data[0], user_data.size()); - - // cout << "[p4sec] Ethertype" << std::endl; - // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); - - // cout << "[p4sec] decrypted payload" << std::endl; - // hexdump((char*)&user_data[ETHERTYPE_SIZE], - // user_data.size() - ETHERTYPE_SIZE); - - // replace payload - // first, remove all the data - get_packet().remove(get_packet().get_data_size()); - // make room for the ciphertext and write the ciphertext in it - char *payload_start = get_packet().prepend( - static_cast (secure_data.size() - + user_data.size())); - for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { - payload_start[i] = user_data[i + ETHERTYPE_SIZE]; - } - - // copy ethertype from encrypted packet - std::stringstream ss_ethertype; - for (uint i = 0; i < ETHERTYPE_SIZE; ++i) - ss_ethertype << std::setfill('0') << std::setw(2) << std::hex - << static_cast(user_data[i]); - std::string ethertype_hexstr = ss_ethertype.str(); - - out_ethertype.set(ethertype_hexstr); - out_valid.set(valid); - } - - std::vector get_char_vector(string str, uint size) { - // string fitted_str = fit_string(str, size); - std::vector vec(size, '\0'); - if (str.length() > size) { - // cout << "[p4sec] given string was too long" << std::endl; - str.resize(size); - } - vec.insert(vec.cend()-size, str.begin(), str.end()); - - return vec; - } - - void protection_function(std::vector secure_association_key, - std::vector secure_channel_identifier, - std::vector packet_number, - std::vector destionation_mac_address, - std::vector source_mac_address, - std::vector security_tag, - std::vector user_data, - std::vector& out_secure_data, - std::vector& out_integrity_check_value - ) { - // hier evtl assertions fuer die Laenge der Parameter - // - // std::cout << "[p4sec] secure_association_key size " - // << secure_association_key.size() << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - - // std::cout << "[p4sec] secure_channel_identifier size " - // << secure_channel_identifier.size() << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); - - // std::cout << "[p4sec] packet_number size " - // << packet_number.size() << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); - - // std::cout << "[p4sec] destionation_mac_address size " - // << destionation_mac_address.size() << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); - - // std::cout << "[p4sec] source_mac_address size " - // << source_mac_address.size() << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - // std::cout << "[p4sec] security_tag size " << - // security_tag.size() << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); - - // std::cout << "[p4sec] user_data size " << - // user_data.size() << std::endl; - // hexdump((char*)&user_data[0], user_data.size()); - - - // terms K, IV, A, P, C, T used in section 2.1 of the GCM - // specification ( GCM ) as submitted to NIST - - // 128 bit key - std::vector K; - K.reserve(secure_association_key.size()); - K.insert(K.cend(), secure_association_key.cbegin(), - secure_association_key.cend()); - - // std::cout << "[p4sec] K size " << K.size() << std::endl; - // hexdump((char*)&K[0], K.size()); - - // 12 byte IV - std::vector IV; - IV.reserve(secure_channel_identifier.size() + packet_number.size()); - // The 64 most significant bits of the 96-bit IV are the octets - // of the SCI, encoded as a binary number (9.1). - IV.insert(IV.cend(), secure_channel_identifier.cbegin(), - secure_channel_identifier.cend()); - // The 32 least significant bits of the 96-bit IV are the octets - // of the PN, encoded as a binary number - IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); - - // std::cout << "[p4sec] IV size " << IV.size() << std::endl; - // hexdump((char*)&IV[0], IV.size()); - - - // A is the Destination MAC Address, Source MAC Address, - // and the octets of the SecTAG concatenated in that order - std::vector A; - A.reserve(destionation_mac_address.size() + - source_mac_address.size() + security_tag.size()); - A.insert(A.cend(), destionation_mac_address.cbegin(), - destionation_mac_address.cend()); - A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); - A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); - - // P is the octets of the User Data - std::vector P; - P.reserve(user_data.size()); - P.insert(P.cend(), user_data.cbegin(), user_data.cend()); - - out_secure_data.resize(P.size(), '\0'); - out_integrity_check_value.resize(16, '\0'); - - - // std::cout << "[p4sec] out_secure_data size " << - // out_secure_data.size() << std::endl; - // hexdump((char*)&out_secure_data[0], out_secure_data.size()); - - // std::cout << "[p4sec] out_integrity_check_value size " - // << out_integrity_check_value.size() << std::endl; - // hexdump((char*)&out_integrity_check_value[0], - // out_integrity_check_value.size()); - - // std::cout << "[p4sec] initilalizing encryption" << std::endl; - int actual_size = 0, final_size = 0; - EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); - - // Set the IV length, kann man machen, muss man aber nicht da standard 12 - // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); - // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode - // To specify any additional authenticated data (AAD) a call - // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() - // should be made with the output parameter out set to NULL - EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); - EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, - &P[0], P.size()); - EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); - EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, - &out_integrity_check_value[0]); - EVP_CIPHER_CTX_free(e_ctx); - } - - int validation_function(std::vector secure_association_key, - std::vector secure_channel_identifier, - std::vector packet_number, - std::vector destionation_mac_address, - std::vector source_mac_address, - std::vector security_tag, - std::vector secure_data, - std::vector integrity_check_value, - std::vector& out_user_data) { - // std::cout << "[p4sec] secure_association_key size " - // << secure_association_key.size() << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - - // std::cout << "[p4sec] secure_channel_identifier size " - // << secure_channel_identifier.size() << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); - - // std::cout << "[p4sec] packet_number size " - // << packet_number.size() << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); - - // std::cout << "[p4sec] destionation_mac_address size " - // << destionation_mac_address.size() << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); - - // std::cout << "[p4sec] source_mac_address size " - // << source_mac_address.size() << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - // std::cout << "[p4sec] security_tag size " - // << security_tag.size() << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); - - // std::cout << "[p4sec] secure_data size " - // << secure_data.size() << std::endl; - // hexdump((char*)&secure_data[0], secure_data.size()); - - // std::cout << "[p4sec] integrity_check_value size " - // << integrity_check_value.size() << std::endl; - // hexdump((char*)&integrity_check_value[0], - // integrity_check_value.size()); - - - // terms K, IV, A, P, C, T used in section 2.1 of the GCM - // specification ( GCM ) as submitted to NIST - - // 128 bit key - std::vector K; - K.reserve(secure_association_key.size()); - K.insert(K.cend(), secure_association_key.cbegin(), - secure_association_key.cend()); - - // std::cout << "[p4sec] K size " << K.size() << std::endl; - // hexdump((char*)&K[0], K.size()); - - // 12 byte IV - std::vector IV; - IV.reserve(secure_channel_identifier.size() + packet_number.size()); - // The 64 most significant bits of the 96-bit IV are the octets of - // the SCI, encoded as a binary number (9.1). - IV.insert(IV.cend(), secure_channel_identifier.cbegin(), - secure_channel_identifier.cend()); - // The 32 least significant bits of the 96-bit IV are the octets of - // the PN, encoded as a binary number - IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); - - // std::cout << "[p4sec] IV size " << IV.size() << std::endl; - // hexdump((char*)&IV[0], IV.size()); - - - // A is the Destination MAC Address, Source MAC Address, and - // the octets of the SecTAG concatenated in that order - std::vector A; - A.reserve(destionation_mac_address.size() + - source_mac_address.size() + security_tag.size()); - A.insert(A.cend(), destionation_mac_address.cbegin(), - destionation_mac_address.cend()); - A.insert(A.cend(), source_mac_address.cbegin(), - source_mac_address.cend()); - A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); - - // P is the octets of the User Data - std::vector P; - P.reserve(secure_data.size()); - P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); - - out_user_data.resize(P.size(), '\0'); - - int actual_size = 0, final_size = 0; - EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); - - // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode - // To specify any additional authenticated data (AAD) a call to - // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should - // be made with the output parameter out set to NULL - EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); - - EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, - &P[0], P.size() ); - EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, - &integrity_check_value[0]); - int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], - &final_size); - - if (result == 1) { - // valid result - } else { - // decryption failed - // -> abprt/drop packet? - } - - // std::cout << "result of decryption: " << result << std::endl; - - - EVP_CIPHER_CTX_free(d_ctx); - - return result; - } - - void hexDump(char *addr, int len) { - int i; - unsigned char buff[17]; - unsigned char *pc = (unsigned char*)addr; - // Process every byte in the data. - for (i = 0; i < len; i++) { - // Multiple of 16 means new line (with line offset). - - if ((i % 16) == 0) { - // Just don't print ASCII for the zeroth line. - if (i != 0) - printf(" %s\n", buff); - - // Output the offset. - printf("[p4sec] %04x ", i); - } - - // Now the hex code for the specific character. - printf(" %02x", pc[i]); - - // And store a printable ASCII character for later. - if ((pc[i] < 0x20) || (pc[i] > 0x7e)) - buff[i % 16] = '.'; - else - buff[i % 16] = pc[i]; - buff[(i % 16) + 1] = '\0'; - } - - // Pad out last line if not exactly 16 characters. - while ((i % 16) != 0) { - printf(" "); - i++; - } - - // And print the final ASCII bit. - printf(" %s\n", buff); - } -}; - -// do not put these inside an anonymous namespace or some compilers may complain -BM_REGISTER_EXTERN(ExternCrypt); -BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, - const Data &, const Data &, const Data &, - const Data &, const Data &, const Data &, - const Data &); -BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, - const Data &, const Data &, const Data &, - const Data &, Data &, Data &); -BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); -BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, - const Data &, const Data &, const Data &, - const Data &, const Data &, const Data &, - const Data &, const Data &); -BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, - const Data &, const Data &, const Data &, - const Data &, const Data &, Data &, Data &); -} // namespace bm - extern int import_primitives(SimpleSwitch *simple_switch); packet_id_t SimpleSwitch::packet_id = 0; From 353b462e44b4a8e120bc78fa76c975bf3502c141 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 12:37:57 -0500 Subject: [PATCH 09/23] Rename diffs file to avoid its lint --- .../sym_crypto/diffs-simple_switch.cpp | 604 ------------------ 1 file changed, 604 deletions(-) delete mode 100644 targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp diff --git a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp deleted file mode 100644 index d0e28713c..000000000 --- a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch.cpp +++ /dev/null @@ -1,604 +0,0 @@ -diff --git a/targets/simple_switch/simple_switch.cpp b/targets/simple_switch/simple_switch.cpp -index 469933d..9d79d2d 100644 ---- a/targets/simple_switch/simple_switch.cpp -+++ b/targets/simple_switch/simple_switch.cpp -@@ -25,12 +25,23 @@ - - #include - -+// aes stuff -+#include -+#include -+#include -+ -+// needed for externs -+#include -+ - #include - #include - #include - #include - #include - #include -+#include -+#include -+#include - - #include "simple_switch.h" - #include "register_access.h" -@@ -67,6 +78,574 @@ struct bmv2_hash { - REGISTER_HASH(hash_ex); - REGISTER_HASH(bmv2_hash); - -+// using namespace bm; -+using std::endl; -+using std::cout; -+using std::string; -+using std::vector; -+ -+#define SAK_SIZE 16 -+#define SCI_SIZE 8 -+#define PN_SIZE 4 -+#define ADDR_SIZE 6 -+#define SECTAG_SIZE 16 -+#define ICV_SIZE 16 -+#define IPV4_HDR_SIZE 20 -+#define ETHERTYPE_SIZE 2 -+ -+#define SECURE_DATA_SIZE 123 -+ -+namespace bm { -+class ExternCrypt : public ExternType { -+ public: -+ BM_EXTERN_ATTRIBUTES { -+ } -+ -+ void init() override { -+ } -+ void protect(const Data &in_sak, -+ const Data &in_sci, -+ const Data &in_pn, -+ const Data &in_src_addr, -+ const Data &in_dst_addr, -+ const Data &in_sectag, -+ const Data &in_ethertype, -+ const Data &in_prepend_ipv4_hdr, -+ const Data &in_ipv4_hdr) { -+ std::vector secure_association_key = get_char_vector( -+ in_sak.get_string(), SAK_SIZE); -+ // cout << "[p4sec] secure_association_key" << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ std::vector secure_channel_identifier = -+ get_char_vector(in_sci.get_string(), SCI_SIZE); -+ // cout << "[p4sec] secure_channel_identifier" << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ std::vector packet_number = -+ get_char_vector(in_pn.get_string(), PN_SIZE); -+ // cout << "[p4sec] packet_number" << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ std::vector source_mac_address = -+ get_char_vector(in_src_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] source_mac_address" << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ std::vector destionation_mac_address = -+ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] destionation_mac_address" << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ std::vector security_tag = -+ get_char_vector(in_sectag.get_string(), SECTAG_SIZE); -+ // cout << "[p4sec] security_tag" << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ std::vector ethertype = -+ get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); -+ // cout << "[p4sec] EtherType" << std::endl; -+ // hexdump((char*)ðertype[0], ethertype.size()); -+ -+ bool prepend_ipv4 = false; -+ // must pass byte to external function -+ // use 0x54 T as true -+ // use 0x46 F as false -+ // cout << "[p4sec] prepend IPv4 Header ? " -+ // << in_prepend_ipv4_hdr.get_string() << std::endl; -+ if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { -+ prepend_ipv4 = true; -+ // cout << "[p4sec] prepend IPv4 Header" << std::endl; -+ } else { -+ // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; -+ } -+ -+ std::vector ipv4_hdr; -+ if (prepend_ipv4) { -+ ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); -+ // cout << "[p4sec] IPv4 Header" << std::endl; -+ // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); -+ } -+ -+ -+ vector raw_packet_data; -+ // calculate secure data length -+ int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; -+ if (prepend_ipv4) { -+ raw_packet_size += IPV4_HDR_SIZE; -+ } -+ raw_packet_data.resize(raw_packet_size, '\0'); -+ // copy EtherType -+ vector::iterator copy_pointer = raw_packet_data.begin(); -+ std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, -+ copy_pointer); -+ copy_pointer += ETHERTYPE_SIZE; -+ // copy IPv4 Header if necessary -+ if (prepend_ipv4) { -+ std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, -+ copy_pointer); -+ copy_pointer += IPV4_HDR_SIZE; -+ } -+ // copy payload -+ std::copy(get_packet().data(), -+ get_packet().data() + get_packet().get_data_size(), -+ copy_pointer); -+ -+ -+ std::vector secure_data; -+ secure_data.reserve(raw_packet_size); -+ std::vector integrity_check_value; -+ integrity_check_value.reserve(ICV_SIZE); -+ -+ protection_function(secure_association_key, secure_channel_identifier, -+ packet_number, destionation_mac_address, -+ source_mac_address, security_tag, raw_packet_data, -+ secure_data, integrity_check_value); -+ -+ // cout << "[p4sec] secure_data" << std::endl; -+ // hexdump((char*)&secure_data[0], secure_data.size()); -+ -+ // cout << "[p4sec] integrity_check_value" << std::endl; -+ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); -+ -+ // replace payload -+ // first, remove all the data -+ get_packet().remove(get_packet().get_data_size()); -+ // make room for the ciphertext and write the ciphertext in it -+ char *payload_start = get_packet().prepend( -+ static_cast (secure_data.size() + -+ integrity_check_value.size())); -+ for (uint i = 0; i < secure_data.size(); i++) { -+ payload_start[i] = secure_data[i]; -+ } -+ for (uint i = 0; i < integrity_check_value.size(); i++) { -+ payload_start[i + secure_data.size()] = integrity_check_value[i]; -+ } -+ } -+ -+ void validate(const Data &in_sak, -+ const Data &in_sci, -+ const Data &in_pn, -+ const Data &in_src_addr, -+ const Data &in_dst_addr, -+ const Data &in_sectag, -+ Data &out_valid, -+ Data &out_ethertype) { -+ std::vector secure_association_key = -+ get_char_vector(in_sak.get_string(), SAK_SIZE); -+ // cout << "[p4sec] secure_association_key" << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ std::vector secure_channel_identifier = -+ get_char_vector(in_sci.get_string(), SCI_SIZE); -+ // cout << "[p4sec] secure_channel_identifier" << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ std::vector packet_number = get_char_vector( -+ in_pn.get_string(), PN_SIZE); -+ // cout << "[p4sec] packet_number" << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ std::vector source_mac_address = get_char_vector( -+ in_src_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] source_mac_address" << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ std::vector destionation_mac_address = -+ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] destionation_mac_address" << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ std::vector security_tag = get_char_vector( -+ in_sectag.get_string(), SECTAG_SIZE); -+ // cout << "[p4sec] security_tag" << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ std::vector secure_data; -+ // calculate secure data length -+ int secure_data_size = get_packet().get_data_size() - ICV_SIZE; -+ secure_data.resize(secure_data_size, '\0'); -+ -+ std::vector integrity_check_value; -+ integrity_check_value.resize(ICV_SIZE, '\0'); -+ -+ // copy secure data -+ std::copy(get_packet().data(), -+ get_packet().data() + get_packet().get_data_size() - ICV_SIZE, -+ secure_data.begin()); -+ -+ // copy ICV -+ std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, -+ get_packet().data() + get_packet().get_data_size(), -+ integrity_check_value.begin()); -+ -+ // cout << "[p4sec] secure_data" << std::endl; -+ // hexdump((char*)&secure_data[0], secure_data.size()); -+ -+ // cout << "[p4sec] integrity_check_value" << std::endl; -+ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); -+ -+ std::vector user_data; -+ user_data.reserve(secure_data_size); -+ -+ int valid = validation_function(secure_association_key, -+ secure_channel_identifier, -+ packet_number, -+ destionation_mac_address, -+ source_mac_address, -+ security_tag, secure_data, -+ integrity_check_value, user_data); -+ -+ // cout << "[p4sec] user_data" << std::endl; -+ // hexdump((char*)&user_data[0], user_data.size()); -+ -+ // cout << "[p4sec] Ethertype" << std::endl; -+ // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); -+ -+ // cout << "[p4sec] decrypted payload" << std::endl; -+ // hexdump((char*)&user_data[ETHERTYPE_SIZE], -+ // user_data.size() - ETHERTYPE_SIZE); -+ -+ // replace payload -+ // first, remove all the data -+ get_packet().remove(get_packet().get_data_size()); -+ // make room for the ciphertext and write the ciphertext in it -+ char *payload_start = get_packet().prepend( -+ static_cast (secure_data.size() -+ + user_data.size())); -+ for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { -+ payload_start[i] = user_data[i + ETHERTYPE_SIZE]; -+ } -+ -+ // copy ethertype from encrypted packet -+ std::stringstream ss_ethertype; -+ for (uint i = 0; i < ETHERTYPE_SIZE; ++i) -+ ss_ethertype << std::setfill('0') << std::setw(2) << std::hex -+ << static_cast(user_data[i]); -+ std::string ethertype_hexstr = ss_ethertype.str(); -+ -+ out_ethertype.set(ethertype_hexstr); -+ out_valid.set(valid); -+ } -+ -+ std::vector get_char_vector(string str, uint size) { -+ // string fitted_str = fit_string(str, size); -+ std::vector vec(size, '\0'); -+ if (str.length() > size) { -+ // cout << "[p4sec] given string was too long" << std::endl; -+ str.resize(size); -+ } -+ vec.insert(vec.cend()-size, str.begin(), str.end()); -+ -+ return vec; -+ } -+ -+ void protection_function(std::vector secure_association_key, -+ std::vector secure_channel_identifier, -+ std::vector packet_number, -+ std::vector destionation_mac_address, -+ std::vector source_mac_address, -+ std::vector security_tag, -+ std::vector user_data, -+ std::vector& out_secure_data, -+ std::vector& out_integrity_check_value -+ ) { -+ // hier evtl assertions fuer die Laenge der Parameter -+ // -+ // std::cout << "[p4sec] secure_association_key size " -+ // << secure_association_key.size() << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ // std::cout << "[p4sec] secure_channel_identifier size " -+ // << secure_channel_identifier.size() << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ // std::cout << "[p4sec] packet_number size " -+ // << packet_number.size() << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ // std::cout << "[p4sec] destionation_mac_address size " -+ // << destionation_mac_address.size() << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ // std::cout << "[p4sec] source_mac_address size " -+ // << source_mac_address.size() << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ // std::cout << "[p4sec] security_tag size " << -+ // security_tag.size() << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ // std::cout << "[p4sec] user_data size " << -+ // user_data.size() << std::endl; -+ // hexdump((char*)&user_data[0], user_data.size()); -+ -+ -+ // terms K, IV, A, P, C, T used in section 2.1 of the GCM -+ // specification ( GCM ) as submitted to NIST -+ -+ // 128 bit key -+ std::vector K; -+ K.reserve(secure_association_key.size()); -+ K.insert(K.cend(), secure_association_key.cbegin(), -+ secure_association_key.cend()); -+ -+ // std::cout << "[p4sec] K size " << K.size() << std::endl; -+ // hexdump((char*)&K[0], K.size()); -+ -+ // 12 byte IV -+ std::vector IV; -+ IV.reserve(secure_channel_identifier.size() + packet_number.size()); -+ // The 64 most significant bits of the 96-bit IV are the octets -+ // of the SCI, encoded as a binary number (9.1). -+ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), -+ secure_channel_identifier.cend()); -+ // The 32 least significant bits of the 96-bit IV are the octets -+ // of the PN, encoded as a binary number -+ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); -+ -+ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; -+ // hexdump((char*)&IV[0], IV.size()); -+ -+ -+ // A is the Destination MAC Address, Source MAC Address, -+ // and the octets of the SecTAG concatenated in that order -+ std::vector A; -+ A.reserve(destionation_mac_address.size() + -+ source_mac_address.size() + security_tag.size()); -+ A.insert(A.cend(), destionation_mac_address.cbegin(), -+ destionation_mac_address.cend()); -+ A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); -+ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); -+ -+ // P is the octets of the User Data -+ std::vector P; -+ P.reserve(user_data.size()); -+ P.insert(P.cend(), user_data.cbegin(), user_data.cend()); -+ -+ out_secure_data.resize(P.size(), '\0'); -+ out_integrity_check_value.resize(16, '\0'); -+ -+ -+ // std::cout << "[p4sec] out_secure_data size " << -+ // out_secure_data.size() << std::endl; -+ // hexdump((char*)&out_secure_data[0], out_secure_data.size()); -+ -+ // std::cout << "[p4sec] out_integrity_check_value size " -+ // << out_integrity_check_value.size() << std::endl; -+ // hexdump((char*)&out_integrity_check_value[0], -+ // out_integrity_check_value.size()); -+ -+ // std::cout << "[p4sec] initilalizing encryption" << std::endl; -+ int actual_size = 0, final_size = 0; -+ EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); -+ EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); -+ -+ // Set the IV length, kann man machen, muss man aber nicht da standard 12 -+ // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); -+ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode -+ // To specify any additional authenticated data (AAD) a call -+ // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() -+ // should be made with the output parameter out set to NULL -+ EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); -+ EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, -+ &P[0], P.size()); -+ EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); -+ EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, -+ &out_integrity_check_value[0]); -+ EVP_CIPHER_CTX_free(e_ctx); -+ } -+ -+ int validation_function(std::vector secure_association_key, -+ std::vector secure_channel_identifier, -+ std::vector packet_number, -+ std::vector destionation_mac_address, -+ std::vector source_mac_address, -+ std::vector security_tag, -+ std::vector secure_data, -+ std::vector integrity_check_value, -+ std::vector& out_user_data) { -+ // std::cout << "[p4sec] secure_association_key size " -+ // << secure_association_key.size() << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ // std::cout << "[p4sec] secure_channel_identifier size " -+ // << secure_channel_identifier.size() << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ // std::cout << "[p4sec] packet_number size " -+ // << packet_number.size() << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ // std::cout << "[p4sec] destionation_mac_address size " -+ // << destionation_mac_address.size() << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ // std::cout << "[p4sec] source_mac_address size " -+ // << source_mac_address.size() << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ // std::cout << "[p4sec] security_tag size " -+ // << security_tag.size() << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ // std::cout << "[p4sec] secure_data size " -+ // << secure_data.size() << std::endl; -+ // hexdump((char*)&secure_data[0], secure_data.size()); -+ -+ // std::cout << "[p4sec] integrity_check_value size " -+ // << integrity_check_value.size() << std::endl; -+ // hexdump((char*)&integrity_check_value[0], -+ // integrity_check_value.size()); -+ -+ -+ // terms K, IV, A, P, C, T used in section 2.1 of the GCM -+ // specification ( GCM ) as submitted to NIST -+ -+ // 128 bit key -+ std::vector K; -+ K.reserve(secure_association_key.size()); -+ K.insert(K.cend(), secure_association_key.cbegin(), -+ secure_association_key.cend()); -+ -+ // std::cout << "[p4sec] K size " << K.size() << std::endl; -+ // hexdump((char*)&K[0], K.size()); -+ -+ // 12 byte IV -+ std::vector IV; -+ IV.reserve(secure_channel_identifier.size() + packet_number.size()); -+ // The 64 most significant bits of the 96-bit IV are the octets of -+ // the SCI, encoded as a binary number (9.1). -+ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), -+ secure_channel_identifier.cend()); -+ // The 32 least significant bits of the 96-bit IV are the octets of -+ // the PN, encoded as a binary number -+ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); -+ -+ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; -+ // hexdump((char*)&IV[0], IV.size()); -+ -+ -+ // A is the Destination MAC Address, Source MAC Address, and -+ // the octets of the SecTAG concatenated in that order -+ std::vector A; -+ A.reserve(destionation_mac_address.size() + -+ source_mac_address.size() + security_tag.size()); -+ A.insert(A.cend(), destionation_mac_address.cbegin(), -+ destionation_mac_address.cend()); -+ A.insert(A.cend(), source_mac_address.cbegin(), -+ source_mac_address.cend()); -+ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); -+ -+ // P is the octets of the User Data -+ std::vector P; -+ P.reserve(secure_data.size()); -+ P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); -+ -+ out_user_data.resize(P.size(), '\0'); -+ -+ int actual_size = 0, final_size = 0; -+ EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); -+ EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); -+ -+ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode -+ // To specify any additional authenticated data (AAD) a call to -+ // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should -+ // be made with the output parameter out set to NULL -+ EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); -+ -+ EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, -+ &P[0], P.size() ); -+ EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, -+ &integrity_check_value[0]); -+ int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], -+ &final_size); -+ -+ if (result == 1) { -+ // valid result -+ } else { -+ // decryption failed -+ // -> abprt/drop packet? -+ } -+ -+ // std::cout << "result of decryption: " << result << std::endl; -+ -+ -+ EVP_CIPHER_CTX_free(d_ctx); -+ -+ return result; -+ } -+ -+ void hexDump(char *addr, int len) { -+ int i; -+ unsigned char buff[17]; -+ unsigned char *pc = (unsigned char*)addr; -+ // Process every byte in the data. -+ for (i = 0; i < len; i++) { -+ // Multiple of 16 means new line (with line offset). -+ -+ if ((i % 16) == 0) { -+ // Just don't print ASCII for the zeroth line. -+ if (i != 0) -+ printf(" %s\n", buff); -+ -+ // Output the offset. -+ printf("[p4sec] %04x ", i); -+ } -+ -+ // Now the hex code for the specific character. -+ printf(" %02x", pc[i]); -+ -+ // And store a printable ASCII character for later. -+ if ((pc[i] < 0x20) || (pc[i] > 0x7e)) -+ buff[i % 16] = '.'; -+ else -+ buff[i % 16] = pc[i]; -+ buff[(i % 16) + 1] = '\0'; -+ } -+ -+ // Pad out last line if not exactly 16 characters. -+ while ((i % 16) != 0) { -+ printf(" "); -+ i++; -+ } -+ -+ // And print the final ASCII bit. -+ printf(" %s\n", buff); -+ } -+}; -+ -+// do not put these inside an anonymous namespace or some compilers may complain -+BM_REGISTER_EXTERN(ExternCrypt); -+BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &); -+BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, Data &, Data &); -+BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); -+BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &); -+BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &, Data &, Data &); -+} // namespace bm -+ - extern int import_primitives(SimpleSwitch *simple_switch); - - packet_id_t SimpleSwitch::packet_id = 0; - From 84a43b56639f6cf4e773a2700f5d973cb43e9bea Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 12:40:20 -0500 Subject: [PATCH 10/23] Add new diffs file --- .../sym_crypto/diffs-simple_switch-cpp | 604 ++++++++++++++++++ 1 file changed, 604 insertions(+) create mode 100644 targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp diff --git a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp new file mode 100644 index 000000000..d0e28713c --- /dev/null +++ b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp @@ -0,0 +1,604 @@ +diff --git a/targets/simple_switch/simple_switch.cpp b/targets/simple_switch/simple_switch.cpp +index 469933d..9d79d2d 100644 +--- a/targets/simple_switch/simple_switch.cpp ++++ b/targets/simple_switch/simple_switch.cpp +@@ -25,12 +25,23 @@ + + #include + ++// aes stuff ++#include ++#include ++#include ++ ++// needed for externs ++#include ++ + #include + #include + #include + #include + #include + #include ++#include ++#include ++#include + + #include "simple_switch.h" + #include "register_access.h" +@@ -67,6 +78,574 @@ struct bmv2_hash { + REGISTER_HASH(hash_ex); + REGISTER_HASH(bmv2_hash); + ++// using namespace bm; ++using std::endl; ++using std::cout; ++using std::string; ++using std::vector; ++ ++#define SAK_SIZE 16 ++#define SCI_SIZE 8 ++#define PN_SIZE 4 ++#define ADDR_SIZE 6 ++#define SECTAG_SIZE 16 ++#define ICV_SIZE 16 ++#define IPV4_HDR_SIZE 20 ++#define ETHERTYPE_SIZE 2 ++ ++#define SECURE_DATA_SIZE 123 ++ ++namespace bm { ++class ExternCrypt : public ExternType { ++ public: ++ BM_EXTERN_ATTRIBUTES { ++ } ++ ++ void init() override { ++ } ++ void protect(const Data &in_sak, ++ const Data &in_sci, ++ const Data &in_pn, ++ const Data &in_src_addr, ++ const Data &in_dst_addr, ++ const Data &in_sectag, ++ const Data &in_ethertype, ++ const Data &in_prepend_ipv4_hdr, ++ const Data &in_ipv4_hdr) { ++ std::vector secure_association_key = get_char_vector( ++ in_sak.get_string(), SAK_SIZE); ++ // cout << "[p4sec] secure_association_key" << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ std::vector secure_channel_identifier = ++ get_char_vector(in_sci.get_string(), SCI_SIZE); ++ // cout << "[p4sec] secure_channel_identifier" << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ std::vector packet_number = ++ get_char_vector(in_pn.get_string(), PN_SIZE); ++ // cout << "[p4sec] packet_number" << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ std::vector source_mac_address = ++ get_char_vector(in_src_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] source_mac_address" << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ std::vector destionation_mac_address = ++ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] destionation_mac_address" << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ std::vector security_tag = ++ get_char_vector(in_sectag.get_string(), SECTAG_SIZE); ++ // cout << "[p4sec] security_tag" << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ std::vector ethertype = ++ get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); ++ // cout << "[p4sec] EtherType" << std::endl; ++ // hexdump((char*)ðertype[0], ethertype.size()); ++ ++ bool prepend_ipv4 = false; ++ // must pass byte to external function ++ // use 0x54 T as true ++ // use 0x46 F as false ++ // cout << "[p4sec] prepend IPv4 Header ? " ++ // << in_prepend_ipv4_hdr.get_string() << std::endl; ++ if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { ++ prepend_ipv4 = true; ++ // cout << "[p4sec] prepend IPv4 Header" << std::endl; ++ } else { ++ // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; ++ } ++ ++ std::vector ipv4_hdr; ++ if (prepend_ipv4) { ++ ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); ++ // cout << "[p4sec] IPv4 Header" << std::endl; ++ // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); ++ } ++ ++ ++ vector raw_packet_data; ++ // calculate secure data length ++ int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; ++ if (prepend_ipv4) { ++ raw_packet_size += IPV4_HDR_SIZE; ++ } ++ raw_packet_data.resize(raw_packet_size, '\0'); ++ // copy EtherType ++ vector::iterator copy_pointer = raw_packet_data.begin(); ++ std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, ++ copy_pointer); ++ copy_pointer += ETHERTYPE_SIZE; ++ // copy IPv4 Header if necessary ++ if (prepend_ipv4) { ++ std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, ++ copy_pointer); ++ copy_pointer += IPV4_HDR_SIZE; ++ } ++ // copy payload ++ std::copy(get_packet().data(), ++ get_packet().data() + get_packet().get_data_size(), ++ copy_pointer); ++ ++ ++ std::vector secure_data; ++ secure_data.reserve(raw_packet_size); ++ std::vector integrity_check_value; ++ integrity_check_value.reserve(ICV_SIZE); ++ ++ protection_function(secure_association_key, secure_channel_identifier, ++ packet_number, destionation_mac_address, ++ source_mac_address, security_tag, raw_packet_data, ++ secure_data, integrity_check_value); ++ ++ // cout << "[p4sec] secure_data" << std::endl; ++ // hexdump((char*)&secure_data[0], secure_data.size()); ++ ++ // cout << "[p4sec] integrity_check_value" << std::endl; ++ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); ++ ++ // replace payload ++ // first, remove all the data ++ get_packet().remove(get_packet().get_data_size()); ++ // make room for the ciphertext and write the ciphertext in it ++ char *payload_start = get_packet().prepend( ++ static_cast (secure_data.size() + ++ integrity_check_value.size())); ++ for (uint i = 0; i < secure_data.size(); i++) { ++ payload_start[i] = secure_data[i]; ++ } ++ for (uint i = 0; i < integrity_check_value.size(); i++) { ++ payload_start[i + secure_data.size()] = integrity_check_value[i]; ++ } ++ } ++ ++ void validate(const Data &in_sak, ++ const Data &in_sci, ++ const Data &in_pn, ++ const Data &in_src_addr, ++ const Data &in_dst_addr, ++ const Data &in_sectag, ++ Data &out_valid, ++ Data &out_ethertype) { ++ std::vector secure_association_key = ++ get_char_vector(in_sak.get_string(), SAK_SIZE); ++ // cout << "[p4sec] secure_association_key" << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ std::vector secure_channel_identifier = ++ get_char_vector(in_sci.get_string(), SCI_SIZE); ++ // cout << "[p4sec] secure_channel_identifier" << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ std::vector packet_number = get_char_vector( ++ in_pn.get_string(), PN_SIZE); ++ // cout << "[p4sec] packet_number" << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ std::vector source_mac_address = get_char_vector( ++ in_src_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] source_mac_address" << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ std::vector destionation_mac_address = ++ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); ++ // cout << "[p4sec] destionation_mac_address" << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ std::vector security_tag = get_char_vector( ++ in_sectag.get_string(), SECTAG_SIZE); ++ // cout << "[p4sec] security_tag" << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ std::vector secure_data; ++ // calculate secure data length ++ int secure_data_size = get_packet().get_data_size() - ICV_SIZE; ++ secure_data.resize(secure_data_size, '\0'); ++ ++ std::vector integrity_check_value; ++ integrity_check_value.resize(ICV_SIZE, '\0'); ++ ++ // copy secure data ++ std::copy(get_packet().data(), ++ get_packet().data() + get_packet().get_data_size() - ICV_SIZE, ++ secure_data.begin()); ++ ++ // copy ICV ++ std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, ++ get_packet().data() + get_packet().get_data_size(), ++ integrity_check_value.begin()); ++ ++ // cout << "[p4sec] secure_data" << std::endl; ++ // hexdump((char*)&secure_data[0], secure_data.size()); ++ ++ // cout << "[p4sec] integrity_check_value" << std::endl; ++ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); ++ ++ std::vector user_data; ++ user_data.reserve(secure_data_size); ++ ++ int valid = validation_function(secure_association_key, ++ secure_channel_identifier, ++ packet_number, ++ destionation_mac_address, ++ source_mac_address, ++ security_tag, secure_data, ++ integrity_check_value, user_data); ++ ++ // cout << "[p4sec] user_data" << std::endl; ++ // hexdump((char*)&user_data[0], user_data.size()); ++ ++ // cout << "[p4sec] Ethertype" << std::endl; ++ // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); ++ ++ // cout << "[p4sec] decrypted payload" << std::endl; ++ // hexdump((char*)&user_data[ETHERTYPE_SIZE], ++ // user_data.size() - ETHERTYPE_SIZE); ++ ++ // replace payload ++ // first, remove all the data ++ get_packet().remove(get_packet().get_data_size()); ++ // make room for the ciphertext and write the ciphertext in it ++ char *payload_start = get_packet().prepend( ++ static_cast (secure_data.size() ++ + user_data.size())); ++ for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { ++ payload_start[i] = user_data[i + ETHERTYPE_SIZE]; ++ } ++ ++ // copy ethertype from encrypted packet ++ std::stringstream ss_ethertype; ++ for (uint i = 0; i < ETHERTYPE_SIZE; ++i) ++ ss_ethertype << std::setfill('0') << std::setw(2) << std::hex ++ << static_cast(user_data[i]); ++ std::string ethertype_hexstr = ss_ethertype.str(); ++ ++ out_ethertype.set(ethertype_hexstr); ++ out_valid.set(valid); ++ } ++ ++ std::vector get_char_vector(string str, uint size) { ++ // string fitted_str = fit_string(str, size); ++ std::vector vec(size, '\0'); ++ if (str.length() > size) { ++ // cout << "[p4sec] given string was too long" << std::endl; ++ str.resize(size); ++ } ++ vec.insert(vec.cend()-size, str.begin(), str.end()); ++ ++ return vec; ++ } ++ ++ void protection_function(std::vector secure_association_key, ++ std::vector secure_channel_identifier, ++ std::vector packet_number, ++ std::vector destionation_mac_address, ++ std::vector source_mac_address, ++ std::vector security_tag, ++ std::vector user_data, ++ std::vector& out_secure_data, ++ std::vector& out_integrity_check_value ++ ) { ++ // hier evtl assertions fuer die Laenge der Parameter ++ // ++ // std::cout << "[p4sec] secure_association_key size " ++ // << secure_association_key.size() << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ // std::cout << "[p4sec] secure_channel_identifier size " ++ // << secure_channel_identifier.size() << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ // std::cout << "[p4sec] packet_number size " ++ // << packet_number.size() << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ // std::cout << "[p4sec] destionation_mac_address size " ++ // << destionation_mac_address.size() << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ // std::cout << "[p4sec] source_mac_address size " ++ // << source_mac_address.size() << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ // std::cout << "[p4sec] security_tag size " << ++ // security_tag.size() << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ // std::cout << "[p4sec] user_data size " << ++ // user_data.size() << std::endl; ++ // hexdump((char*)&user_data[0], user_data.size()); ++ ++ ++ // terms K, IV, A, P, C, T used in section 2.1 of the GCM ++ // specification ( GCM ) as submitted to NIST ++ ++ // 128 bit key ++ std::vector K; ++ K.reserve(secure_association_key.size()); ++ K.insert(K.cend(), secure_association_key.cbegin(), ++ secure_association_key.cend()); ++ ++ // std::cout << "[p4sec] K size " << K.size() << std::endl; ++ // hexdump((char*)&K[0], K.size()); ++ ++ // 12 byte IV ++ std::vector IV; ++ IV.reserve(secure_channel_identifier.size() + packet_number.size()); ++ // The 64 most significant bits of the 96-bit IV are the octets ++ // of the SCI, encoded as a binary number (9.1). ++ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), ++ secure_channel_identifier.cend()); ++ // The 32 least significant bits of the 96-bit IV are the octets ++ // of the PN, encoded as a binary number ++ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); ++ ++ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; ++ // hexdump((char*)&IV[0], IV.size()); ++ ++ ++ // A is the Destination MAC Address, Source MAC Address, ++ // and the octets of the SecTAG concatenated in that order ++ std::vector A; ++ A.reserve(destionation_mac_address.size() + ++ source_mac_address.size() + security_tag.size()); ++ A.insert(A.cend(), destionation_mac_address.cbegin(), ++ destionation_mac_address.cend()); ++ A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); ++ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); ++ ++ // P is the octets of the User Data ++ std::vector P; ++ P.reserve(user_data.size()); ++ P.insert(P.cend(), user_data.cbegin(), user_data.cend()); ++ ++ out_secure_data.resize(P.size(), '\0'); ++ out_integrity_check_value.resize(16, '\0'); ++ ++ ++ // std::cout << "[p4sec] out_secure_data size " << ++ // out_secure_data.size() << std::endl; ++ // hexdump((char*)&out_secure_data[0], out_secure_data.size()); ++ ++ // std::cout << "[p4sec] out_integrity_check_value size " ++ // << out_integrity_check_value.size() << std::endl; ++ // hexdump((char*)&out_integrity_check_value[0], ++ // out_integrity_check_value.size()); ++ ++ // std::cout << "[p4sec] initilalizing encryption" << std::endl; ++ int actual_size = 0, final_size = 0; ++ EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); ++ EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); ++ ++ // Set the IV length, kann man machen, muss man aber nicht da standard 12 ++ // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); ++ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode ++ // To specify any additional authenticated data (AAD) a call ++ // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() ++ // should be made with the output parameter out set to NULL ++ EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); ++ EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, ++ &P[0], P.size()); ++ EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); ++ EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, ++ &out_integrity_check_value[0]); ++ EVP_CIPHER_CTX_free(e_ctx); ++ } ++ ++ int validation_function(std::vector secure_association_key, ++ std::vector secure_channel_identifier, ++ std::vector packet_number, ++ std::vector destionation_mac_address, ++ std::vector source_mac_address, ++ std::vector security_tag, ++ std::vector secure_data, ++ std::vector integrity_check_value, ++ std::vector& out_user_data) { ++ // std::cout << "[p4sec] secure_association_key size " ++ // << secure_association_key.size() << std::endl; ++ // hexdump((char*)&secure_association_key[0], ++ // secure_association_key.size()); ++ ++ // std::cout << "[p4sec] secure_channel_identifier size " ++ // << secure_channel_identifier.size() << std::endl; ++ // hexdump((char*)&secure_channel_identifier[0], ++ // secure_channel_identifier.size()); ++ ++ // std::cout << "[p4sec] packet_number size " ++ // << packet_number.size() << std::endl; ++ // hexdump((char*)&packet_number[0], packet_number.size()); ++ ++ // std::cout << "[p4sec] destionation_mac_address size " ++ // << destionation_mac_address.size() << std::endl; ++ // hexdump((char*)&destionation_mac_address[0], ++ // destionation_mac_address.size()); ++ ++ // std::cout << "[p4sec] source_mac_address size " ++ // << source_mac_address.size() << std::endl; ++ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); ++ ++ // std::cout << "[p4sec] security_tag size " ++ // << security_tag.size() << std::endl; ++ // hexdump((char*)&security_tag[0], security_tag.size()); ++ ++ // std::cout << "[p4sec] secure_data size " ++ // << secure_data.size() << std::endl; ++ // hexdump((char*)&secure_data[0], secure_data.size()); ++ ++ // std::cout << "[p4sec] integrity_check_value size " ++ // << integrity_check_value.size() << std::endl; ++ // hexdump((char*)&integrity_check_value[0], ++ // integrity_check_value.size()); ++ ++ ++ // terms K, IV, A, P, C, T used in section 2.1 of the GCM ++ // specification ( GCM ) as submitted to NIST ++ ++ // 128 bit key ++ std::vector K; ++ K.reserve(secure_association_key.size()); ++ K.insert(K.cend(), secure_association_key.cbegin(), ++ secure_association_key.cend()); ++ ++ // std::cout << "[p4sec] K size " << K.size() << std::endl; ++ // hexdump((char*)&K[0], K.size()); ++ ++ // 12 byte IV ++ std::vector IV; ++ IV.reserve(secure_channel_identifier.size() + packet_number.size()); ++ // The 64 most significant bits of the 96-bit IV are the octets of ++ // the SCI, encoded as a binary number (9.1). ++ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), ++ secure_channel_identifier.cend()); ++ // The 32 least significant bits of the 96-bit IV are the octets of ++ // the PN, encoded as a binary number ++ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); ++ ++ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; ++ // hexdump((char*)&IV[0], IV.size()); ++ ++ ++ // A is the Destination MAC Address, Source MAC Address, and ++ // the octets of the SecTAG concatenated in that order ++ std::vector A; ++ A.reserve(destionation_mac_address.size() + ++ source_mac_address.size() + security_tag.size()); ++ A.insert(A.cend(), destionation_mac_address.cbegin(), ++ destionation_mac_address.cend()); ++ A.insert(A.cend(), source_mac_address.cbegin(), ++ source_mac_address.cend()); ++ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); ++ ++ // P is the octets of the User Data ++ std::vector P; ++ P.reserve(secure_data.size()); ++ P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); ++ ++ out_user_data.resize(P.size(), '\0'); ++ ++ int actual_size = 0, final_size = 0; ++ EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); ++ EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); ++ ++ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode ++ // To specify any additional authenticated data (AAD) a call to ++ // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should ++ // be made with the output parameter out set to NULL ++ EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); ++ ++ EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, ++ &P[0], P.size() ); ++ EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, ++ &integrity_check_value[0]); ++ int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], ++ &final_size); ++ ++ if (result == 1) { ++ // valid result ++ } else { ++ // decryption failed ++ // -> abprt/drop packet? ++ } ++ ++ // std::cout << "result of decryption: " << result << std::endl; ++ ++ ++ EVP_CIPHER_CTX_free(d_ctx); ++ ++ return result; ++ } ++ ++ void hexDump(char *addr, int len) { ++ int i; ++ unsigned char buff[17]; ++ unsigned char *pc = (unsigned char*)addr; ++ // Process every byte in the data. ++ for (i = 0; i < len; i++) { ++ // Multiple of 16 means new line (with line offset). ++ ++ if ((i % 16) == 0) { ++ // Just don't print ASCII for the zeroth line. ++ if (i != 0) ++ printf(" %s\n", buff); ++ ++ // Output the offset. ++ printf("[p4sec] %04x ", i); ++ } ++ ++ // Now the hex code for the specific character. ++ printf(" %02x", pc[i]); ++ ++ // And store a printable ASCII character for later. ++ if ((pc[i] < 0x20) || (pc[i] > 0x7e)) ++ buff[i % 16] = '.'; ++ else ++ buff[i % 16] = pc[i]; ++ buff[(i % 16) + 1] = '\0'; ++ } ++ ++ // Pad out last line if not exactly 16 characters. ++ while ((i % 16) != 0) { ++ printf(" "); ++ i++; ++ } ++ ++ // And print the final ASCII bit. ++ printf(" %s\n", buff); ++ } ++}; ++ ++// do not put these inside an anonymous namespace or some compilers may complain ++BM_REGISTER_EXTERN(ExternCrypt); ++BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &); ++BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, Data &, Data &); ++BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); ++BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &); ++BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, ++ const Data &, const Data &, const Data &, ++ const Data &, const Data &, Data &, Data &); ++} // namespace bm ++ + extern int import_primitives(SimpleSwitch *simple_switch); + + packet_id_t SimpleSwitch::packet_id = 0; + From fb7b8f3da3c627f774d393b2518c4efb234e0fce Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 14:11:18 -0500 Subject: [PATCH 11/23] Fix minor issues --- targets/simple_switch/externs/sym_crypto/README.md | 2 +- targets/simple_switch/externs/sym_crypto/crypto.cpp | 2 ++ .../simple_switch/externs/sym_crypto/diffs-simple_switch-cpp | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/externs/sym_crypto/README.md index f59a045f9..cf13bd712 100644 --- a/targets/simple_switch/externs/sym_crypto/README.md +++ b/targets/simple_switch/externs/sym_crypto/README.md @@ -1,6 +1,6 @@ # ADD CRYPTO to SIMPLE_SWITCH -Patch diffs-simple_switch.cpp to your behavioral-model repo +Patch diffs-simple_switch-cpp to your behavioral-model repo # LINKING diff --git a/targets/simple_switch/externs/sym_crypto/crypto.cpp b/targets/simple_switch/externs/sym_crypto/crypto.cpp index 60a16ced5..d7f9c57f6 100644 --- a/targets/simple_switch/externs/sym_crypto/crypto.cpp +++ b/targets/simple_switch/externs/sym_crypto/crypto.cpp @@ -56,6 +56,7 @@ using std::vector; #define SECURE_DATA_SIZE 123 +namespace bm { class ExternCrypt : public ExternType { public: BM_EXTERN_ATTRIBUTES { @@ -604,3 +605,4 @@ BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, Data &, Data &); +} // namespace bm diff --git a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp index d0e28713c..02aad5b15 100644 --- a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp +++ b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp @@ -30,7 +30,6 @@ index 469933d..9d79d2d 100644 REGISTER_HASH(hash_ex); REGISTER_HASH(bmv2_hash); -+// using namespace bm; +using std::endl; +using std::cout; +using std::string; From e7d89e7d470d64d4c2a2b9e3d2e11deee7d31e2d Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 16:56:30 -0500 Subject: [PATCH 12/23] Fix acsec's old P4 mark_to_drop --- targets/simple_switch/externs/sym_crypto/basic.p4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/simple_switch/externs/sym_crypto/basic.p4 b/targets/simple_switch/externs/sym_crypto/basic.p4 index 3463c6d07..0cac3c13f 100644 --- a/targets/simple_switch/externs/sym_crypto/basic.p4 +++ b/targets/simple_switch/externs/sym_crypto/basic.p4 @@ -182,7 +182,7 @@ control MyIngress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { action drop() { - mark_to_drop(); + mark_to_drop(standard_metadata); } action send_to_controller(bit<16> reason, egressSpec_t port){ From 11f02c9e7a2059210b2eaf86493fb8c0d0efe794 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Mon, 16 Dec 2019 18:15:12 -0500 Subject: [PATCH 13/23] Comment out recirculate after decrypt --- targets/simple_switch/externs/sym_crypto/basic.p4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/simple_switch/externs/sym_crypto/basic.p4 b/targets/simple_switch/externs/sym_crypto/basic.p4 index 0cac3c13f..6df98e4c3 100644 --- a/targets/simple_switch/externs/sym_crypto/basic.p4 +++ b/targets/simple_switch/externs/sym_crypto/basic.p4 @@ -285,7 +285,7 @@ control MyIngress(inout headers hdr, //headers from decrypted payload not parsed -> recirculate packet meta.user_metadata.recirculated = true; - recirculate({meta.intrinsic_metadata, standard_metadata, meta.user_metadata}); +// recirculate({meta.intrinsic_metadata, standard_metadata, meta.user_metadata}); } } From 19656e2acc509fec20931af5a56ff651c3540056 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Wed, 18 Dec 2019 11:20:44 -0500 Subject: [PATCH 14/23] Update README.md now that steps exist how to test crypto extern --- .../externs/sym_crypto/README.md | 45 ++----------------- 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/externs/sym_crypto/README.md index cf13bd712..b4d225508 100644 --- a/targets/simple_switch/externs/sym_crypto/README.md +++ b/targets/simple_switch/externs/sym_crypto/README.md @@ -1,46 +1,7 @@ # ADD CRYPTO to SIMPLE_SWITCH -Patch diffs-simple_switch-cpp to your behavioral-model repo +The extern is testing using this repo: -# LINKING +https://github.com/uni-tue-kn/p4-macsec -When crypto is incorporated in simple_switch.cpp, change the following Makefile.am to link crypto libs. - -diff --git a/targets/simple_switch/Makefile.am b/targets/simple_switch/Makefile.am -index ee1bc7e..3e06ae1 100644 ---- a/targets/simple_switch/Makefile.am -+++ b/targets/simple_switch/Makefile.am -@@ -33,7 +33,7 @@ $(top_builddir)/src/bm_sim/libbmsim.la \ - $(top_builddir)/src/bf_lpm_trie/libbflpmtrie.la \ - $(top_builddir)/src/BMI/libbmi.la \ - $(top_builddir)/third_party/jsoncpp/libjson.la \ ---lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -+-lboost_system $(THRIFT_LIB) -lboost_program_options -lboost_filesystem -lcrypto -lz - - libsimpleswitch_runner_la_LIBADD = \ - $(PI_LIB) \ - -# BUILD - -Since Makefile.am is changed, run "./configure" from root directory of behavioral-model. - -# P4 CODE - -See basic.p4. - -1. crypt.validate() is decryption. - -2. crypt.protect() is encryption. - -3. See extern ExternCrypt definition in the same file. - -4. Args to validate() and protect can be understood from P4 code and also this - paper: https://arxiv.org/abs/1904.07088 - -# COMPILING P4 CODE - -Use following args with p4c-bm2-ss - ---emit-externs --p4runtime-file $(basename $@).p4info --p4runtime-format text - -# HOW to run simple_switch/simple_switch_grpc is TODO +Please see README.md at the repo for steps used to test. From e1fe58c4755a72cb51cffcbf7321c2534bd851cc Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Wed, 18 Dec 2019 12:29:37 -0500 Subject: [PATCH 15/23] delete diffs file and updated README --- .../externs/sym_crypto/README.md | 7 +- .../sym_crypto/diffs-simple_switch-cpp | 603 ------------------ 2 files changed, 6 insertions(+), 604 deletions(-) delete mode 100644 targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/externs/sym_crypto/README.md index b4d225508..ec8a6faeb 100644 --- a/targets/simple_switch/externs/sym_crypto/README.md +++ b/targets/simple_switch/externs/sym_crypto/README.md @@ -1,6 +1,11 @@ # ADD CRYPTO to SIMPLE_SWITCH -The extern is testing using this repo: +For reference, the extern is implemented in crypto.cpp in this directory. +The code is crypto.cpp is also available in the repo URL included below +so that testing can be done using macsec code. + +The extern is testied using a P4 program called basic.p4 available in +the repo below. https://github.com/uni-tue-kn/p4-macsec diff --git a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp b/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp deleted file mode 100644 index 02aad5b15..000000000 --- a/targets/simple_switch/externs/sym_crypto/diffs-simple_switch-cpp +++ /dev/null @@ -1,603 +0,0 @@ -diff --git a/targets/simple_switch/simple_switch.cpp b/targets/simple_switch/simple_switch.cpp -index 469933d..9d79d2d 100644 ---- a/targets/simple_switch/simple_switch.cpp -+++ b/targets/simple_switch/simple_switch.cpp -@@ -25,12 +25,23 @@ - - #include - -+// aes stuff -+#include -+#include -+#include -+ -+// needed for externs -+#include -+ - #include - #include - #include - #include - #include - #include -+#include -+#include -+#include - - #include "simple_switch.h" - #include "register_access.h" -@@ -67,6 +78,574 @@ struct bmv2_hash { - REGISTER_HASH(hash_ex); - REGISTER_HASH(bmv2_hash); - -+using std::endl; -+using std::cout; -+using std::string; -+using std::vector; -+ -+#define SAK_SIZE 16 -+#define SCI_SIZE 8 -+#define PN_SIZE 4 -+#define ADDR_SIZE 6 -+#define SECTAG_SIZE 16 -+#define ICV_SIZE 16 -+#define IPV4_HDR_SIZE 20 -+#define ETHERTYPE_SIZE 2 -+ -+#define SECURE_DATA_SIZE 123 -+ -+namespace bm { -+class ExternCrypt : public ExternType { -+ public: -+ BM_EXTERN_ATTRIBUTES { -+ } -+ -+ void init() override { -+ } -+ void protect(const Data &in_sak, -+ const Data &in_sci, -+ const Data &in_pn, -+ const Data &in_src_addr, -+ const Data &in_dst_addr, -+ const Data &in_sectag, -+ const Data &in_ethertype, -+ const Data &in_prepend_ipv4_hdr, -+ const Data &in_ipv4_hdr) { -+ std::vector secure_association_key = get_char_vector( -+ in_sak.get_string(), SAK_SIZE); -+ // cout << "[p4sec] secure_association_key" << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ std::vector secure_channel_identifier = -+ get_char_vector(in_sci.get_string(), SCI_SIZE); -+ // cout << "[p4sec] secure_channel_identifier" << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ std::vector packet_number = -+ get_char_vector(in_pn.get_string(), PN_SIZE); -+ // cout << "[p4sec] packet_number" << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ std::vector source_mac_address = -+ get_char_vector(in_src_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] source_mac_address" << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ std::vector destionation_mac_address = -+ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] destionation_mac_address" << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ std::vector security_tag = -+ get_char_vector(in_sectag.get_string(), SECTAG_SIZE); -+ // cout << "[p4sec] security_tag" << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ std::vector ethertype = -+ get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); -+ // cout << "[p4sec] EtherType" << std::endl; -+ // hexdump((char*)ðertype[0], ethertype.size()); -+ -+ bool prepend_ipv4 = false; -+ // must pass byte to external function -+ // use 0x54 T as true -+ // use 0x46 F as false -+ // cout << "[p4sec] prepend IPv4 Header ? " -+ // << in_prepend_ipv4_hdr.get_string() << std::endl; -+ if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { -+ prepend_ipv4 = true; -+ // cout << "[p4sec] prepend IPv4 Header" << std::endl; -+ } else { -+ // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; -+ } -+ -+ std::vector ipv4_hdr; -+ if (prepend_ipv4) { -+ ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); -+ // cout << "[p4sec] IPv4 Header" << std::endl; -+ // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); -+ } -+ -+ -+ vector raw_packet_data; -+ // calculate secure data length -+ int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; -+ if (prepend_ipv4) { -+ raw_packet_size += IPV4_HDR_SIZE; -+ } -+ raw_packet_data.resize(raw_packet_size, '\0'); -+ // copy EtherType -+ vector::iterator copy_pointer = raw_packet_data.begin(); -+ std::copy(ethertype.data(), ethertype.data() + ETHERTYPE_SIZE, -+ copy_pointer); -+ copy_pointer += ETHERTYPE_SIZE; -+ // copy IPv4 Header if necessary -+ if (prepend_ipv4) { -+ std::copy(ipv4_hdr.data(), ipv4_hdr.data() + IPV4_HDR_SIZE, -+ copy_pointer); -+ copy_pointer += IPV4_HDR_SIZE; -+ } -+ // copy payload -+ std::copy(get_packet().data(), -+ get_packet().data() + get_packet().get_data_size(), -+ copy_pointer); -+ -+ -+ std::vector secure_data; -+ secure_data.reserve(raw_packet_size); -+ std::vector integrity_check_value; -+ integrity_check_value.reserve(ICV_SIZE); -+ -+ protection_function(secure_association_key, secure_channel_identifier, -+ packet_number, destionation_mac_address, -+ source_mac_address, security_tag, raw_packet_data, -+ secure_data, integrity_check_value); -+ -+ // cout << "[p4sec] secure_data" << std::endl; -+ // hexdump((char*)&secure_data[0], secure_data.size()); -+ -+ // cout << "[p4sec] integrity_check_value" << std::endl; -+ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); -+ -+ // replace payload -+ // first, remove all the data -+ get_packet().remove(get_packet().get_data_size()); -+ // make room for the ciphertext and write the ciphertext in it -+ char *payload_start = get_packet().prepend( -+ static_cast (secure_data.size() + -+ integrity_check_value.size())); -+ for (uint i = 0; i < secure_data.size(); i++) { -+ payload_start[i] = secure_data[i]; -+ } -+ for (uint i = 0; i < integrity_check_value.size(); i++) { -+ payload_start[i + secure_data.size()] = integrity_check_value[i]; -+ } -+ } -+ -+ void validate(const Data &in_sak, -+ const Data &in_sci, -+ const Data &in_pn, -+ const Data &in_src_addr, -+ const Data &in_dst_addr, -+ const Data &in_sectag, -+ Data &out_valid, -+ Data &out_ethertype) { -+ std::vector secure_association_key = -+ get_char_vector(in_sak.get_string(), SAK_SIZE); -+ // cout << "[p4sec] secure_association_key" << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ std::vector secure_channel_identifier = -+ get_char_vector(in_sci.get_string(), SCI_SIZE); -+ // cout << "[p4sec] secure_channel_identifier" << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ std::vector packet_number = get_char_vector( -+ in_pn.get_string(), PN_SIZE); -+ // cout << "[p4sec] packet_number" << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ std::vector source_mac_address = get_char_vector( -+ in_src_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] source_mac_address" << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ std::vector destionation_mac_address = -+ get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); -+ // cout << "[p4sec] destionation_mac_address" << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ std::vector security_tag = get_char_vector( -+ in_sectag.get_string(), SECTAG_SIZE); -+ // cout << "[p4sec] security_tag" << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ std::vector secure_data; -+ // calculate secure data length -+ int secure_data_size = get_packet().get_data_size() - ICV_SIZE; -+ secure_data.resize(secure_data_size, '\0'); -+ -+ std::vector integrity_check_value; -+ integrity_check_value.resize(ICV_SIZE, '\0'); -+ -+ // copy secure data -+ std::copy(get_packet().data(), -+ get_packet().data() + get_packet().get_data_size() - ICV_SIZE, -+ secure_data.begin()); -+ -+ // copy ICV -+ std::copy(get_packet().data() + get_packet().get_data_size() - ICV_SIZE, -+ get_packet().data() + get_packet().get_data_size(), -+ integrity_check_value.begin()); -+ -+ // cout << "[p4sec] secure_data" << std::endl; -+ // hexdump((char*)&secure_data[0], secure_data.size()); -+ -+ // cout << "[p4sec] integrity_check_value" << std::endl; -+ // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); -+ -+ std::vector user_data; -+ user_data.reserve(secure_data_size); -+ -+ int valid = validation_function(secure_association_key, -+ secure_channel_identifier, -+ packet_number, -+ destionation_mac_address, -+ source_mac_address, -+ security_tag, secure_data, -+ integrity_check_value, user_data); -+ -+ // cout << "[p4sec] user_data" << std::endl; -+ // hexdump((char*)&user_data[0], user_data.size()); -+ -+ // cout << "[p4sec] Ethertype" << std::endl; -+ // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); -+ -+ // cout << "[p4sec] decrypted payload" << std::endl; -+ // hexdump((char*)&user_data[ETHERTYPE_SIZE], -+ // user_data.size() - ETHERTYPE_SIZE); -+ -+ // replace payload -+ // first, remove all the data -+ get_packet().remove(get_packet().get_data_size()); -+ // make room for the ciphertext and write the ciphertext in it -+ char *payload_start = get_packet().prepend( -+ static_cast (secure_data.size() -+ + user_data.size())); -+ for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { -+ payload_start[i] = user_data[i + ETHERTYPE_SIZE]; -+ } -+ -+ // copy ethertype from encrypted packet -+ std::stringstream ss_ethertype; -+ for (uint i = 0; i < ETHERTYPE_SIZE; ++i) -+ ss_ethertype << std::setfill('0') << std::setw(2) << std::hex -+ << static_cast(user_data[i]); -+ std::string ethertype_hexstr = ss_ethertype.str(); -+ -+ out_ethertype.set(ethertype_hexstr); -+ out_valid.set(valid); -+ } -+ -+ std::vector get_char_vector(string str, uint size) { -+ // string fitted_str = fit_string(str, size); -+ std::vector vec(size, '\0'); -+ if (str.length() > size) { -+ // cout << "[p4sec] given string was too long" << std::endl; -+ str.resize(size); -+ } -+ vec.insert(vec.cend()-size, str.begin(), str.end()); -+ -+ return vec; -+ } -+ -+ void protection_function(std::vector secure_association_key, -+ std::vector secure_channel_identifier, -+ std::vector packet_number, -+ std::vector destionation_mac_address, -+ std::vector source_mac_address, -+ std::vector security_tag, -+ std::vector user_data, -+ std::vector& out_secure_data, -+ std::vector& out_integrity_check_value -+ ) { -+ // hier evtl assertions fuer die Laenge der Parameter -+ // -+ // std::cout << "[p4sec] secure_association_key size " -+ // << secure_association_key.size() << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ // std::cout << "[p4sec] secure_channel_identifier size " -+ // << secure_channel_identifier.size() << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ // std::cout << "[p4sec] packet_number size " -+ // << packet_number.size() << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ // std::cout << "[p4sec] destionation_mac_address size " -+ // << destionation_mac_address.size() << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ // std::cout << "[p4sec] source_mac_address size " -+ // << source_mac_address.size() << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ // std::cout << "[p4sec] security_tag size " << -+ // security_tag.size() << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ // std::cout << "[p4sec] user_data size " << -+ // user_data.size() << std::endl; -+ // hexdump((char*)&user_data[0], user_data.size()); -+ -+ -+ // terms K, IV, A, P, C, T used in section 2.1 of the GCM -+ // specification ( GCM ) as submitted to NIST -+ -+ // 128 bit key -+ std::vector K; -+ K.reserve(secure_association_key.size()); -+ K.insert(K.cend(), secure_association_key.cbegin(), -+ secure_association_key.cend()); -+ -+ // std::cout << "[p4sec] K size " << K.size() << std::endl; -+ // hexdump((char*)&K[0], K.size()); -+ -+ // 12 byte IV -+ std::vector IV; -+ IV.reserve(secure_channel_identifier.size() + packet_number.size()); -+ // The 64 most significant bits of the 96-bit IV are the octets -+ // of the SCI, encoded as a binary number (9.1). -+ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), -+ secure_channel_identifier.cend()); -+ // The 32 least significant bits of the 96-bit IV are the octets -+ // of the PN, encoded as a binary number -+ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); -+ -+ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; -+ // hexdump((char*)&IV[0], IV.size()); -+ -+ -+ // A is the Destination MAC Address, Source MAC Address, -+ // and the octets of the SecTAG concatenated in that order -+ std::vector A; -+ A.reserve(destionation_mac_address.size() + -+ source_mac_address.size() + security_tag.size()); -+ A.insert(A.cend(), destionation_mac_address.cbegin(), -+ destionation_mac_address.cend()); -+ A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); -+ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); -+ -+ // P is the octets of the User Data -+ std::vector P; -+ P.reserve(user_data.size()); -+ P.insert(P.cend(), user_data.cbegin(), user_data.cend()); -+ -+ out_secure_data.resize(P.size(), '\0'); -+ out_integrity_check_value.resize(16, '\0'); -+ -+ -+ // std::cout << "[p4sec] out_secure_data size " << -+ // out_secure_data.size() << std::endl; -+ // hexdump((char*)&out_secure_data[0], out_secure_data.size()); -+ -+ // std::cout << "[p4sec] out_integrity_check_value size " -+ // << out_integrity_check_value.size() << std::endl; -+ // hexdump((char*)&out_integrity_check_value[0], -+ // out_integrity_check_value.size()); -+ -+ // std::cout << "[p4sec] initilalizing encryption" << std::endl; -+ int actual_size = 0, final_size = 0; -+ EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); -+ EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); -+ -+ // Set the IV length, kann man machen, muss man aber nicht da standard 12 -+ // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); -+ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode -+ // To specify any additional authenticated data (AAD) a call -+ // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() -+ // should be made with the output parameter out set to NULL -+ EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); -+ EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, -+ &P[0], P.size()); -+ EVP_EncryptFinal(e_ctx, &out_secure_data[actual_size], &final_size); -+ EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_GET_TAG, 16, -+ &out_integrity_check_value[0]); -+ EVP_CIPHER_CTX_free(e_ctx); -+ } -+ -+ int validation_function(std::vector secure_association_key, -+ std::vector secure_channel_identifier, -+ std::vector packet_number, -+ std::vector destionation_mac_address, -+ std::vector source_mac_address, -+ std::vector security_tag, -+ std::vector secure_data, -+ std::vector integrity_check_value, -+ std::vector& out_user_data) { -+ // std::cout << "[p4sec] secure_association_key size " -+ // << secure_association_key.size() << std::endl; -+ // hexdump((char*)&secure_association_key[0], -+ // secure_association_key.size()); -+ -+ // std::cout << "[p4sec] secure_channel_identifier size " -+ // << secure_channel_identifier.size() << std::endl; -+ // hexdump((char*)&secure_channel_identifier[0], -+ // secure_channel_identifier.size()); -+ -+ // std::cout << "[p4sec] packet_number size " -+ // << packet_number.size() << std::endl; -+ // hexdump((char*)&packet_number[0], packet_number.size()); -+ -+ // std::cout << "[p4sec] destionation_mac_address size " -+ // << destionation_mac_address.size() << std::endl; -+ // hexdump((char*)&destionation_mac_address[0], -+ // destionation_mac_address.size()); -+ -+ // std::cout << "[p4sec] source_mac_address size " -+ // << source_mac_address.size() << std::endl; -+ // hexdump((char*)&source_mac_address[0], source_mac_address.size()); -+ -+ // std::cout << "[p4sec] security_tag size " -+ // << security_tag.size() << std::endl; -+ // hexdump((char*)&security_tag[0], security_tag.size()); -+ -+ // std::cout << "[p4sec] secure_data size " -+ // << secure_data.size() << std::endl; -+ // hexdump((char*)&secure_data[0], secure_data.size()); -+ -+ // std::cout << "[p4sec] integrity_check_value size " -+ // << integrity_check_value.size() << std::endl; -+ // hexdump((char*)&integrity_check_value[0], -+ // integrity_check_value.size()); -+ -+ -+ // terms K, IV, A, P, C, T used in section 2.1 of the GCM -+ // specification ( GCM ) as submitted to NIST -+ -+ // 128 bit key -+ std::vector K; -+ K.reserve(secure_association_key.size()); -+ K.insert(K.cend(), secure_association_key.cbegin(), -+ secure_association_key.cend()); -+ -+ // std::cout << "[p4sec] K size " << K.size() << std::endl; -+ // hexdump((char*)&K[0], K.size()); -+ -+ // 12 byte IV -+ std::vector IV; -+ IV.reserve(secure_channel_identifier.size() + packet_number.size()); -+ // The 64 most significant bits of the 96-bit IV are the octets of -+ // the SCI, encoded as a binary number (9.1). -+ IV.insert(IV.cend(), secure_channel_identifier.cbegin(), -+ secure_channel_identifier.cend()); -+ // The 32 least significant bits of the 96-bit IV are the octets of -+ // the PN, encoded as a binary number -+ IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); -+ -+ // std::cout << "[p4sec] IV size " << IV.size() << std::endl; -+ // hexdump((char*)&IV[0], IV.size()); -+ -+ -+ // A is the Destination MAC Address, Source MAC Address, and -+ // the octets of the SecTAG concatenated in that order -+ std::vector A; -+ A.reserve(destionation_mac_address.size() + -+ source_mac_address.size() + security_tag.size()); -+ A.insert(A.cend(), destionation_mac_address.cbegin(), -+ destionation_mac_address.cend()); -+ A.insert(A.cend(), source_mac_address.cbegin(), -+ source_mac_address.cend()); -+ A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); -+ -+ // P is the octets of the User Data -+ std::vector P; -+ P.reserve(secure_data.size()); -+ P.insert(P.cend(), secure_data.cbegin(), secure_data.cend()); -+ -+ out_user_data.resize(P.size(), '\0'); -+ -+ int actual_size = 0, final_size = 0; -+ EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new(); -+ EVP_DecryptInit(d_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); -+ -+ // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode -+ // To specify any additional authenticated data (AAD) a call to -+ // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should -+ // be made with the output parameter out set to NULL -+ EVP_DecryptUpdate(d_ctx, NULL, &actual_size, &A[0], A.size()); -+ -+ EVP_DecryptUpdate(d_ctx, &out_user_data[0], &actual_size, -+ &P[0], P.size() ); -+ EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, -+ &integrity_check_value[0]); -+ int result = EVP_DecryptFinal(d_ctx, &out_user_data[actual_size], -+ &final_size); -+ -+ if (result == 1) { -+ // valid result -+ } else { -+ // decryption failed -+ // -> abprt/drop packet? -+ } -+ -+ // std::cout << "result of decryption: " << result << std::endl; -+ -+ -+ EVP_CIPHER_CTX_free(d_ctx); -+ -+ return result; -+ } -+ -+ void hexDump(char *addr, int len) { -+ int i; -+ unsigned char buff[17]; -+ unsigned char *pc = (unsigned char*)addr; -+ // Process every byte in the data. -+ for (i = 0; i < len; i++) { -+ // Multiple of 16 means new line (with line offset). -+ -+ if ((i % 16) == 0) { -+ // Just don't print ASCII for the zeroth line. -+ if (i != 0) -+ printf(" %s\n", buff); -+ -+ // Output the offset. -+ printf("[p4sec] %04x ", i); -+ } -+ -+ // Now the hex code for the specific character. -+ printf(" %02x", pc[i]); -+ -+ // And store a printable ASCII character for later. -+ if ((pc[i] < 0x20) || (pc[i] > 0x7e)) -+ buff[i % 16] = '.'; -+ else -+ buff[i % 16] = pc[i]; -+ buff[(i % 16) + 1] = '\0'; -+ } -+ -+ // Pad out last line if not exactly 16 characters. -+ while ((i % 16) != 0) { -+ printf(" "); -+ i++; -+ } -+ -+ // And print the final ASCII bit. -+ printf(" %s\n", buff); -+ } -+}; -+ -+// do not put these inside an anonymous namespace or some compilers may complain -+BM_REGISTER_EXTERN(ExternCrypt); -+BM_REGISTER_EXTERN_METHOD(ExternCrypt, protect, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &); -+BM_REGISTER_EXTERN_METHOD(ExternCrypt, validate, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, Data &, Data &); -+BM_REGISTER_EXTERN_W_NAME(ext_crypt, ExternCrypt); -+BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, protect, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &); -+BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, -+ const Data &, const Data &, const Data &, -+ const Data &, const Data &, Data &, Data &); -+} // namespace bm -+ - extern int import_primitives(SimpleSwitch *simple_switch); - - packet_id_t SimpleSwitch::packet_id = 0; - From a3c273aed46eeb8cd02a03e17e65f7eff67b95f5 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Wed, 18 Dec 2019 18:45:13 -0500 Subject: [PATCH 16/23] Add more notes to README --- .../externs/sym_crypto/README.md | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/externs/sym_crypto/README.md index ec8a6faeb..b72145c17 100644 --- a/targets/simple_switch/externs/sym_crypto/README.md +++ b/targets/simple_switch/externs/sym_crypto/README.md @@ -1,12 +1,22 @@ # ADD CRYPTO to SIMPLE_SWITCH For reference, the extern is implemented in crypto.cpp in this directory. -The code is crypto.cpp is also available in the repo URL included below -so that testing can be done using macsec code. +This cpp code is to be incorporated in +behavioral-model/targets/simple_switch/simple_switch.cpp -The extern is testied using a P4 program called basic.p4 available in -the repo below. +The code is crypto.cpp is also available in the repo URL included below +so that testing can be done using MACsec (MAC security) code. A +README.md is available at the repo below with steps for how to test +the code. https://github.com/uni-tue-kn/p4-macsec -Please see README.md at the repo for steps used to test. +The extern is defined in the following P4 file. Search for ExternCrypt +for the extern definition. Additionally the extern is used in P4 code +as crypt.validate() which is decryption and crypt.protect() which is +encryption. + +https://github.com/uni-tue-kn/p4-macsec/p4/p4/basic.p4 + +basic.p4 is used to test the cryto extern code with simple_switch. + From d32443ac935dcec4529095edb9cd5ae68da3c12e Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Wed, 18 Dec 2019 19:36:07 -0500 Subject: [PATCH 17/23] Delete basic.p4 since it's pointed to in the repo --- .../simple_switch/externs/sym_crypto/basic.p4 | 453 ------------------ 1 file changed, 453 deletions(-) delete mode 100644 targets/simple_switch/externs/sym_crypto/basic.p4 diff --git a/targets/simple_switch/externs/sym_crypto/basic.p4 b/targets/simple_switch/externs/sym_crypto/basic.p4 deleted file mode 100644 index 6df98e4c3..000000000 --- a/targets/simple_switch/externs/sym_crypto/basic.p4 +++ /dev/null @@ -1,453 +0,0 @@ -/* -*- P4_16 -*- */ -#include -#include - -#define CONTROLLER_PORT 16 - -const bit<16> TYPE_IPV4 = 0x800; -const bit<16> TYPE_ARP = 0x806; -const bit<16> TYPE_LLDP = 0x88cc; -const bit<16> TYPE_MACSEC = 0x88e5; -const bit<16> TYPE_BDDP = 0x8999; - -const bit<16> DST_MAC_UNKNOWN = 1; -const bit<16> SRC_MAC_UNKNOWN = 2; -const bit<16> SRC_MAC_TIMEOUT = 3; -const bit<16> SRC_MAC_CHANGED_PORT = 4; -const bit<16> ARP_IN = 10; -const bit<16> LLDP_IN = 11; -const bit<16> PACKET_OUT_ON_PORT = 60001; -const bit<16> FULL_PROCESS = 60002; - - -/************************************************************************* -*********************** H E A D E R S *********************************** -*************************************************************************/ - -typedef bit<9> egressSpec_t; -typedef bit<48> macAddr_t; -typedef bit<32> ip4Addr_t; - -header cpu_header_t { - bit<64> zeros; - bit<16> reason; - bit<16> port; - bit<48> timestamp; -} - -header ethernet_t { - macAddr_t dstAddr; - macAddr_t srcAddr; - bit<16> etherType; -} - -header ipv4_t { - bit<4> version; - bit<4> ihl; - bit<8> diffserv; - bit<16> totalLen; - bit<16> identification; - bit<3> flags; - bit<13> fragOffset; - bit<8> ttl; - bit<8> protocol; - bit<16> hdrChecksum; - ip4Addr_t srcAddr; - ip4Addr_t dstAddr; -} - -header sectag_t { - bit<1> tci_v; - bit<1> tci_es; - bit<1> tci_sc; - bit<1> tci_scb; - bit<1> tci_e; - bit<1> tci_c; - bit<2> an; - bit<8> sl; - bit<32> pn; - bit<64> sci; -} - -struct user_metadata_t { - bit<128> SAK; - bit<48> SYSTEM_ID; - bit<8> REGISTER_NUMBER; - bit<48> src_mac_timeout; - egressSpec_t src_mac_table_port; - bool from_controller; - bool recirculated; -} - -struct intrinsic_metadata_t { - bit<16> recirculate_flag; - bit<48> ingress_global_timestamp; -} - -struct metadata { - @metadata @name("intrinsic_metadata") - intrinsic_metadata_t intrinsic_metadata; - user_metadata_t user_metadata; -} - -struct headers { - cpu_header_t cpu_header; - ethernet_t ethernet; - sectag_t sectag; - ipv4_t ipv4; -} - -/************************************************************************* -*********************** P A R S E R *********************************** -*************************************************************************/ - -parser MyParser(packet_in packet, - out headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - - state start { - transition select(packet.lookahead().zeros) { - (bit<64>)0 : parse_cpu_header; - default: parse_ethernet; - } - } - - state parse_cpu_header { - packet.extract(hdr.cpu_header); - transition parse_ethernet; - } - - state parse_ethernet { - packet.extract(hdr.ethernet); - transition select(hdr.ethernet.etherType) { - TYPE_IPV4: parse_ipv4; - TYPE_MACSEC: parse_sectag; - TYPE_LLDP: accept; - TYPE_BDDP: accept; - default: accept; - } - } - - state parse_ipv4 { - packet.extract(hdr.ipv4); - transition accept; - } - - state parse_sectag { - packet.extract(hdr.sectag); - transition accept; - } - -} - -/************************************************************************* -************ C H E C K S U M V E R I F I C A T I O N ************* -*************************************************************************/ - -control MyVerifyChecksum(inout headers hdr, inout metadata meta) { - apply { } -} - - -/************************************************************************* -************** I N G R E S S P R O C E S S I N G ******************* -*************************************************************************/ - -extern ExternCrypt { - ExternCrypt(); - void protect(in bit<128> SAK, - in bit<64> SCI, - in bit<32> PN, - in bit<48> src_addr, - in bit<48> dst_addr, - in bit<128> sectag, - in bit<16> ethertype, - in bit<8> prepend_ipv4_hdr, - in bit<160> ipv4_hdr); - void validate(in bit<128> SAK, - in bit<64> SCI, - in bit<32> PN, - in bit<48> src_addr, - in bit<48> dst_addr, - in bit<128> sectag, - out bit<8> valid, - out bit<16> ethertype); -} - -ExternCrypt() crypt; - - -control MyIngress(inout headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - action drop() { - mark_to_drop(standard_metadata); - } - - action send_to_controller(bit<16> reason, egressSpec_t port){ - standard_metadata.egress_spec = CONTROLLER_PORT; - hdr.cpu_header.setValid(); - hdr.cpu_header.reason = reason; - hdr.cpu_header.port = (bit<16>)port; - hdr.cpu_header.timestamp = standard_metadata.ingress_global_timestamp; - } - - action l2_forward(egressSpec_t port) { - standard_metadata.egress_spec = port; - } - - action flood() { - send_to_controller(DST_MAC_UNKNOWN, standard_metadata.ingress_port); - } - - action learn_src_mac() { - send_to_controller(SRC_MAC_UNKNOWN, standard_metadata.ingress_port); - } - - action src_known(egressSpec_t port, bit<48> timestamp) { - meta.user_metadata.src_mac_table_port = port; - meta.user_metadata.src_mac_timeout = timestamp; - } - - action validate_packet(bit<128> key) { - meta.user_metadata.SAK = key; - } - - table mac_src { - key = { - hdr.ethernet.srcAddr: exact; - } - actions = { - learn_src_mac; - src_known; - } - size = 1024; - default_action = learn_src_mac(); - } - - table mac_dst { - key = { - hdr.ethernet.dstAddr: exact; - } - actions = { - l2_forward; - flood; - drop; - } - size = 1024; - default_action = flood(); - } - - table validate_tbl { - key = { - standard_metadata.ingress_port: exact; - } - actions = { - NoAction; - validate_packet; - } - } - - apply { - //packet from controller, go through full pipeline - if (hdr.cpu_header.isValid() && hdr.cpu_header.reason == FULL_PROCESS) { - hdr.cpu_header.setInvalid(); - meta.user_metadata.from_controller = true; - } - else { - meta.user_metadata.from_controller = false; - } - - // packet from controller, send out on specified port - if (hdr.cpu_header.isValid() && hdr.cpu_header.reason == PACKET_OUT_ON_PORT) { - standard_metadata.egress_spec = (bit<9>)hdr.cpu_header.port; - hdr.cpu_header.setInvalid(); - } - - // packet encrypted with macsec - else if (hdr.sectag.isValid()) { - if (validate_tbl.apply().hit) { - //key found, decrypt the packet - bit<128> SAK = meta.user_metadata.SAK; - bit<64> SCI = hdr.sectag.sci; - bit<32> PN = hdr.sectag.pn; - bit<128> sectag = TYPE_MACSEC ++ hdr.sectag.tci_v ++ hdr.sectag.tci_es ++ hdr.sectag.tci_sc ++ hdr.sectag.tci_scb ++ hdr.sectag.tci_e ++ hdr.sectag.tci_c ++ hdr.sectag.an ++ hdr.sectag.sl ++ hdr.sectag.pn ++ hdr.sectag.sci; - bit<48> src_addr = hdr.ethernet.srcAddr; - bit<48> dst_addr = hdr.ethernet.dstAddr; - bit<8> valid; - bit<16> ethertype; - - crypt.validate(SAK, SCI, PN, src_addr, dst_addr, sectag, valid, ethertype); - - hdr.ethernet.etherType = ethertype; - hdr.sectag.setInvalid(); - - //headers from decrypted payload not parsed -> recirculate packet - meta.user_metadata.recirculated = true; -// recirculate({meta.intrinsic_metadata, standard_metadata, meta.user_metadata}); - } - } - - // LLDP or BDDP packet, send to controller - else if (hdr.ethernet.isValid() && (hdr.ethernet.etherType == TYPE_LLDP || hdr.ethernet.etherType == TYPE_BDDP)) { - send_to_controller(LLDP_IN, standard_metadata.ingress_port); - } - - // ARP packet, send to controller - else if (hdr.ethernet.isValid() && hdr.ethernet.etherType == TYPE_ARP) { - send_to_controller(ARP_IN, standard_metadata.ingress_port); - } - - // all other ethernet packets - else if (hdr.ethernet.isValid()) { - // refresh source mac entry - if(!meta.user_metadata.from_controller && mac_src.apply().hit) { - if(standard_metadata.ingress_global_timestamp > meta.user_metadata.src_mac_timeout) { - send_to_controller(SRC_MAC_TIMEOUT, standard_metadata.ingress_port); - } - else if (meta.user_metadata.src_mac_table_port != standard_metadata.ingress_port) { - send_to_controller(SRC_MAC_CHANGED_PORT, standard_metadata.ingress_port); - } - } - - // get port for dst amc - // drop if port unknown and packet was decrypted (=recirculated) - // (prevents flooding decrypted packet) - if(!hdr.cpu_header.isValid()) { - if(!mac_dst.apply().hit && meta.user_metadata.recirculated) { - drop(); - } - } - - // drop packet if premilinary egress port - if (standard_metadata.egress_spec == 0x1FF) { - drop(); - } - - // drop packet if ingress port == egress port - if (standard_metadata.egress_spec != CONTROLLER_PORT && standard_metadata.egress_spec == standard_metadata.ingress_port) { - drop(); - } - } - } -} - -/************************************************************************* -**************** E G R E S S P R O C E S S I N G ******************* -*************************************************************************/ - -//16 register, bei mehr Ports entsprechend anpassen -register>(32w64) outgoing_packet_numbers; - -control MyEgress(inout headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - action protect_packet(bit<128> key, bit<48> system_id, bit<8> reg) { - meta.user_metadata.SAK = key; - meta.user_metadata.SYSTEM_ID = system_id; - meta.user_metadata.REGISTER_NUMBER = reg; - } - - table protect_tbl { - key = { - standard_metadata.egress_port: exact; - } - actions = { - NoAction; - protect_packet; - } - } - - apply { - if (!hdr.cpu_header.isValid() && hdr.ethernet.isValid() && hdr.ethernet.etherType != TYPE_ARP - && hdr.ethernet.etherType != TYPE_BDDP && protect_tbl.apply().hit){ - bit<128> SAK = meta.user_metadata.SAK; - //get the PN from the corresponding counter - bit<32> PN; - outgoing_packet_numbers.read(PN, (bit<32>) meta.user_metadata.REGISTER_NUMBER); - outgoing_packet_numbers.write((bit<32>) meta.user_metadata.REGISTER_NUMBER, PN + 1); - - //combine the System and Port Id to get the SCI - bit<64> SCI = meta.user_metadata.SYSTEM_ID ++ (bit<16>) standard_metadata.egress_port; - - //set the macsec Header fragments to valid - hdr.sectag.setValid(); - - //set the neccesary data for the sectag and the new ethertype - hdr.sectag.tci_v = 0; - hdr.sectag.tci_es = 0; - hdr.sectag.tci_sc = 1; - hdr.sectag.tci_scb = 0; - hdr.sectag.tci_e = 1; - hdr.sectag.tci_c = 1; - hdr.sectag.an = 0; - hdr.sectag.sl = 0; - hdr.sectag.pn = PN; - hdr.sectag.sci = SCI; - bit<128> sectag = TYPE_MACSEC ++ hdr.sectag.tci_v ++ hdr.sectag.tci_es ++ hdr.sectag.tci_sc ++ hdr.sectag.tci_scb ++ hdr.sectag.tci_e ++ hdr.sectag.tci_c ++ hdr.sectag.an ++ hdr.sectag.sl ++ hdr.sectag.pn ++ hdr.sectag.sci; - - bit<8> prepend_ipv4 = 0x46; - bit<160> ipv4 = 0; - if (hdr.ipv4.isValid()) { - prepend_ipv4 = 0x54; - ipv4 = hdr.ipv4.version ++ hdr.ipv4.ihl ++ hdr.ipv4.diffserv ++ hdr.ipv4.totalLen ++ hdr.ipv4.identification ++ hdr.ipv4.flags ++ hdr.ipv4.fragOffset ++ hdr.ipv4.ttl ++ hdr.ipv4.protocol ++ hdr.ipv4.hdrChecksum ++ hdr.ipv4.srcAddr ++ hdr.ipv4.dstAddr; - hdr.ipv4.setInvalid(); - } - - crypt.protect(SAK, SCI, PN, hdr.ethernet.srcAddr, hdr.ethernet.dstAddr, sectag, hdr.ethernet.etherType, prepend_ipv4, ipv4); - - hdr.ethernet.etherType = TYPE_MACSEC; - } - } -} - -/************************************************************************* -************* C H E C K S U M C O M P U T A T I O N ************** -*************************************************************************/ - -control MyComputeChecksum(inout headers hdr, inout metadata meta) { - apply { - update_checksum( - hdr.ipv4.isValid(), - { hdr.ipv4.version, - hdr.ipv4.ihl, - hdr.ipv4.diffserv, - hdr.ipv4.totalLen, - hdr.ipv4.identification, - hdr.ipv4.flags, - hdr.ipv4.fragOffset, - hdr.ipv4.ttl, - hdr.ipv4.protocol, - hdr.ipv4.srcAddr, - hdr.ipv4.dstAddr }, - hdr.ipv4.hdrChecksum, - HashAlgorithm.csum16); - } -} - -/************************************************************************* -*********************** D E P A R S E R ******************************* -*************************************************************************/ - -control MyDeparser(packet_out packet, in headers hdr) { - apply { - packet.emit(hdr.cpu_header); - packet.emit(hdr.ethernet); - packet.emit(hdr.sectag); - packet.emit(hdr.ipv4); - } -} - -/************************************************************************* -*********************** S W I T C H ******************************* -*************************************************************************/ - -V1Switch( -MyParser(), -MyVerifyChecksum(), -MyIngress(), -MyEgress(), -MyComputeChecksum(), -MyDeparser() -) main; From 9ff1f4d57e7e3e455dca1bd9db4a0a67bacc5fbf Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Tue, 24 Dec 2019 06:12:10 -0500 Subject: [PATCH 18/23] Sync extern from macsec parent --- .../externs/sym_crypto/crypto.cpp | 154 ++++++++++-------- 1 file changed, 82 insertions(+), 72 deletions(-) diff --git a/targets/simple_switch/externs/sym_crypto/crypto.cpp b/targets/simple_switch/externs/sym_crypto/crypto.cpp index d7f9c57f6..1edb90c2a 100644 --- a/targets/simple_switch/externs/sym_crypto/crypto.cpp +++ b/targets/simple_switch/externs/sym_crypto/crypto.cpp @@ -1,4 +1,6 @@ /* Copyright 2013-present Barefoot Networks, Inc. + * Modifications copyright 2018-present University of Tuebingen + * Chair of Communication Networks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,30 +17,38 @@ /* * Antonin Bas (antonin@barefootnetworks.com) + * + * Modifications: + * Marco Haeberle (marco.haeberle@uni-tuebingen.de) + * Joshua Hartmann * */ + // aes stuff #include #include #include +#include #include #include #include // needed for externs #include #include -#include +#include #include #include #include #include - -#include +#include +#include #include +#include #include "simple_switch.h" +#include "register_access.h" using std::endl; using std::cout; @@ -54,8 +64,6 @@ using std::vector; #define IPV4_HDR_SIZE 20 #define ETHERTYPE_SIZE 2 -#define SECURE_DATA_SIZE 123 - namespace bm { class ExternCrypt : public ExternType { public: @@ -65,14 +73,14 @@ class ExternCrypt : public ExternType { void init() override { } void protect(const Data &in_sak, - const Data &in_sci, - const Data &in_pn, - const Data &in_src_addr, - const Data &in_dst_addr, - const Data &in_sectag, - const Data &in_ethertype, - const Data &in_prepend_ipv4_hdr, - const Data &in_ipv4_hdr) { + const Data &in_sci, + const Data &in_pn, + const Data &in_src_addr, + const Data &in_dst_addr, + const Data &in_sectag, + const Data &in_ethertype, + const Data &in_prepend_ipv4_hdr, + const Data &in_ipv4_hdr) { std::vector secure_association_key = get_char_vector( in_sak.get_string(), SAK_SIZE); // cout << "[p4sec] secure_association_key" << std::endl; @@ -95,11 +103,11 @@ class ExternCrypt : public ExternType { // cout << "[p4sec] source_mac_address" << std::endl; // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - std::vector destionation_mac_address = + std::vector destination_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] destionation_mac_address" << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); + // cout << "[p4sec] destination_mac_address" << std::endl; + // hexdump((char*)&destination_mac_address[0], + // destination_mac_address.size()); std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); @@ -162,7 +170,7 @@ class ExternCrypt : public ExternType { integrity_check_value.reserve(ICV_SIZE); protection_function(secure_association_key, secure_channel_identifier, - packet_number, destionation_mac_address, + packet_number, destination_mac_address, source_mac_address, security_tag, raw_packet_data, secure_data, integrity_check_value); @@ -196,35 +204,35 @@ class ExternCrypt : public ExternType { Data &out_valid, Data &out_ethertype) { std::vector secure_association_key = - get_char_vector(in_sak.get_string(), SAK_SIZE); + get_char_vector(in_sak.get_string(), SAK_SIZE); // cout << "[p4sec] secure_association_key" << std::endl; // hexdump((char*)&secure_association_key[0], // secure_association_key.size()); std::vector secure_channel_identifier = - get_char_vector(in_sci.get_string(), SCI_SIZE); + get_char_vector(in_sci.get_string(), SCI_SIZE); // cout << "[p4sec] secure_channel_identifier" << std::endl; // hexdump((char*)&secure_channel_identifier[0], // secure_channel_identifier.size()); - std::vector packet_number = get_char_vector( - in_pn.get_string(), PN_SIZE); + std::vector packet_number = + get_char_vector(in_pn.get_string(), PN_SIZE); // cout << "[p4sec] packet_number" << std::endl; // hexdump((char*)&packet_number[0], packet_number.size()); - std::vector source_mac_address = get_char_vector( - in_src_addr.get_string(), ADDR_SIZE); + std::vector source_mac_address = + get_char_vector(in_src_addr.get_string(), ADDR_SIZE); // cout << "[p4sec] source_mac_address" << std::endl; // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - std::vector destionation_mac_address = - get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] destionation_mac_address" << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); + std::vector destination_mac_address = + get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); + // cout << "[p4sec] destination_mac_address" << std::endl; + // hexdump((char*)&destination_mac_address[0], + // destination_mac_address.size()); - std::vector security_tag = get_char_vector( - in_sectag.get_string(), SECTAG_SIZE); + std::vector security_tag = + get_char_vector(in_sectag.get_string(), SECTAG_SIZE); // cout << "[p4sec] security_tag" << std::endl; // hexdump((char*)&security_tag[0], security_tag.size()); @@ -258,11 +266,12 @@ class ExternCrypt : public ExternType { int valid = validation_function(secure_association_key, secure_channel_identifier, packet_number, - destionation_mac_address, + destination_mac_address, source_mac_address, security_tag, secure_data, integrity_check_value, user_data); + // cout << "[p4sec] user_data" << std::endl; // hexdump((char*)&user_data[0], user_data.size()); @@ -278,8 +287,8 @@ class ExternCrypt : public ExternType { get_packet().remove(get_packet().get_data_size()); // make room for the ciphertext and write the ciphertext in it char *payload_start = get_packet().prepend( - static_cast (secure_data.size() - + user_data.size())); + static_cast (user_data.size()) + - ETHERTYPE_SIZE); for (uint i = 0; i < user_data.size() - ETHERTYPE_SIZE; i++) { payload_start[i] = user_data[i + ETHERTYPE_SIZE]; } @@ -287,8 +296,8 @@ class ExternCrypt : public ExternType { // copy ethertype from encrypted packet std::stringstream ss_ethertype; for (uint i = 0; i < ETHERTYPE_SIZE; ++i) - ss_ethertype << std::setfill('0') << std::setw(2) << std::hex - << static_cast(user_data[i]); + ss_ethertype << std::setfill('0') << std::setw(2) + << std::hex << static_cast(user_data[i]); std::string ethertype_hexstr = ss_ethertype.str(); out_ethertype.set(ethertype_hexstr); @@ -310,7 +319,7 @@ class ExternCrypt : public ExternType { void protection_function(std::vector secure_association_key, std::vector secure_channel_identifier, std::vector packet_number, - std::vector destionation_mac_address, + std::vector destination_mac_address, std::vector source_mac_address, std::vector security_tag, std::vector user_data, @@ -333,17 +342,17 @@ class ExternCrypt : public ExternType { // << packet_number.size() << std::endl; // hexdump((char*)&packet_number[0], packet_number.size()); - // std::cout << "[p4sec] destionation_mac_address size " - // << destionation_mac_address.size() << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); + // std::cout << "[p4sec] destination_mac_address size " + // << destination_mac_address.size() << std::endl; + // hexdump((char*)&destination_mac_address[0], + // destination_mac_address.size()); // std::cout << "[p4sec] source_mac_address size " // << source_mac_address.size() << std::endl; // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - // std::cout << "[p4sec] security_tag size " << - // security_tag.size() << std::endl; + // std::cout << "[p4sec] security_tag size " + // << security_tag.size() << std::endl; // hexdump((char*)&security_tag[0], security_tag.size()); // std::cout << "[p4sec] user_data size " << @@ -366,25 +375,25 @@ class ExternCrypt : public ExternType { // 12 byte IV std::vector IV; IV.reserve(secure_channel_identifier.size() + packet_number.size()); - // The 64 most significant bits of the 96-bit IV are the octets - // of the SCI, encoded as a binary number (9.1). + // The 64 most significant bits of the 96-bit IV are the octets of + // the SCI, encoded as a binary number (9.1). IV.insert(IV.cend(), secure_channel_identifier.cbegin(), secure_channel_identifier.cend()); - // The 32 least significant bits of the 96-bit IV are the octets - // of the PN, encoded as a binary number + // The 32 least significant bits of the 96-bit IV are the octets of + // the PN, encoded as a binary number IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); // std::cout << "[p4sec] IV size " << IV.size() << std::endl; // hexdump((char*)&IV[0], IV.size()); - // A is the Destination MAC Address, Source MAC Address, - // and the octets of the SecTAG concatenated in that order + // A is the Destination MAC Address, Source MAC Address, and the octets + // of the SecTAG concatenated in that order std::vector A; - A.reserve(destionation_mac_address.size() + - source_mac_address.size() + security_tag.size()); - A.insert(A.cend(), destionation_mac_address.cbegin(), - destionation_mac_address.cend()); + A.reserve(destination_mac_address.size() + source_mac_address.size() + + security_tag.size()); + A.insert(A.cend(), destination_mac_address.cbegin(), + destination_mac_address.cend()); A.insert(A.cend(), source_mac_address.cbegin(), source_mac_address.cend()); A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); @@ -393,12 +402,13 @@ class ExternCrypt : public ExternType { P.reserve(user_data.size()); P.insert(P.cend(), user_data.cbegin(), user_data.cend()); + out_secure_data.resize(P.size(), '\0'); out_integrity_check_value.resize(16, '\0'); - // std::cout << "[p4sec] out_secure_data size " << - // out_secure_data.size() << std::endl; + // std::cout << "[p4sec] out_secure_data size " + // << out_secure_data.size() << std::endl; // hexdump((char*)&out_secure_data[0], out_secure_data.size()); // std::cout << "[p4sec] out_integrity_check_value size " @@ -414,9 +424,9 @@ class ExternCrypt : public ExternType { // Set the IV length, kann man machen, muss man aber nicht da standard 12 // EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL); // https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbynid.html#GCM_Mode - // To specify any additional authenticated data (AAD) a call - // to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() - // should be made with the output parameter out set to NULL + // To specify any additional authenticated data (AAD) a call to + // EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be + // made with the output parameter out set to NULL EVP_EncryptUpdate(e_ctx, NULL, &actual_size, &A[0], A.size()); EVP_EncryptUpdate(e_ctx, &out_secure_data[0], &actual_size, &P[0], P.size()); @@ -429,7 +439,7 @@ class ExternCrypt : public ExternType { int validation_function(std::vector secure_association_key, std::vector secure_channel_identifier, std::vector packet_number, - std::vector destionation_mac_address, + std::vector destination_mac_address, std::vector source_mac_address, std::vector security_tag, std::vector secure_data, @@ -449,10 +459,10 @@ class ExternCrypt : public ExternType { // << packet_number.size() << std::endl; // hexdump((char*)&packet_number[0], packet_number.size()); - // std::cout << "[p4sec] destionation_mac_address size " - // << destionation_mac_address.size() << std::endl; - // hexdump((char*)&destionation_mac_address[0], - // destionation_mac_address.size()); + // std::cout << "[p4sec] destination_mac_address size " + // << destination_mac_address.size() << std::endl; + // hexdump((char*)&destination_mac_address[0], + // destination_mac_address.size()); // std::cout << "[p4sec] source_mac_address size " // << source_mac_address.size() << std::endl; @@ -499,15 +509,15 @@ class ExternCrypt : public ExternType { // hexdump((char*)&IV[0], IV.size()); - // A is the Destination MAC Address, Source MAC Address, and - // the octets of the SecTAG concatenated in that order + // A is the Destination MAC Address, Source MAC Address, and the + // octets of the SecTAG concatenated in that order std::vector A; - A.reserve(destionation_mac_address.size() + - source_mac_address.size() + security_tag.size()); - A.insert(A.cend(), destionation_mac_address.cbegin(), - destionation_mac_address.cend()); + A.reserve(destination_mac_address.size() + source_mac_address.size() + + security_tag.size()); + A.insert(A.cend(), destination_mac_address.cbegin(), + destination_mac_address.cend()); A.insert(A.cend(), source_mac_address.cbegin(), - source_mac_address.cend()); + source_mac_address.cend()); A.insert(A.cend(), security_tag.cbegin(), security_tag.cend()); // P is the octets of the User Data @@ -541,7 +551,7 @@ class ExternCrypt : public ExternType { // -> abprt/drop packet? } - // std::cout << "result of decryption: " << result << std::endl; + std::cout << "result of decryption: " << result << std::endl; EVP_CIPHER_CTX_free(d_ctx); @@ -549,7 +559,7 @@ class ExternCrypt : public ExternType { return result; } - void hexDump(char *addr, int len) { + void hexdump(char *addr, int len) { int i; unsigned char buff[17]; unsigned char *pc = (unsigned char*)addr; From c357ef5e30fb1f7577e6932ae7605a7b1a80b7cf Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Sat, 28 Dec 2019 14:38:58 -0500 Subject: [PATCH 19/23] Took care of review comments --- .../macsec}/README.md | 5 +- .../macsec}/crypto.cpp | 207 +++--------------- 2 files changed, 34 insertions(+), 178 deletions(-) rename targets/simple_switch/{externs/sym_crypto => sample_extern/macsec}/README.md (83%) rename targets/simple_switch/{externs/sym_crypto => sample_extern/macsec}/crypto.cpp (66%) diff --git a/targets/simple_switch/externs/sym_crypto/README.md b/targets/simple_switch/sample_extern/macsec/README.md similarity index 83% rename from targets/simple_switch/externs/sym_crypto/README.md rename to targets/simple_switch/sample_extern/macsec/README.md index b72145c17..969b4b950 100644 --- a/targets/simple_switch/externs/sym_crypto/README.md +++ b/targets/simple_switch/sample_extern/macsec/README.md @@ -1,4 +1,4 @@ -# ADD CRYPTO to SIMPLE_SWITCH +# ADD CRYPTO EXTERN to SIMPLE_SWITCH For reference, the extern is implemented in crypto.cpp in this directory. This cpp code is to be incorporated in @@ -20,3 +20,6 @@ https://github.com/uni-tue-kn/p4-macsec/p4/p4/basic.p4 basic.p4 is used to test the cryto extern code with simple_switch. +basic.p4 is compiled using p4c with args shown in + +https://github.com/uni-tue-kn/p4-macsec/blob/master/p4/p4/Makefile diff --git a/targets/simple_switch/externs/sym_crypto/crypto.cpp b/targets/simple_switch/sample_extern/macsec/crypto.cpp similarity index 66% rename from targets/simple_switch/externs/sym_crypto/crypto.cpp rename to targets/simple_switch/sample_extern/macsec/crypto.cpp index 1edb90c2a..c4a4dd468 100644 --- a/targets/simple_switch/externs/sym_crypto/crypto.cpp +++ b/targets/simple_switch/sample_extern/macsec/crypto.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -83,41 +84,23 @@ class ExternCrypt : public ExternType { const Data &in_ipv4_hdr) { std::vector secure_association_key = get_char_vector( in_sak.get_string(), SAK_SIZE); - // cout << "[p4sec] secure_association_key" << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - std::vector secure_channel_identifier = get_char_vector(in_sci.get_string(), SCI_SIZE); - // cout << "[p4sec] secure_channel_identifier" << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); std::vector packet_number = get_char_vector(in_pn.get_string(), PN_SIZE); - // cout << "[p4sec] packet_number" << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); std::vector source_mac_address = get_char_vector(in_src_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] source_mac_address" << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); std::vector destination_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] destination_mac_address" << std::endl; - // hexdump((char*)&destination_mac_address[0], - // destination_mac_address.size()); std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); - // cout << "[p4sec] security_tag" << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); std::vector ethertype = get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); - // cout << "[p4sec] EtherType" << std::endl; - // hexdump((char*)ðertype[0], ethertype.size()); bool prepend_ipv4 = false; // must pass byte to external function @@ -127,7 +110,6 @@ class ExternCrypt : public ExternType { // << in_prepend_ipv4_hdr.get_string() << std::endl; if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { prepend_ipv4 = true; - // cout << "[p4sec] prepend IPv4 Header" << std::endl; } else { // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; } @@ -135,8 +117,7 @@ class ExternCrypt : public ExternType { std::vector ipv4_hdr; if (prepend_ipv4) { ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); - // cout << "[p4sec] IPv4 Header" << std::endl; - // hexdump((char*)&ipv4_hdr[0], ipv4_hdr.size()); + // hexdump((unsigned char*)&ipv4_hdr[0], ipv4_hdr.size()); } @@ -174,12 +155,6 @@ class ExternCrypt : public ExternType { source_mac_address, security_tag, raw_packet_data, secure_data, integrity_check_value); - // cout << "[p4sec] secure_data" << std::endl; - // hexdump((char*)&secure_data[0], secure_data.size()); - - // cout << "[p4sec] integrity_check_value" << std::endl; - // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); - // replace payload // first, remove all the data get_packet().remove(get_packet().get_data_size()); @@ -205,36 +180,21 @@ class ExternCrypt : public ExternType { Data &out_ethertype) { std::vector secure_association_key = get_char_vector(in_sak.get_string(), SAK_SIZE); - // cout << "[p4sec] secure_association_key" << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); std::vector secure_channel_identifier = get_char_vector(in_sci.get_string(), SCI_SIZE); - // cout << "[p4sec] secure_channel_identifier" << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); std::vector packet_number = get_char_vector(in_pn.get_string(), PN_SIZE); - // cout << "[p4sec] packet_number" << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); std::vector source_mac_address = get_char_vector(in_src_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] source_mac_address" << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); std::vector destination_mac_address = get_char_vector(in_dst_addr.get_string(), ADDR_SIZE); - // cout << "[p4sec] destination_mac_address" << std::endl; - // hexdump((char*)&destination_mac_address[0], - // destination_mac_address.size()); std::vector security_tag = get_char_vector(in_sectag.get_string(), SECTAG_SIZE); - // cout << "[p4sec] security_tag" << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); std::vector secure_data; // calculate secure data length @@ -254,12 +214,6 @@ class ExternCrypt : public ExternType { get_packet().data() + get_packet().get_data_size(), integrity_check_value.begin()); - // cout << "[p4sec] secure_data" << std::endl; - // hexdump((char*)&secure_data[0], secure_data.size()); - - // cout << "[p4sec] integrity_check_value" << std::endl; - // hexdump((char*)&integrity_check_value[0], integrity_check_value.size()); - std::vector user_data; user_data.reserve(secure_data_size); @@ -271,17 +225,6 @@ class ExternCrypt : public ExternType { security_tag, secure_data, integrity_check_value, user_data); - - // cout << "[p4sec] user_data" << std::endl; - // hexdump((char*)&user_data[0], user_data.size()); - - // cout << "[p4sec] Ethertype" << std::endl; - // hexdump((char*)&user_data[0], ETHERTYPE_SIZE); - - // cout << "[p4sec] decrypted payload" << std::endl; - // hexdump((char*)&user_data[ETHERTYPE_SIZE], - // user_data.size() - ETHERTYPE_SIZE); - // replace payload // first, remove all the data get_packet().remove(get_packet().get_data_size()); @@ -308,7 +251,6 @@ class ExternCrypt : public ExternType { // string fitted_str = fit_string(str, size); std::vector vec(size, '\0'); if (str.length() > size) { - // cout << "[p4sec] given string was too long" << std::endl; str.resize(size); } vec.insert(vec.cend()-size, str.begin(), str.end()); @@ -316,50 +258,19 @@ class ExternCrypt : public ExternType { return vec; } - void protection_function(std::vector secure_association_key, - std::vector secure_channel_identifier, - std::vector packet_number, - std::vector destination_mac_address, - std::vector source_mac_address, - std::vector security_tag, - std::vector user_data, - std::vector& out_secure_data, - std::vector& out_integrity_check_value + void protection_function( // first 3 args are exceed 80 chars on line + // and this shifts left. + const std::vector &secure_association_key, + const std::vector &secure_channel_identifier, + const std::vector &packet_number, + const std::vector &destination_mac_address, + const std::vector &source_mac_address, + const std::vector &security_tag, + const std::vector &user_data, + std::vector &out_secure_data, + std::vector &out_integrity_check_value ) { - // hier evtl assertions fuer die Laenge der Parameter - // - // std::cout << "[p4sec] secure_association_key size " - // << secure_association_key.size() << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - - // std::cout << "[p4sec] secure_channel_identifier size " - // << secure_channel_identifier.size() << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); - - // std::cout << "[p4sec] packet_number size " - // << packet_number.size() << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); - - // std::cout << "[p4sec] destination_mac_address size " - // << destination_mac_address.size() << std::endl; - // hexdump((char*)&destination_mac_address[0], - // destination_mac_address.size()); - - // std::cout << "[p4sec] source_mac_address size " - // << source_mac_address.size() << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - // std::cout << "[p4sec] security_tag size " - // << security_tag.size() << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); - - // std::cout << "[p4sec] user_data size " << - // user_data.size() << std::endl; - // hexdump((char*)&user_data[0], user_data.size()); - - + // here assertions for the length of the parameters. // terms K, IV, A, P, C, T used in section 2.1 of the GCM // specification ( GCM ) as submitted to NIST @@ -369,9 +280,6 @@ class ExternCrypt : public ExternType { K.insert(K.cend(), secure_association_key.cbegin(), secure_association_key.cend()); - // std::cout << "[p4sec] K size " << K.size() << std::endl; - // hexdump((char*)&K[0], K.size()); - // 12 byte IV std::vector IV; IV.reserve(secure_channel_identifier.size() + packet_number.size()); @@ -383,10 +291,6 @@ class ExternCrypt : public ExternType { // the PN, encoded as a binary number IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); - // std::cout << "[p4sec] IV size " << IV.size() << std::endl; - // hexdump((char*)&IV[0], IV.size()); - - // A is the Destination MAC Address, Source MAC Address, and the octets // of the SecTAG concatenated in that order std::vector A; @@ -406,17 +310,6 @@ class ExternCrypt : public ExternType { out_secure_data.resize(P.size(), '\0'); out_integrity_check_value.resize(16, '\0'); - - // std::cout << "[p4sec] out_secure_data size " - // << out_secure_data.size() << std::endl; - // hexdump((char*)&out_secure_data[0], out_secure_data.size()); - - // std::cout << "[p4sec] out_integrity_check_value size " - // << out_integrity_check_value.size() << std::endl; - // hexdump((char*)&out_integrity_check_value[0], - // out_integrity_check_value.size()); - - // std::cout << "[p4sec] initilalizing encryption" << std::endl; int actual_size = 0, final_size = 0; EVP_CIPHER_CTX* e_ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit(e_ctx, EVP_aes_128_gcm(), &K[0], &IV[0]); @@ -436,52 +329,16 @@ class ExternCrypt : public ExternType { EVP_CIPHER_CTX_free(e_ctx); } - int validation_function(std::vector secure_association_key, - std::vector secure_channel_identifier, - std::vector packet_number, - std::vector destination_mac_address, - std::vector source_mac_address, - std::vector security_tag, - std::vector secure_data, - std::vector integrity_check_value, - std::vector& out_user_data) { - // std::cout << "[p4sec] secure_association_key size " - // << secure_association_key.size() << std::endl; - // hexdump((char*)&secure_association_key[0], - // secure_association_key.size()); - - // std::cout << "[p4sec] secure_channel_identifier size " - // << secure_channel_identifier.size() << std::endl; - // hexdump((char*)&secure_channel_identifier[0], - // secure_channel_identifier.size()); - - // std::cout << "[p4sec] packet_number size " - // << packet_number.size() << std::endl; - // hexdump((char*)&packet_number[0], packet_number.size()); - - // std::cout << "[p4sec] destination_mac_address size " - // << destination_mac_address.size() << std::endl; - // hexdump((char*)&destination_mac_address[0], - // destination_mac_address.size()); - - // std::cout << "[p4sec] source_mac_address size " - // << source_mac_address.size() << std::endl; - // hexdump((char*)&source_mac_address[0], source_mac_address.size()); - - // std::cout << "[p4sec] security_tag size " - // << security_tag.size() << std::endl; - // hexdump((char*)&security_tag[0], security_tag.size()); - - // std::cout << "[p4sec] secure_data size " - // << secure_data.size() << std::endl; - // hexdump((char*)&secure_data[0], secure_data.size()); - - // std::cout << "[p4sec] integrity_check_value size " - // << integrity_check_value.size() << std::endl; - // hexdump((char*)&integrity_check_value[0], - // integrity_check_value.size()); - - + int validation_function( + const std::vector &secure_association_key, + const std::vector &secure_channel_identifier, + const std::vector &packet_number, + const std::vector &destination_mac_address, + const std::vector &source_mac_address, + const std::vector &security_tag, + const std::vector &secure_data, + std::vector &integrity_check_value, + std::vector &out_user_data) { // terms K, IV, A, P, C, T used in section 2.1 of the GCM // specification ( GCM ) as submitted to NIST @@ -491,9 +348,6 @@ class ExternCrypt : public ExternType { K.insert(K.cend(), secure_association_key.cbegin(), secure_association_key.cend()); - // std::cout << "[p4sec] K size " << K.size() << std::endl; - // hexdump((char*)&K[0], K.size()); - // 12 byte IV std::vector IV; IV.reserve(secure_channel_identifier.size() + packet_number.size()); @@ -505,8 +359,7 @@ class ExternCrypt : public ExternType { // the PN, encoded as a binary number IV.insert(IV.cend(), packet_number.cbegin(), packet_number.cend()); - // std::cout << "[p4sec] IV size " << IV.size() << std::endl; - // hexdump((char*)&IV[0], IV.size()); + hexdump((unsigned char*)&IV[0], IV.size()); // A is the Destination MAC Address, Source MAC Address, and the @@ -559,10 +412,9 @@ class ExternCrypt : public ExternType { return result; } - void hexdump(char *addr, int len) { + void hexdump(unsigned char *pc, int len) { int i; unsigned char buff[17]; - unsigned char *pc = (unsigned char*)addr; // Process every byte in the data. for (i = 0; i < len; i++) { // Multiple of 16 means new line (with line offset). @@ -570,7 +422,7 @@ class ExternCrypt : public ExternType { if ((i % 16) == 0) { // Just don't print ASCII for the zeroth line. if (i != 0) - printf(" %s\n", buff); + std::cout << buff << std::endl; // Output the offset. printf("[p4sec] %04x ", i); @@ -589,12 +441,12 @@ class ExternCrypt : public ExternType { // Pad out last line if not exactly 16 characters. while ((i % 16) != 0) { - printf(" "); + std::cout << " "; i++; } // And print the final ASCII bit. - printf(" %s\n", buff); + std::cout << " " << buff << std::endl; } }; @@ -616,3 +468,4 @@ BM_REGISTER_EXTERN_W_NAME_METHOD(ext_crypt, ExternCrypt, validate, const Data &, const Data &, const Data &, const Data &, const Data &, const Data &, Data &, Data &); } // namespace bm + From 1dc5f2cc4dc0cffc1d929bb70cf0b7530d233ddf Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Sat, 28 Dec 2019 15:13:17 -0500 Subject: [PATCH 20/23] Fix style issue with prior commit --- targets/simple_switch/sample_extern/macsec/crypto.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/simple_switch/sample_extern/macsec/crypto.cpp b/targets/simple_switch/sample_extern/macsec/crypto.cpp index c4a4dd468..3ff12e75d 100644 --- a/targets/simple_switch/sample_extern/macsec/crypto.cpp +++ b/targets/simple_switch/sample_extern/macsec/crypto.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include From f031ac7cec54bd5fa7d9489fd1812a8232f55d42 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Sat, 28 Dec 2019 20:19:27 -0500 Subject: [PATCH 21/23] Add Makefile to extern code --- targets/simple_switch/sample_extern/macsec/Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 targets/simple_switch/sample_extern/macsec/Makefile diff --git a/targets/simple_switch/sample_extern/macsec/Makefile b/targets/simple_switch/sample_extern/macsec/Makefile new file mode 100644 index 000000000..63c0f6f6b --- /dev/null +++ b/targets/simple_switch/sample_extern/macsec/Makefile @@ -0,0 +1,11 @@ +crypto_SOURCES = crypto.cpp +crypto_LDADD = -lcrypto + +CPPFLAGS += -I../../ -fPIC -shared + +libexterncrypto.so : $(crypto_SOURCES) + g++ $(CPPFLAGS) $(crypto_SOURCES) -o libexterncrypto.so $(crypto_LDADD) + +clean: + rm -rf libexterncrypto.so + From 3ca057f509959c8569f830f55838c31658495357 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Tue, 7 Jan 2020 13:33:34 -0500 Subject: [PATCH 22/23] Change code after Antonin's review --- .../sample_extern/macsec/Makefile | 11 ---- .../sample_extern/macsec/README.md | 25 --------- .../sample_externs/macsec/README.md | 51 +++++++++++++++++++ .../macsec/crypto.cpp | 9 +--- 4 files changed, 52 insertions(+), 44 deletions(-) delete mode 100644 targets/simple_switch/sample_extern/macsec/Makefile delete mode 100644 targets/simple_switch/sample_extern/macsec/README.md create mode 100644 targets/simple_switch/sample_externs/macsec/README.md rename targets/simple_switch/{sample_extern => sample_externs}/macsec/crypto.cpp (98%) diff --git a/targets/simple_switch/sample_extern/macsec/Makefile b/targets/simple_switch/sample_extern/macsec/Makefile deleted file mode 100644 index 63c0f6f6b..000000000 --- a/targets/simple_switch/sample_extern/macsec/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -crypto_SOURCES = crypto.cpp -crypto_LDADD = -lcrypto - -CPPFLAGS += -I../../ -fPIC -shared - -libexterncrypto.so : $(crypto_SOURCES) - g++ $(CPPFLAGS) $(crypto_SOURCES) -o libexterncrypto.so $(crypto_LDADD) - -clean: - rm -rf libexterncrypto.so - diff --git a/targets/simple_switch/sample_extern/macsec/README.md b/targets/simple_switch/sample_extern/macsec/README.md deleted file mode 100644 index 969b4b950..000000000 --- a/targets/simple_switch/sample_extern/macsec/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# ADD CRYPTO EXTERN to SIMPLE_SWITCH - -For reference, the extern is implemented in crypto.cpp in this directory. -This cpp code is to be incorporated in -behavioral-model/targets/simple_switch/simple_switch.cpp - -The code is crypto.cpp is also available in the repo URL included below -so that testing can be done using MACsec (MAC security) code. A -README.md is available at the repo below with steps for how to test -the code. - -https://github.com/uni-tue-kn/p4-macsec - -The extern is defined in the following P4 file. Search for ExternCrypt -for the extern definition. Additionally the extern is used in P4 code -as crypt.validate() which is decryption and crypt.protect() which is -encryption. - -https://github.com/uni-tue-kn/p4-macsec/p4/p4/basic.p4 - -basic.p4 is used to test the cryto extern code with simple_switch. - -basic.p4 is compiled using p4c with args shown in - -https://github.com/uni-tue-kn/p4-macsec/blob/master/p4/p4/Makefile diff --git a/targets/simple_switch/sample_externs/macsec/README.md b/targets/simple_switch/sample_externs/macsec/README.md new file mode 100644 index 000000000..9b188dcf5 --- /dev/null +++ b/targets/simple_switch/sample_externs/macsec/README.md @@ -0,0 +1,51 @@ +# Add macsec extern to simple_switch +# macsec is layer-2 security. + +For reference, the extern is implemented in crypto.cpp in this directory. +Steps to use the macsec extern are described below. + +TODO + +The code is crypto.cpp is also available in the repo URL included below +so that testing can be done using MACsec (MAC security) code. A +README.md is available at the repo below with steps for how to test +the code. + +https://github.com/uni-tue-kn/p4-macsec + +The extern definition is included below. + +extern ExternCrypt { + ExternCrypt(); + void protect(in bit<128> SAK, + in bit<64> SCI, + in bit<32> PN, + in bit<48> src_addr, + in bit<48> dst_addr, + in bit<128> sectag, + in bit<16> ethertype, + in bit<8> prepend_ipv4_hdr, + in bit<160> ipv4_hdr); + void validate(in bit<128> SAK, + in bit<64> SCI, + in bit<32> PN, + in bit<48> src_addr, + in bit<48> dst_addr, + in bit<128> sectag, + out bit<8> valid, + out bit<16> ethertype); +} + +Additionally the extern is used in P4 code as crypt.validate() which is +decryption and crypt.protect() which is encryption. + +https://github.com/uni-tue-kn/p4-macsec/p4/p4/basic.p4 + +basic.p4 is used to test the cryto extern code with simple_switch as follows: + +In p4-macsec/p4/p4 directory, run `make run`. This will compile the P4 program +and start the switches and mininet. + +basic.p4 is compiled using p4c with args shown in + +https://github.com/uni-tue-kn/p4-macsec/blob/master/p4/p4/Makefile diff --git a/targets/simple_switch/sample_extern/macsec/crypto.cpp b/targets/simple_switch/sample_externs/macsec/crypto.cpp similarity index 98% rename from targets/simple_switch/sample_extern/macsec/crypto.cpp rename to targets/simple_switch/sample_externs/macsec/crypto.cpp index 3ff12e75d..55af38a3c 100644 --- a/targets/simple_switch/sample_extern/macsec/crypto.cpp +++ b/targets/simple_switch/sample_externs/macsec/crypto.cpp @@ -102,24 +102,17 @@ class ExternCrypt : public ExternType { get_char_vector(in_ethertype.get_string(), ETHERTYPE_SIZE); bool prepend_ipv4 = false; - // must pass byte to external function - // use 0x54 T as true - // use 0x46 F as false - // cout << "[p4sec] prepend IPv4 Header ? " - // << in_prepend_ipv4_hdr.get_string() << std::endl; if (in_prepend_ipv4_hdr.get_string().compare("T") == 0) { prepend_ipv4 = true; } else { - // cout << "[p4sec] do not prepend IPv4 Header" << std::endl; + cout << "[p4sec] do not prepend IPv4 Header" << std::endl; } std::vector ipv4_hdr; if (prepend_ipv4) { ipv4_hdr = get_char_vector(in_ipv4_hdr.get_string(), IPV4_HDR_SIZE); - // hexdump((unsigned char*)&ipv4_hdr[0], ipv4_hdr.size()); } - vector raw_packet_data; // calculate secure data length int raw_packet_size = get_packet().get_data_size() + ETHERTYPE_SIZE; From f187058569ce4572be9a1837ce50e10a3a4834c4 Mon Sep 17 00:00:00 2001 From: hemant_mnkcg Date: Tue, 7 Jan 2020 13:34:02 -0500 Subject: [PATCH 23/23] Change code after Antonin's review --- targets/simple_switch/sample_externs/macsec/Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 targets/simple_switch/sample_externs/macsec/Makefile diff --git a/targets/simple_switch/sample_externs/macsec/Makefile b/targets/simple_switch/sample_externs/macsec/Makefile new file mode 100644 index 000000000..63c0f6f6b --- /dev/null +++ b/targets/simple_switch/sample_externs/macsec/Makefile @@ -0,0 +1,11 @@ +crypto_SOURCES = crypto.cpp +crypto_LDADD = -lcrypto + +CPPFLAGS += -I../../ -fPIC -shared + +libexterncrypto.so : $(crypto_SOURCES) + g++ $(CPPFLAGS) $(crypto_SOURCES) -o libexterncrypto.so $(crypto_LDADD) + +clean: + rm -rf libexterncrypto.so +