1 /**
2  * @license
3  * Copyright 2016 Google Inc. All rights reserved.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // TODO(bleichen):
18 //   - So far only 16 byte tags are tested.
19 //   - default values: BC uses a 64-bit default for tags.
20 //     Tag size is not such a big problem as with AES-GCM,
21 //     since a 64 bit tag gives 64 bit strength for AES-EAX.
22 
23 package com.google.security.wycheproof;
24 
25 import javax.crypto.Cipher;
26 import javax.crypto.spec.GCMParameterSpec;
27 import javax.crypto.spec.SecretKeySpec;
28 import junit.framework.TestCase;
29 
30 /** AES-EAX tests */
31 public class AesEaxTest extends TestCase {
32 
33   /** Test vectors */
34   public static class EaxTestVector {
35     final byte[] pt;
36     final byte[] aad;
37     final byte[] ct;
38     final String ptHex;
39     final String ctHex;
40     final GCMParameterSpec parameters;
41     final SecretKeySpec key;
42 
EaxTestVector( String message, String keyMaterial, String nonce, String aad, String ciphertext)43     public EaxTestVector(
44         String message, String keyMaterial, String nonce, String aad, String ciphertext) {
45       this.ptHex = message;
46       this.pt = TestUtil.hexToBytes(message);
47       this.aad = TestUtil.hexToBytes(aad);
48       this.ct = TestUtil.hexToBytes(ciphertext);
49       this.ctHex = ciphertext;
50       // BouncyCastle uses GCMParameterSpec to specify the parameters for EAX.
51       // This solution is a bit of a hack, but so far we don't know a better way to
52       // specify these parameters.
53       // So far all test vectors use a 128 bit tag.
54       this.parameters = new GCMParameterSpec(128, TestUtil.hexToBytes(nonce));
55       this.key = new SecretKeySpec(TestUtil.hexToBytes(keyMaterial), "AES");
56     }
57   };
58 
59   private static final EaxTestVector[] EAX_TEST_VECTOR = {
60     new EaxTestVector(
61         "",
62         "010511c5e24ee7097dca93272ebfae9e",
63         "93ad516bc6f7302b8edb884ca37f2e65",
64         "",
65         "12edfdb379ef62e845da3d17995b4a1e"),
66     new EaxTestVector(
67         "",
68         "acf877a5aa71e794efd6dc82d5b1a155",
69         "4e301710ae15b2f0ee6335d774741f7e",
70         "c0e0f00a919b7652",
71         "eb3dae1fc33be95848da9fd24e7dbae3"),
72     new EaxTestVector(
73         "c3",
74         "95d8e3675bbc3b96befdc5efb7433a68",
75         "0d40fdefd9289e3a49114454b3c4a5f4",
76         "f2",
77         "c5814dfc2f4ee1719bd5f1d5a649174c1a"),
78     new EaxTestVector(
79         "5810842d",
80         "2eed51af91b178b26e9b53c8877a7af6",
81         "e78747ca46cb9f2068e07717d5226e8a",
82         "",
83         "24245c5bb54aa8bfaceca3665867fa2d7de1653d"),
84     new EaxTestVector(
85         "5ae11bb3b7d60e55",
86         "cb782da180e97023530d1612e2287f0d",
87         "ba641ebe03057b387dd3132e0c7a3853",
88         "",
89         "f6f64fa858708b8f445812fd75a9639f635045fd5972b820"),
90     new EaxTestVector(
91         "54332ed26cd966761710ea58a8f248",
92         "8b4457d52e5c04b38d306f8f38480e97",
93         "3f9d6faca5dd97eb1bc74e1954304cca",
94         "",
95         "3ebbf1fe11e2f454e0ef587fb42a7588e1e32ea788cae20d1700584f448814"),
96     new EaxTestVector(
97         "82ce1f2934dcafe9dee7e0e7cbfdfcd0",
98         "2892cf62d2cc0e8e9c796624e05920f5",
99         "8a0da6d1c4b7a4f426ad62f6829cc310",
100         "c3ed66484eb367c8",
101         "c374afaa42d9497326af332f42d2dee8fb478c82a2b2567b0ab9597c93f137cf"),
102     new EaxTestVector(
103         "e0c993ff5d1d00b4cbee523a1df01db011794d54ab7a504c",
104         "463d89aadfa7d8158dcff9b9c3fc32aa",
105         "356ab4709b32fc85ff82f40561e9f08b",
106         "5ab01a3bfa141f8d33720bd1",
107         "d34bc706a9d7a2be6c2d8805cec2fac270ec6d17844b0911accb612cbb3b373438c74c1280445359"),
108     new EaxTestVector(
109         "e9dfb2897e44236880baf166fa62fa5b8a4713aa981dbc3fe6cf65d9f0c30f47",
110         "54617abbeb90fff7095b26af0e596064",
111         "2621c97c4fe379d9d42f04c479ae1bac",
112         "b6b29c2fbe29dcd2",
113         "212263116062443db28d6abd2c3bca880ea4d178282247fffbc10532d40e9cea"
114             + "6f580fdaca33d446dd6f38a4425be844"),
115     new EaxTestVector(
116         "7537f3e4cbe228468a7837c66aec8a9b6033cba4f1b3d8",
117         "7c74da83b1f292b869c891c80850e85f8237412e13a0bf3f",
118         "cfab2c573a0e723613e6e5b58787af60",
119         "",
120         "98a55f7db58fde8ed8bc00c01c97a6e5bda137b03e56e0dddfbe396c44a14646cbc89979f38736"),
121     // Some test vectors for counter overflow:
122     // Initial counter value == 2^128-1
123     new EaxTestVector(
124         "0000000000000000000000000000000011111111111111111111111111111111",
125         "000102030405060708090a0b0c0d0e0f",
126         "3c8cc2970a008f75cc5beae2847258c2",
127         "",
128         "3c441f32ce07822364d7a2990e50bb13d7b02a26969e4a937e5e9073b0d9c968"
129             + "db90bdb3da3d00afd0fc6a83551da95e"),
130     // counter value overflows at 64-bit boundary
131     new EaxTestVector(
132         "0000000000000000000000000000000011111111111111111111111111111111",
133         "000102030405060708090a0b0c0d0e0f",
134         "aef03d00598494e9fb03cd7d8b590866",
135         "",
136         "d19ac59849026a91aa1b9aec29b11a202a4d739fd86c28e3ae3d588ea21d70c6"
137             + "c30f6cd9202074ed6e2a2a360eac8c47"),
138     // no counter overflow, but the 64 most significant bits are set.
139     new EaxTestVector(
140         "0000000000000000000000000000000011111111111111111111111111111111",
141         "000102030405060708090a0b0c0d0e0f",
142         "55d12511c696a80d0514d1ffba49cada",
143         "",
144         "2108558ac4b2c2d5cc66cea51d6210e046177a67631cd2dd8f09469733acb517"
145             + "fc355e87a267be3ae3e44c0bf3f99b2b"),
146     // counter value overflows at 32-bit boundary
147     new EaxTestVector(
148         "0000000000000000000000000000000011111111111111111111111111111111",
149         "000102030405060708090a0b0c0d0e0f",
150         "79422ddd91c4eee2deaef1f968305304",
151         "",
152         "4d2c1524ca4baa4eefcce6b91b227ee83abaff8105dcafa2ab191f5df2575035"
153             + "e2c865ce2d7abdac024c6f991a848390"),
154     // no counter overflow, but bits 32-64 and 96-128 are set.
155     new EaxTestVector(
156         "0000000000000000000000000000000011111111111111111111111111111111",
157         "000102030405060708090a0b0c0d0e0f",
158         "0af5aa7a7676e28306306bcd9bf2003a",
159         "",
160         "8eb01e62185d782eb9287a341a6862ac5257d6f9adc99ee0a24d9c22b3e9b38a"
161             + "39c339bc8a74c75e2c65c6119544d61e"),
162     // no counter overflow, lower 64 bits are 2^63-1
163     new EaxTestVector(
164         "0000000000000000000000000000000011111111111111111111111111111111",
165         "000102030405060708090a0b0c0d0e0f",
166         "af5a03ae7edd73471bdcdfac5e194a60",
167         "",
168         "94c5d2aca6dbbce8c24513a25e095c0e54a942860d327a222a815cc713b163b4"
169             + "f50b30304e45c9d411e8df4508a98612"),
170     // counter overflow between block 2 and block 3.
171     new EaxTestVector(
172         "0000000000000000000000000000000011111111111111111111111111111111"
173             + "2222222222222222222222222222222233333333333333333333333333333333",
174         "000102030405060708090a0b0c0d0e0f",
175         "b37087680f0edd5a52228b8c7aaea664",
176         "",
177         "3bb6173e3772d4b62eef37f9ef0781f360b6c74be3bf6b371067bc1b090d9d66"
178             + "22a1fbec6ac471b3349cd4277a101d40890fbf27dfdcd0b4e3781f9806daabb6"
179             + "a0498745e59999ddc32d5b140241124e"),
180     // no counter overflow, the lower 64 bits are 2^63-4.
181     new EaxTestVector(
182         "0000000000000000000000000000000011111111111111111111111111111111"
183             + "2222222222222222222222222222222233333333333333333333333333333333"
184             + "44444444444444444444444444444444",
185         "000102030405060708090a0b0c0d0e0f",
186         "4f802da62a384555a19bc2b382eb25af",
187         "",
188         "e9b0bb8857818ce3201c3690d21daa7f264fb8ee93cc7a4674ea2fc32bf182fb"
189             + "2a7e8ad51507ad4f31cefc2356fe7936a7f6e19f95e88fdbf17620916d3a6f3d"
190             + "01fc17d358672f777fd4099246e436e167910be744b8315ae0eb6124590c5d8b"),
191     // 192-bit keys
192     new EaxTestVector(
193         "",
194         "03dd258601c1d4872a52b27892db0356911b2df1436dc7f4",
195         "723cb2022102113018dcd2d204022114",
196         "",
197         "c472b1c6c22b4f2b7e02409499aa2ade"),
198     new EaxTestVector(
199         "",
200         "d33dda72649575e42d6eb1f3255e686084b8a9cf4480803c",
201         "ad2a1d2ef236dfaeb109ab29b1084d63",
202         "fb9c0938a5d317fad5f43edc",
203         "6edc358f22358e1d328c4c1cd98184c6"),
204     new EaxTestVector(
205         "abcdef",
206         "03dd258601c1d4872a52b27892db0356911b2df1436dc7f4",
207         "025f3d2286c143976412022102696708231208",
208         "8917328de211",
209         "520f4f2cf1b893ae3ba8ecbac3a08ea57de2cd"),
210     new EaxTestVector(
211         "4e43dbebe316b7d684b56236fdd928dd",
212         "a36eed1cb54130f547664c184c249e777a3d8ba2e2251b58",
213         "e9587847b1e81511e0643f7dda5b725c",
214         "80c7cb954463b6067b081ff66b1d40cc",
215         "e2645cd32a6e8c1e7cd1991d879b335756f848aba8e51f0b56712bb2889c4783"),
216     new EaxTestVector(
217         "1111111111111111111111111111111122222222222222222222222222222222",
218         "0172acf299142c001d0c231287c1182784554ca3a21908276ac2c92af1294612",
219         "000102030405060708090a0b0c0d0e0f1a1b1c1d",
220         "77922d34e452e0a40962873d22901dd22ad1c303",
221         "5917879b9fa85f4007b7bd0cd46f067d5a7bf287f19dfcc5475c95a4acce520a"
222             + "4c5df804bc091a3b5d6c838b7e494571"),
223     // 256-bit keys
224     new EaxTestVector(
225         "",
226         "0172acf299142c001d0c231287c1182784554ca3a21908276ac2c92af1294612",
227         "696708231208",
228         "",
229         "7c8f86f837a4f72c574678d92f637f07"),
230     new EaxTestVector(
231         "abcdef",
232         "0172acf299142c001d0c231287c1182784554ca3a21908276ac2c92af1294612",
233         "696708231208",
234         "8917328de211",
235         "12486c87bf9a7f22fa65a9493ec0f57f8070f5"),
236     new EaxTestVector(
237         "13d106d7be0890093f44a457d4cc5309",
238         "db50934278a8d8101d1c538acfbfaa13aba9fe53408b6205a0c996d53cf04e8d",
239         "eaef04607a36b2e1b1c539bc335aee9a",
240         "d50e7dbdcc7cf92822dd9dd762a0fc12",
241         "2202165697a2d21316c5f65d2aedb3c52b5567b3f8a25e247cfda1f02bc6cf6f"),
242     new EaxTestVector(
243         "17672288fff3e93a45b3b951bbcfa8a4cb",
244         "1cd28aca6542a4df7316b2c6e9232a4e2cc88cf7aaece33eec7da32ab514051f",
245         "d219298abb115ccbb473cf8e2da9671a",
246         "9c504ab2e5ce0f46844833aba6a11c9186e500239460bb26",
247         "aa518b62c5422e56ce393951aa0441e99df8cafb1555d5a30c90391bb9272c32b9"),
248     new EaxTestVector(
249         "1111111111111111111111111111111122222222222222222222222222222222",
250         "0172acf299142c001d0c231287c1182784554ca3a21908276ac2c92af1294612",
251         "000102030405060708090a0b0c0d0e0f1a1b1c1d",
252         "92d3e42e0409273291d2dc034450",
253         "5917879b9fa85f4007b7bd0cd46f067d5a7bf287f19dfcc5475c95a4acce520a"
254             + "e632946e4999be20159977431bef0454"),
255   };
256 
testEax()257   public void testEax() throws Exception {
258     for (EaxTestVector test : EAX_TEST_VECTOR) {
259       Cipher cipher = Cipher.getInstance("AES/EAX/NoPadding");
260       cipher.init(Cipher.ENCRYPT_MODE, test.key, test.parameters);
261       cipher.updateAAD(test.aad);
262       byte[] ct = cipher.doFinal(test.pt);
263       assertEquals(test.ctHex, TestUtil.bytesToHex(ct));
264     }
265   }
266 
testLateUpdateAAD()267   public void testLateUpdateAAD() throws Exception {
268     for (EaxTestVector test : EAX_TEST_VECTOR) {
269       Cipher cipher = Cipher.getInstance("AES/EAX/NoPadding");
270       cipher.init(Cipher.ENCRYPT_MODE, test.key, test.parameters);
271       byte[] c0 = cipher.update(test.pt);
272       try {
273         cipher.updateAAD(test.aad);
274       } catch (java.lang.IllegalStateException ex) {
275         // Typically one should pass the AAD in first.
276         // Hence it is OK to get this exception.
277         // For example, this is the behaviour of SUNJce.
278         continue;
279       }
280       byte[] c1 = cipher.doFinal();
281       String result = TestUtil.bytesToHex(c0) + TestUtil.bytesToHex(c1);
282       assertEquals(test.ctHex, result);
283     }
284   }
285 }
286