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