1// Copyright 2021 The BoringSSL Authors 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// https://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 15package main 16 17import ( 18 "bytes" 19 "crypto/aes" 20 "crypto/rand" 21 "encoding/hex" 22 "testing" 23) 24 25func TestCTSRoundTrip(t *testing.T) { 26 var buf [aes.BlockSize * 8]byte 27 var key, iv [16]byte 28 rand.Reader.Read(buf[:]) 29 rand.Reader.Read(key[:]) 30 rand.Reader.Read(iv[:]) 31 32 for i := aes.BlockSize; i < len(buf); i++ { 33 in := buf[:i] 34 ciphertext := doCTSEncrypt(key[:], in[:], iv[:]) 35 if len(ciphertext) != len(in) { 36 t.Errorf("incorrect ciphertext length for input length %d", len(in)) 37 continue 38 } 39 out := doCTSDecrypt(key[:], ciphertext, iv[:]) 40 41 if !bytes.Equal(in[:], out) { 42 t.Errorf("did not round trip for length %d", len(in)) 43 } 44 } 45} 46 47func TestCTSVectors(t *testing.T) { 48 tests := []struct { 49 plaintextHex string 50 ciphertextHex string 51 ivHex string 52 }{ 53 // Test vectors from OpenSSL. 54 { 55 "4920776f756c64206c696b652074686520", 56 "c6353568f2bf8cb4d8a580362da7ff7f97", 57 "00000000000000000000000000000000", 58 }, 59 { 60 "4920776f756c64206c696b65207468652047656e6572616c20476175277320", 61 "fc00783e0efdb2c1d445d4c8eff7ed2297687268d6ecccc0c07b25e25ecfe5", 62 "00000000000000000000000000000000", 63 }, 64 { 65 "4920776f756c64206c696b65207468652047656e6572616c2047617527732043", 66 "39312523a78662d5be7fcbcc98ebf5a897687268d6ecccc0c07b25e25ecfe584", 67 "00000000000000000000000000000000", 68 }, 69 { 70 "4920776f756c64206c696b65207468652047656e6572616c20476175277320436869636b656e2c20706c656173652c", 71 "97687268d6ecccc0c07b25e25ecfe584b3fffd940c16a18c1b5549d2f838029e39312523a78662d5be7fcbcc98ebf5", 72 "00000000000000000000000000000000", 73 }, 74 { 75 "4920776f756c64206c696b65207468652047656e6572616c20476175277320436869636b656e2c20706c656173652c", 76 "5432a630742dee7beb70f9f1400ee6a0426da5c54a9990f5ae0b7825f51f0060b557cfb581949a4bdf3bb67dedd472", 77 "000102030405060708090a0b0c0d0e0f", 78 }, 79 } 80 81 key := fromHex("636869636b656e207465726979616b69") 82 83 for i, test := range tests { 84 plaintext := fromHex(test.plaintextHex) 85 iv := fromHex(test.ivHex) 86 ciphertext := doCTSEncrypt(key, plaintext, iv) 87 if got := hex.EncodeToString(ciphertext); got != test.ciphertextHex { 88 t.Errorf("#%d: unexpected ciphertext %s, want %s", i, got, test.ciphertextHex) 89 } 90 plaintextAgain := doCTSDecrypt(key, ciphertext, iv) 91 if !bytes.Equal(plaintext, plaintextAgain) { 92 t.Errorf("#%d: did not round trip", i) 93 } 94 } 95} 96