(self,packet,key_name)
| 63 | # This function expects an already encoded data packet, and |
| 64 | # return its encrypted version. |
| 65 | def encrypt(self,packet,key_name): |
| 66 | key = self.keys.get(key_name) |
| 67 | if key == None: |
| 68 | raise Exception("No key with the specified name: "+str(key_name)) |
| 69 | |
| 70 | # Derive the encryption and HMAC keys. |
| 71 | aes_key,hmac_key = self.derive_keys(key) |
| 72 | |
| 73 | # Create an empty bytearray that will contain the encrypted |
| 74 | # packet. The size is not the same as the original packet: |
| 75 | # we have the padding needed to encrypt the data section |
| 76 | # and the 10 bytes HMAC at the end |
| 77 | data_len = len(packet)-7 # 7 bytes plaintext header. |
| 78 | padding_len = (16 - data_len % 16) % 16 |
| 79 | encr_len = 4+len(packet)+padding_len+10 # 4 is the 32bit IV field |
| 80 | encr = bytearray(encr_len) |
| 81 | |
| 82 | # Copy header information. |
| 83 | encr[0] = packet[0] # Packet type. |
| 84 | encr[1] = packet[1] & (0xff^MessageFlagsRelayed) # Flags, but Relayed. |
| 85 | encr[2:6] = packet[2:6] # Sender ID |
| 86 | encr[6] = 0 # TTL. Set to zero for HMAC. |
| 87 | |
| 88 | # Set the 4 IV bytes. |
| 89 | for i in range(7,11): encr[i] = urandom.getrandbits(8) |
| 90 | |
| 91 | # Set plaintext data: here we will actually store the ciphertext |
| 92 | # but we use it as a buffer for zero-padding. |
| 93 | encr[11:11+data_len] = packet[7:7+data_len] |
| 94 | |
| 95 | # The actual initialization fector includes all the first 11 |
| 96 | # bytes, and is the truncated SHA256. |
| 97 | iv = self.sha16(encr[:11]) |
| 98 | |
| 99 | # Encrypt the payload. The 2 argument below means CBC mode. |
| 100 | encr_payload = cryptolib.aes(aes_key,2,iv).encrypt(encr[11:-10]) |
| 101 | encr[11:-10] = encr_payload |
| 102 | |
| 103 | # Compute HMAC and store the first 10 bytes at the end |
| 104 | # of the packet. Last 4 bits are used for padding length. |
| 105 | hm = HMAC_SHA256(hmac_key,encr[:-10])[:10] |
| 106 | encr[-10:] = hm |
| 107 | encr[-1] = (encr[-1] & 0xf0) | padding_len |
| 108 | |
| 109 | # Fix header with right flags & TTL. |
| 110 | encr[1] = packet[1] |
| 111 | encr[6] = packet[6] |
| 112 | return encr |
| 113 | |
| 114 | # Try every possible key, trying to decrypt the packet. Is |
| 115 | # no match is found, None is returned, otherwise the method returns |
no test coverage detected