xref: /aosp_15_r20/external/tink/go/aead/subtle/aes_ctr_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	"bytes"
21	"crypto/aes"
22	"encoding/hex"
23	"strings"
24	"testing"
25
26	"github.com/google/tink/go/aead/subtle"
27	"github.com/google/tink/go/subtle/random"
28)
29
30func TestNewAESCTR(t *testing.T) {
31	key := make([]byte, 64)
32
33	// Test various key sizes with a fixed IV size.
34	for i := 0; i < 64; i++ {
35		k := key[:i]
36		c, err := subtle.NewAESCTR(k, subtle.AESCTRMinIVSize)
37
38		switch len(k) {
39		case 16:
40			fallthrough
41		case 32:
42			// Valid key sizes.
43			if err != nil {
44				t.Errorf("want: valid cipher (key size=%d), got: error %v", len(k), err)
45			}
46			// Verify that the struct contents are correctly set.
47			if len(c.Key) != len(k) {
48				t.Errorf("want: key size=%d, got: key size=%d", len(k), len(c.Key))
49			}
50			if c.IVSize != subtle.AESCTRMinIVSize {
51				t.Errorf("want: IV size=%d, got: IV size=%d", subtle.AESCTRMinIVSize, c.IVSize)
52			}
53		default:
54			// Invalid key sizes.
55			if !strings.Contains(err.Error(), "aes_ctr: invalid AES key size; want 16 or 32") {
56				t.Errorf("wrong error message; want a string starting with \"aes_ctr: invalid AES key size; want 16 or 32\", got %v", err)
57			}
58		}
59	}
60
61	// Test different IV sizes with a fixed key.
62	for i := 0; i < 64; i++ {
63		k := key[:16]
64		c, err := subtle.NewAESCTR(k, i)
65		if i >= subtle.AESCTRMinIVSize && i <= aes.BlockSize {
66			if err != nil {
67				t.Errorf("want: valid cipher (IV size=%d), got: error %v", i, err)
68			}
69			if len(c.Key) != len(k) {
70				t.Errorf("want: key size=%d, got: key size=%d", len(k), len(c.Key))
71			}
72			if c.IVSize != i {
73				t.Errorf("want: IV size=%d, got: IV size=%d", i, c.IVSize)
74			}
75			continue
76		}
77		if !strings.Contains(err.Error(), "aes_ctr: invalid IV size:") {
78			t.Errorf("want: error invalid IV size, got: %v", err)
79		}
80	}
81}
82
83func TestNistTestVector(t *testing.T) {
84	// NIST SP 800-38A pp 55
85	key, err := hex.DecodeString("2b7e151628aed2a6abf7158809cf4f3c")
86	if err != nil {
87		t.Fatalf("failed to hex decode key, error: %v", err)
88	}
89
90	// NIST IV
91	iv := "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
92	// NIST ciphertext blocks
93	c := "874d6191b620e3261bef6864990db6ce" +
94		"9806f66b7970fdff8617187bb9fffdff" +
95		"5ae4df3edbd5d35e5b4f09020db03eab" +
96		"1e031dda2fbe03d1792170a0f3009cee"
97	ciphertext, err := hex.DecodeString(iv + c)
98	if err != nil {
99		t.Fatalf("failed to hex decode ciphertext, error: %v", err)
100	}
101
102	// NIST plaintext blocks
103	p := "6bc1bee22e409f96e93d7e117393172a" +
104		"ae2d8a571e03ac9c9eb76fac45af8e51" +
105		"30c81c46a35ce411e5fbc1191a0a52ef" +
106		"f69f2445df4f9b17ad2b417be66c3710"
107	message, err := hex.DecodeString(p)
108	if err != nil {
109		t.Fatalf("failed to hex decode message, error: %v", err)
110	}
111
112	stream, err := subtle.NewAESCTR(key, len(iv)/2)
113	if err != nil {
114		t.Fatalf("failed to create AESCTR instance, error: %v", err)
115	}
116
117	plaintext, err := stream.Decrypt(ciphertext)
118	if err != nil {
119		t.Errorf("failed to decrypt ciphertext, error: %v", err)
120	}
121
122	if !bytes.Equal(plaintext, message) {
123		t.Errorf("plaintext doesn't match message")
124	}
125}
126
127func TestMultipleEncrypt(t *testing.T) {
128	key := random.GetRandomBytes(16)
129
130	stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
131	if err != nil {
132		t.Fatalf("failed to create AESCTR instance, error: %v", err)
133	}
134
135	plaintext := []byte("Some data to encrypt.")
136	ct1, err := stream.Encrypt(plaintext)
137	if err != nil {
138		t.Errorf("encryption failed, error: %v", err)
139	}
140	ct2, err := stream.Encrypt(plaintext)
141	if err != nil {
142		t.Errorf("encryption failed, error: %v", err)
143	}
144	if bytes.Equal(ct1, ct2) {
145		t.Error("the two ciphertexts cannot be equal")
146	}
147	// Encrypt 100 times and verify that the result is 100 different ciphertexts.
148	ciphertexts := map[string]bool{}
149	for i := 0; i < 100; i++ {
150		c, err := stream.Encrypt(plaintext)
151		if err != nil {
152			t.Errorf("encryption failed for iteration %d, error: %v", i, err)
153		}
154		ciphertexts[string(c)] = true
155	}
156
157	if len(ciphertexts) != 100 {
158		t.Errorf("got: %d ciphertexts, want: 100 ciphertexts", len(ciphertexts))
159	}
160}
161
162func TestEncryptDecrypt(t *testing.T) {
163	key, err := hex.DecodeString("000102030405060708090a0b0c0d0e0f")
164	if err != nil {
165		t.Fatal("failed to hex decode key")
166	}
167
168	stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
169	if err != nil {
170		t.Fatalf("failed to get AESCTR instance, error: %v", err)
171	}
172
173	message := []byte("Some data to encrypt.")
174	ciphertext, err := stream.Encrypt(message)
175	if err != nil {
176		t.Errorf("encryption failed, error: %v", err)
177	}
178
179	if len(ciphertext) != len(message)+subtle.AESCTRMinIVSize {
180		t.Errorf("ciphertext incorrect size, got: %d, want: %d", len(ciphertext), len(message)+subtle.AESCTRMinIVSize)
181	}
182
183	plaintext, err := stream.Decrypt(ciphertext)
184	if err != nil {
185		t.Errorf("decryption failed, error: %v", err)
186	}
187
188	if !bytes.Equal(message, plaintext) {
189		t.Errorf("decryption result mismatch, got: %v, want: %v", plaintext, message)
190	}
191}
192
193func TestEncryptRandomMessage(t *testing.T) {
194	key := random.GetRandomBytes(16)
195
196	stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
197	if err != nil {
198		t.Errorf("failed to instantiate AESCTR, error: %v", err)
199	}
200
201	for i := 0; i < 256; i++ {
202		message := random.GetRandomBytes(uint32(i))
203		ciphertext, err := stream.Encrypt(message)
204		if err != nil {
205			t.Errorf("encryption failed at iteration %d, error: %v", i, err)
206		}
207		if len(ciphertext) != len(message)+subtle.AESCTRMinIVSize {
208			t.Errorf("invalid ciphertext length for i = %d", i)
209		}
210
211		plaintext, err := stream.Decrypt(ciphertext)
212		if err != nil {
213			t.Errorf("decryption failed at iteration %d, error: %v", i, err)
214		}
215
216		if !bytes.Equal(plaintext, message) {
217			t.Errorf("plaintext doesn't match message, i = %d", i)
218		}
219	}
220}
221
222func TestEncryptRandomKeyAndMessage(t *testing.T) {
223	for i := 0; i < 256; i++ {
224		key := random.GetRandomBytes(16)
225
226		stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
227		if err != nil {
228			t.Errorf("failed to instantiate AESCTR, error: %v", err)
229		}
230
231		message := random.GetRandomBytes(uint32(i))
232		ciphertext, err := stream.Encrypt(message)
233		if err != nil {
234			t.Errorf("encryption failed at iteration %d, error: %v", i, err)
235		}
236		if len(ciphertext) != len(message)+subtle.AESCTRMinIVSize {
237			t.Errorf("invalid ciphertext length for i = %d", i)
238		}
239
240		plaintext, err := stream.Decrypt(ciphertext)
241		if err != nil {
242			t.Errorf("decryption failed at iteration %d, error: %v", i, err)
243		}
244
245		if !bytes.Equal(plaintext, message) {
246			t.Errorf("plaintext doesn't match message, i = %d", i)
247		}
248	}
249}
250