google.golang.org/grpc@v1.62.1/credentials/alts/internal/conn/aes128gcmrekey_test.go (about)

     1  /*
     2   *
     3   * Copyright 2018 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package conn
    20  
    21  import (
    22  	"testing"
    23  
    24  	core "google.golang.org/grpc/credentials/alts/internal"
    25  )
    26  
    27  // getGCMCryptoPair outputs a client/server pair on aes128gcmRekey.
    28  func getRekeyCryptoPair(key []byte, counter []byte, t *testing.T) (ALTSRecordCrypto, ALTSRecordCrypto) {
    29  	client, err := NewAES128GCMRekey(core.ClientSide, key)
    30  	if err != nil {
    31  		t.Fatalf("NewAES128GCMRekey(ClientSide, key) = %v", err)
    32  	}
    33  	server, err := NewAES128GCMRekey(core.ServerSide, key)
    34  	if err != nil {
    35  		t.Fatalf("NewAES128GCMRekey(ServerSide, key) = %v", err)
    36  	}
    37  	// set counter if provided.
    38  	if counter != nil {
    39  		if CounterSide(counter) == core.ClientSide {
    40  			client.(*aes128gcmRekey).outCounter = CounterFromValue(counter, overflowLenAES128GCMRekey)
    41  			server.(*aes128gcmRekey).inCounter = CounterFromValue(counter, overflowLenAES128GCMRekey)
    42  		} else {
    43  			server.(*aes128gcmRekey).outCounter = CounterFromValue(counter, overflowLenAES128GCMRekey)
    44  			client.(*aes128gcmRekey).inCounter = CounterFromValue(counter, overflowLenAES128GCMRekey)
    45  		}
    46  	}
    47  	return client, server
    48  }
    49  
    50  func testRekeyEncryptRoundtrip(client ALTSRecordCrypto, server ALTSRecordCrypto, t *testing.T) {
    51  	// Encrypt.
    52  	const plaintext = "This is plaintext."
    53  	var err error
    54  	buf := []byte(plaintext)
    55  	buf, err = client.Encrypt(buf[:0], buf)
    56  	if err != nil {
    57  		t.Fatal("Encrypting with client-side context: unexpected error", err, "\n",
    58  			"Plaintext:", []byte(plaintext))
    59  	}
    60  
    61  	// Encrypt a second message.
    62  	const plaintext2 = "This is a second plaintext."
    63  	buf2 := []byte(plaintext2)
    64  	buf2, err = client.Encrypt(buf2[:0], buf2)
    65  	if err != nil {
    66  		t.Fatal("Encrypting with client-side context: unexpected error", err, "\n",
    67  			"Plaintext:", []byte(plaintext2))
    68  	}
    69  
    70  	// Decryption fails: cannot decrypt second message before first.
    71  	if got, err := server.Decrypt(nil, buf2); err == nil {
    72  		t.Error("Decrypting client-side ciphertext with a client-side context unexpectedly succeeded; want unexpected counter error:\n",
    73  			"  Original plaintext:", []byte(plaintext2), "\n",
    74  			"  Ciphertext:", buf2, "\n",
    75  			"  Decrypted plaintext:", got)
    76  	}
    77  
    78  	// Decryption fails: wrong counter space.
    79  	if got, err := client.Decrypt(nil, buf); err == nil {
    80  		t.Error("Decrypting client-side ciphertext with a client-side context unexpectedly succeeded; want counter space error:\n",
    81  			"  Original plaintext:", []byte(plaintext), "\n",
    82  			"  Ciphertext:", buf, "\n",
    83  			"  Decrypted plaintext:", got)
    84  	}
    85  
    86  	// Decrypt first message.
    87  	ciphertext := append([]byte(nil), buf...)
    88  	buf, err = server.Decrypt(buf[:0], buf)
    89  	if err != nil || string(buf) != plaintext {
    90  		t.Fatal("Decrypting client-side ciphertext with a server-side context did not produce original content:\n",
    91  			"  Original plaintext:", []byte(plaintext), "\n",
    92  			"  Ciphertext:", ciphertext, "\n",
    93  			"  Decryption error:", err, "\n",
    94  			"  Decrypted plaintext:", buf)
    95  	}
    96  
    97  	// Decryption fails: replay attack.
    98  	if got, err := server.Decrypt(nil, buf); err == nil {
    99  		t.Error("Decrypting client-side ciphertext with a client-side context unexpectedly succeeded; want unexpected counter error:\n",
   100  			"  Original plaintext:", []byte(plaintext), "\n",
   101  			"  Ciphertext:", buf, "\n",
   102  			"  Decrypted plaintext:", got)
   103  	}
   104  }
   105  
   106  // Test encrypt and decrypt on roundtrip messages for aes128gcmRekey.
   107  func (s) TestAES128GCMRekeyEncryptRoundtrip(t *testing.T) {
   108  	// Test for aes128gcmRekey.
   109  	key := make([]byte, 44)
   110  	client, server := getRekeyCryptoPair(key, nil, t)
   111  	testRekeyEncryptRoundtrip(client, server, t)
   112  }