xref: /aosp_15_r20/external/tink/go/mac/subtle/hmac_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2020 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//
15////////////////////////////////////////////////////////////////////////////////
16
17package subtle_test
18
19import (
20	"encoding/hex"
21	"strings"
22	"testing"
23
24	"github.com/google/tink/go/mac/subtle"
25	"github.com/google/tink/go/subtle/random"
26)
27
28var key, _ = hex.DecodeString("000102030405060708090a0b0c0d0e0f")
29var data = []byte("Hello")
30var hmacTests = []struct {
31	hashAlg     string
32	tagSize     uint32
33	key         []byte
34	data        []byte
35	expectedMac string
36}{
37	{
38		hashAlg:     "SHA256",
39		tagSize:     32,
40		data:        data,
41		key:         key,
42		expectedMac: "e0ff02553d9a619661026c7aa1ddf59b7b44eac06a9908ff9e19961d481935d4",
43	},
44	{
45		hashAlg: "SHA512",
46		tagSize: 64,
47		data:    data,
48		key:     key,
49		expectedMac: "481e10d823ba64c15b94537a3de3f253c16642451ac45124dd4dde120bf1e5c15" +
50			"e55487d55ba72b43039f235226e7954cd5854b30abc4b5b53171a4177047c9b",
51	},
52	// empty data
53	{
54		hashAlg:     "SHA256",
55		tagSize:     32,
56		data:        []byte{},
57		key:         key,
58		expectedMac: "07eff8b326b7798c9ccfcbdbe579489ac785a7995a04618b1a2813c26744777d",
59	},
60}
61
62func TestHMACBasic(t *testing.T) {
63	for i, test := range hmacTests {
64		cipher, err := subtle.NewHMAC(test.hashAlg, test.key, test.tagSize)
65		if err != nil {
66			t.Errorf("cannot create new mac in test case %d: %s", i, err)
67		}
68		mac, err := cipher.ComputeMAC(test.data)
69		if err != nil {
70			t.Errorf("mac computation failed in test case %d: %s", i, err)
71		}
72		if hex.EncodeToString(mac) != test.expectedMac[:(test.tagSize*2)] {
73			t.Errorf("incorrect mac in test case %d: expect %s, got %s",
74				i, test.expectedMac[:(test.tagSize*2)], hex.EncodeToString(mac))
75		}
76		if err := cipher.VerifyMAC(mac, test.data); err != nil {
77			t.Errorf("mac verification failed in test case %d: %s", i, err)
78		}
79	}
80}
81
82func TestNewHMACWithInvalidInput(t *testing.T) {
83	// invalid hash algorithm
84	_, err := subtle.NewHMAC("MD5", random.GetRandomBytes(16), 32)
85	if err == nil || !strings.Contains(err.Error(), "invalid hash algorithm") {
86		t.Errorf("expect an error when hash algorithm is invalid")
87	}
88	// key too short
89	_, err = subtle.NewHMAC("SHA256", random.GetRandomBytes(1), 32)
90	if err == nil || !strings.Contains(err.Error(), "key too short") {
91		t.Errorf("expect an error when key is too short")
92	}
93	// tag too short
94	_, err = subtle.NewHMAC("SHA256", random.GetRandomBytes(16), 9)
95	if err == nil || !strings.Contains(err.Error(), "tag size too small") {
96		t.Errorf("expect an error when tag size is too small")
97	}
98	// tag too big
99	_, err = subtle.NewHMAC("SHA1", random.GetRandomBytes(16), 21)
100	if err == nil || !strings.Contains(err.Error(), "tag size too big") {
101		t.Errorf("expect an error when tag size is too big")
102	}
103	_, err = subtle.NewHMAC("SHA256", random.GetRandomBytes(16), 33)
104	if err == nil || !strings.Contains(err.Error(), "tag size too big") {
105		t.Errorf("expect an error when tag size is too big")
106	}
107	_, err = subtle.NewHMAC("SHA512", random.GetRandomBytes(16), 65)
108	if err == nil || !strings.Contains(err.Error(), "tag size too big") {
109		t.Errorf("expect an error when tag size is too big")
110	}
111}
112
113func TestHMAComputeVerifyWithNilInput(t *testing.T) {
114	cipher, err := subtle.NewHMAC("SHA256", random.GetRandomBytes(16), 32)
115	if err != nil {
116		t.Errorf("unexpected error when creating new HMAC")
117	}
118	tag, err := cipher.ComputeMAC(nil)
119	if err != nil {
120		t.Errorf("cipher.ComputeMAC(nil) failed: %v", err)
121	}
122	if err := cipher.VerifyMAC(tag, nil); err != nil {
123		t.Errorf("cipher.VerifyMAC(tag, nil) failed: %v", err)
124	}
125}
126
127func TestVerifyMACWithInvalidInput(t *testing.T) {
128	cipher, err := subtle.NewHMAC("SHA256", random.GetRandomBytes(16), 32)
129	if err != nil {
130		t.Errorf("unexpected error when creating new HMAC")
131	}
132	if err := cipher.VerifyMAC(nil, []byte{1}); err == nil {
133		t.Errorf("expect an error when mac is nil")
134	}
135	if err := cipher.VerifyMAC([]byte{1}, nil); err == nil {
136		t.Errorf("expect an error when data is nil")
137	}
138	if err := cipher.VerifyMAC(nil, nil); err == nil {
139		t.Errorf("cipher.VerifyMAC(nil, nil) succeeded unexpectedly")
140	}
141}
142
143func TestHMACModification(t *testing.T) {
144	for i, test := range hmacTests {
145		cipher, err := subtle.NewHMAC(test.hashAlg, test.key, test.tagSize)
146		if err != nil {
147			t.Errorf("cannot create new mac in test case %d: %s", i, err)
148		}
149		mac, _ := cipher.ComputeMAC(test.data)
150		for i := 0; i < len(mac); i++ {
151			tmp := mac[i]
152			for j := 0; j < 8; j++ {
153				mac[i] ^= 1 << uint8(j)
154				err := cipher.VerifyMAC(mac, test.data)
155				if err == nil {
156					t.Errorf("test case %d: modified MAC should be invalid", i)
157				}
158				mac[i] = tmp
159			}
160		}
161	}
162}
163
164func TestHMACTruncation(t *testing.T) {
165	for i, test := range hmacTests {
166		cipher, err := subtle.NewHMAC(test.hashAlg, test.key, test.tagSize)
167		if err != nil {
168			t.Errorf("cannot create new mac in test case %d: %s", i, err)
169		}
170		mac, _ := cipher.ComputeMAC(test.data)
171		for i := 1; i < len(mac); i++ {
172			tmp := mac[:i]
173			err := cipher.VerifyMAC(tmp, test.data)
174			if err == nil {
175				t.Errorf("test case %d: truncated MAC should be invalid", i)
176			}
177		}
178	}
179}
180