@@ -92,6 +92,85 @@ def test_aes_cbc(self):
92
92
self .assertEqual ((ret , written ), (0 , len (o )))
93
93
self .assertEqual (h (out_buf ), h (o ))
94
94
95
+ def test_aes_cbc_with_ecdh_key (self ):
96
+ ENCRYPT , DECRYPT , PUBKEY_LEN , _ = 1 , 2 , 33 , True
97
+ a_priv = make_cbuffer ('1c6a837d1ac663fdc7f1002327ca38452766eaf4fe3b80ce620bf7cd3f584cf6' )[0 ]
98
+ a_pub = make_cbuffer ('03e581be89d1ef8ce11d60746d08e4f8aedf934d1d861dd436042ee2e3b16db918' )[0 ]
99
+ b_priv = make_cbuffer ('0b6b3dc90d203d854100110788ac87d43aa00620c9cdb361b281b09022ef4b53' )[0 ]
100
+ b_pub = make_cbuffer ('03ff06999ad61c0f3a733b93fc1e6b75ecfb1439b326e840de590a56454f0eeb0d' )[0 ]
101
+ iv = make_cbuffer ('bd5d4724243880738e7e8b0c02658700' )[0 ]
102
+ label = 'a sample label' .encode ()
103
+ payload = 'This is an example response/payload to encrypt' .encode ()
104
+ buf = make_cbuffer ('00' * 256 )[0 ]
105
+
106
+ # Encryption
107
+ good_args = [b_priv , len (b_priv ), iv , len (iv ), payload , len (payload ),
108
+ a_pub , len (a_pub ), label , len (label ), ENCRYPT , buf , len (buf )]
109
+
110
+ ret , written = wally_aes_cbc_with_ecdh_key (* good_args )
111
+ self .assertEqual (ret , WALLY_OK ) # Make sure good args work
112
+ encrypted = make_cbuffer (buf [:written ].hex ())[0 ]
113
+
114
+ invalid_cases = [
115
+ (None , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # NULL privkey
116
+ (_ , 0 , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # Empty privkey
117
+ (_ , 9 , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # Wrong privkey length
118
+ (_ , _ , None , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # NULL IV (enc)
119
+ (_ , _ , _ , 0 , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # Empty IV (enc)
120
+ (_ , _ , _ , 9 , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # Wrong IV length (enc)
121
+ (_ , _ , _ , _ , None , _ , _ , _ , _ , _ , _ , _ , _ ), # NULL payload
122
+ (_ , _ , _ , _ , _ , 0 , _ , _ , _ , _ , _ , _ , _ ), # Empty payload
123
+ (_ , _ , _ , _ , _ , _ , None , _ , _ , _ , _ , _ , _ ), # NULL pubkey
124
+ (_ , _ , _ , _ , _ , _ , _ , 0 , _ , _ , _ , _ , _ ), # Empty pubkey
125
+ (_ , _ , _ , _ , _ , _ , _ , 9 , _ , _ , _ , _ , _ ), # Wrong pubkey length
126
+ (_ , _ , _ , _ , _ , _ , _ , _ , None , _ , _ , _ , _ ), # NULL label
127
+ (_ , _ , _ , _ , _ , _ , _ , _ , _ , 0 , _ , _ , _ ), # Empty label
128
+ (_ , _ , _ , _ , _ , _ , _ , _ , _ , _ , 3 , _ , _ ), # Encrypt+Decrypt flags
129
+ (_ , _ , _ , _ , _ , _ , _ , _ , _ , _ , 5 , _ , _ ), # Unknown flag
130
+ (_ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , None , _ ), # NULL output
131
+ (_ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , 0 ), # Zero-length output
132
+ ]
133
+ for case in invalid_cases :
134
+ args = [good_args [i ] if a == _ else a for i , a in enumerate (case )]
135
+ self .assertEqual (wally_aes_cbc_with_ecdh_key (* args ), (WALLY_EINVAL , 0 ))
136
+
137
+ # Test writing up to/beyond the output buffer size
138
+ for out_len in range (1 , len (encrypted ) + 16 ):
139
+ args = [a for a in good_args ]
140
+ args [- 1 ] = out_len
141
+ ret = wally_aes_cbc_with_ecdh_key (* args )
142
+ self .assertEqual (ret , (WALLY_OK , written )) # returns required length
143
+
144
+ # Decryption
145
+ good_args = [a_priv , len (a_priv ), None , 0 , encrypted , len (encrypted ),
146
+ b_pub , len (b_pub ), label , len (label ), DECRYPT , buf , len (buf )]
147
+
148
+ ret , written = wally_aes_cbc_with_ecdh_key (* good_args )
149
+ self .assertEqual (ret , WALLY_OK ) # Make sure good args work
150
+ self .assertEqual (buf [:written ], payload )
151
+
152
+ bad = make_cbuffer ((encrypted [:- 1 ] + b'?' ).hex ())[0 ] # Corrupt the HMAC
153
+ bad_len = len (encrypted ) - 1
154
+ invalid_cases = [
155
+ (_ , _ , iv , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ), # Non-NULL IV (dec)
156
+ (_ , _ , _ , len (iv ), _ , _ , _ , _ , _ , _ , _ , _ , _ ), # Non-zero IV length (dec)
157
+ (_ , _ , _ , _ , bad , _ , _ , _ , _ , _ , _ , _ , _ ), # Corrupt HMAC
158
+ (_ , _ , _ , _ , _ , bad_len , _ , _ , _ , _ , _ , _ , _ ), # Truncated encrypted data
159
+ ]
160
+ for case in invalid_cases :
161
+ args = [good_args [i ] if a == _ else a for i , a in enumerate (case )]
162
+ self .assertEqual (wally_aes_cbc_with_ecdh_key (* args ), (WALLY_EINVAL , 0 ))
163
+
164
+ # Test writing up to/beyond the output buffer size
165
+ for out_len in range (1 , len (payload ) + 16 ):
166
+ args = [a for a in good_args ]
167
+ args [- 1 ] = out_len
168
+ ret , written = wally_aes_cbc_with_ecdh_key (* args )
169
+ self .assertEqual (ret , WALLY_OK )
170
+ # The output size required includes final padding which is
171
+ # stripped if the payload isn't a multiple of the AES block size.
172
+ self .assertLessEqual (len (payload ), written )
173
+
95
174
96
175
if __name__ == '__main__' :
97
176
unittest .main ()
0 commit comments