xref: /aosp_15_r20/external/tink/testing/cross_language/mac/hmac_test.py (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1# Copyright 2023 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import os
16import random
17
18from absl.testing import absltest
19from absl.testing import parameterized
20import tink
21
22from tink.proto import common_pb2
23from tink.proto import hmac_pb2
24from tink.proto import tink_pb2
25import tink_config
26from util import testing_servers
27
28
29def setUpModule():
30  tink.mac.register()
31  testing_servers.start('aes_ctr_hmac_streaming_key_test')
32
33
34def tearDownModule():
35  testing_servers.stop()
36
37
38def to_keyset(
39    key: hmac_pb2.HmacKey, output_prefix_type: tink_pb2.OutputPrefixType
40) -> tink_pb2.Keyset:
41  """Embeds a HmacKey with the output_prefix_type in a keyset."""
42  return tink_pb2.Keyset(
43      primary_key_id=1234,
44      key=[
45          tink_pb2.Keyset.Key(
46              key_data=tink_pb2.KeyData(
47                  type_url='type.googleapis.com/google.crypto.tink.HmacKey',
48                  value=key.SerializeToString(),
49                  key_material_type='SYMMETRIC',
50              ),
51              output_prefix_type=output_prefix_type,
52              status=tink_pb2.KeyStatusType.ENABLED,
53              key_id=1234,
54          )
55      ],
56  )
57
58
59def valid_keys():
60  return [
61      # Try SHA1 tag sizes
62      hmac_pb2.HmacKey(
63          version=0,
64          key_value=os.urandom(16),
65          params=hmac_pb2.HmacParams(
66              hash=common_pb2.HashType.SHA1, tag_size=10
67          ),
68      ),
69      hmac_pb2.HmacKey(
70          version=0,
71          key_value=os.urandom(16),
72          params=hmac_pb2.HmacParams(
73              hash=common_pb2.HashType.SHA1, tag_size=15
74          ),
75      ),
76      hmac_pb2.HmacKey(
77          version=0,
78          key_value=os.urandom(16),
79          params=hmac_pb2.HmacParams(
80              hash=common_pb2.HashType.SHA1, tag_size=20
81          ),
82      ),
83      # Try SHA1 key sizes
84      hmac_pb2.HmacKey(
85          version=0,
86          key_value=os.urandom(16),
87          params=hmac_pb2.HmacParams(
88              hash=common_pb2.HashType.SHA1, tag_size=10
89          ),
90      ),
91      hmac_pb2.HmacKey(
92          version=0,
93          key_value=os.urandom(17),
94          params=hmac_pb2.HmacParams(
95              hash=common_pb2.HashType.SHA1, tag_size=10
96          ),
97      ),
98      hmac_pb2.HmacKey(
99          version=0,
100          key_value=os.urandom(30),
101          params=hmac_pb2.HmacParams(
102              hash=common_pb2.HashType.SHA1, tag_size=10
103          ),
104      ),
105      # Very large key
106      hmac_pb2.HmacKey(
107          version=0,
108          key_value=os.urandom(1274),
109          params=hmac_pb2.HmacParams(
110              hash=common_pb2.HashType.SHA1, tag_size=10
111          ),
112      ),
113      # Different hash functions, min tag & key size.
114      hmac_pb2.HmacKey(
115          version=0,
116          key_value=os.urandom(16),
117          params=hmac_pb2.HmacParams(
118              hash=common_pb2.HashType.SHA224, tag_size=10
119          ),
120      ),
121      hmac_pb2.HmacKey(
122          version=0,
123          key_value=os.urandom(16),
124          params=hmac_pb2.HmacParams(
125              hash=common_pb2.HashType.SHA256, tag_size=10
126          ),
127      ),
128      hmac_pb2.HmacKey(
129          version=0,
130          key_value=os.urandom(16),
131          params=hmac_pb2.HmacParams(
132              hash=common_pb2.HashType.SHA384, tag_size=10
133          ),
134      ),
135      hmac_pb2.HmacKey(
136          version=0,
137          key_value=os.urandom(16),
138          params=hmac_pb2.HmacParams(
139              hash=common_pb2.HashType.SHA512, tag_size=10
140          ),
141      ),
142  ]
143
144
145def invalid_keys():
146  return [
147      # Short key size
148      hmac_pb2.HmacKey(
149          version=0,
150          key_value=os.urandom(9),
151          params=hmac_pb2.HmacParams(
152              hash=common_pb2.HashType.SHA1, tag_size=10
153          ),
154      ),
155      # Too short tag
156      hmac_pb2.HmacKey(
157          version=0,
158          key_value=os.urandom(16),
159          params=hmac_pb2.HmacParams(
160              hash=common_pb2.HashType.SHA1, tag_size=9
161          ),
162      ),
163      hmac_pb2.HmacKey(
164          version=0,
165          key_value=os.urandom(16),
166          params=hmac_pb2.HmacParams(
167              hash=common_pb2.HashType.SHA224, tag_size=9
168          ),
169      ),
170      hmac_pb2.HmacKey(
171          version=0,
172          key_value=os.urandom(16),
173          params=hmac_pb2.HmacParams(
174              hash=common_pb2.HashType.SHA256, tag_size=9
175          ),
176      ),
177      hmac_pb2.HmacKey(
178          version=0,
179          key_value=os.urandom(16),
180          params=hmac_pb2.HmacParams(
181              hash=common_pb2.HashType.SHA384, tag_size=9
182          ),
183      ),
184      hmac_pb2.HmacKey(
185          version=0,
186          key_value=os.urandom(16),
187          params=hmac_pb2.HmacParams(
188              hash=common_pb2.HashType.SHA512, tag_size=9
189          ),
190      ),
191      # Too long tag
192      hmac_pb2.HmacKey(
193          version=0,
194          key_value=os.urandom(16),
195          params=hmac_pb2.HmacParams(
196              hash=common_pb2.HashType.SHA1, tag_size=21
197          ),
198      ),
199      hmac_pb2.HmacKey(
200          version=0,
201          key_value=os.urandom(16),
202          params=hmac_pb2.HmacParams(
203              hash=common_pb2.HashType.SHA224, tag_size=29
204          ),
205      ),
206      hmac_pb2.HmacKey(
207          version=0,
208          key_value=os.urandom(16),
209          params=hmac_pb2.HmacParams(
210              hash=common_pb2.HashType.SHA256, tag_size=33
211          ),
212      ),
213      hmac_pb2.HmacKey(
214          version=0,
215          key_value=os.urandom(16),
216          params=hmac_pb2.HmacParams(
217              hash=common_pb2.HashType.SHA384, tag_size=49
218          ),
219      ),
220      hmac_pb2.HmacKey(
221          version=0,
222          key_value=os.urandom(16),
223          params=hmac_pb2.HmacParams(
224              hash=common_pb2.HashType.SHA512, tag_size=65
225          ),
226      ),
227  ]
228
229
230def valid_lang_and_key():
231  for lang in tink_config.supported_languages_for_key_type('HmacKey'):
232    for key in valid_keys():
233      yield (lang, key)
234
235
236def consistency_test_cases():
237  for lang1 in tink_config.supported_languages_for_key_type('HmacKey'):
238    for lang2 in tink_config.supported_languages_for_key_type('HmacKey'):
239      for key in valid_keys():
240        for output_prefix_type in [tink_pb2.OutputPrefixType.TINK,
241                                   tink_pb2.OutputPrefixType.LEGACY,
242                                   tink_pb2.OutputPrefixType.RAW,
243                                   tink_pb2.OutputPrefixType.CRUNCHY]:
244          yield (lang1, lang2, key, output_prefix_type)
245
246
247def invalid_lang_and_key():
248  for lang in tink_config.supported_languages_for_key_type('HmacKey'):
249    for key in invalid_keys():
250      yield (lang, key)
251
252
253class HmacKeyTest(parameterized.TestCase):
254  """Tests specific for keys of type HmacKey."""
255
256  @parameterized.parameters(valid_lang_and_key())
257  def test_create_mac(
258      self, lang: str, key: hmac_pb2.HmacKey
259  ):
260    keyset = to_keyset(key, tink_pb2.OutputPrefixType.TINK)
261    testing_servers.remote_primitive(
262        lang, keyset.SerializeToString(), tink.mac.Mac
263    )
264
265  @parameterized.parameters(consistency_test_cases())
266  def test_compute_mac_lang1_lang2(
267      self,
268      lang1: str,
269      lang2: str,
270      key: hmac_pb2.HmacKey,
271      output_prefix_type: tink_pb2.OutputPrefixType,
272  ):
273    keyset = to_keyset(key, output_prefix_type)
274    mac1 = testing_servers.remote_primitive(
275        lang1, keyset.SerializeToString(), tink.mac.Mac
276    )
277    mac2 = testing_servers.remote_primitive(
278        lang2, keyset.SerializeToString(), tink.mac.Mac
279    )
280    message = os.urandom(random.choice([0, 1, 17, 31, 1027]))
281    mac2.verify_mac(mac1.compute_mac(message), message)
282
283
284if __name__ == '__main__':
285  absltest.main()
286