def calc_mac(self, key, ts, prev_hof=None): """Generates MAC for newly created OF.""" raw = bytearray() raw += struct.pack("!I", ts) raw += self.pack(mac=True) if prev_hof: raw += prev_hof.pack()[1:] # Ignore flag byte else: raw += bytes(self.LEN - 1) return mac(key, bytes(raw))[:self.MAC_LEN]
def derive_drkey_raw(sec_val, dst_ia): """ Derive the raw first order DRKey (local AS -> dst_ia). :param DRKeySecretValue sec_val: secret value of local AS :param ISD_AS dst_ia: destination of first order DRKey. :returns: the raw first order DRKey. :rtype: bytes """ return mac( sec_val.secret, b"".join([ struct.pack("!I", dst_ia._isd), struct.pack("!I", dst_ia._as), bytes(8) ]))
def calc_mac(self, info, key, path_ids, prev_raw=None): """ Calculate the MAC based on the reservation info, the relevant path IDs, and the previous SOF field if any. The algorithm is a CBC MAC, with constant input size. """ raw = [] raw.append(struct.pack("!HH", self.ingress, self.egress)) raw.append(info.pack(mac=True)) ids_len = 0 for id_ in path_ids: ids_len += len(id_) raw.append(id_) # Pad path IDs with 0's to give constant length raw.append(bytes(self.MAX_PATH_IDS_LEN - ids_len)) raw.append(prev_raw or bytes(self.LEN)) # Pad to multiple of block size raw.append(bytes(self.MAC_BLOCK_PADDING)) to_mac = b"".join(raw) assert len(to_mac) == self.MAC_DATA_LEN + self.MAC_BLOCK_PADDING assert len(to_mac) % self.MAC_BLOCK_SIZE == 0 return mac(key, to_mac)[:self.MAC_LEN]