...

Source file src/golang.org/x/crypto/internal/wycheproof/aes_cbc_test.go

Documentation: golang.org/x/crypto/internal/wycheproof

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package wycheproof
     6  
     7  import (
     8  	"crypto/aes"
     9  	"crypto/cipher"
    10  	"encoding/hex"
    11  	"fmt"
    12  	"testing"
    13  )
    14  
    15  func TestAesCbc(t *testing.T) {
    16  	// IndCpaTestVector
    17  	type IndCpaTestVector struct {
    18  
    19  		// A brief description of the test case
    20  		Comment string `json:"comment,omitempty"`
    21  
    22  		// the raw ciphertext (without IV)
    23  		Ct string `json:"ct,omitempty"`
    24  
    25  		// A list of flags
    26  		Flags []string `json:"flags,omitempty"`
    27  
    28  		// the initialization vector
    29  		Iv string `json:"iv,omitempty"`
    30  
    31  		// the key
    32  		Key string `json:"key,omitempty"`
    33  
    34  		// the plaintext
    35  		Msg string `json:"msg,omitempty"`
    36  
    37  		// Test result
    38  		Result string `json:"result,omitempty"`
    39  
    40  		// Identifier of the test case
    41  		TcId int `json:"tcId,omitempty"`
    42  	}
    43  
    44  	// Notes a description of the labels used in the test vectors
    45  	type Notes struct {
    46  	}
    47  
    48  	// IndCpaTestGroup
    49  	type IndCpaTestGroup struct {
    50  
    51  		// the IV size in bits
    52  		IvSize int `json:"ivSize,omitempty"`
    53  
    54  		// the keySize in bits
    55  		KeySize int `json:"keySize,omitempty"`
    56  
    57  		// the expected size of the tag in bits
    58  		TagSize int                 `json:"tagSize,omitempty"`
    59  		Tests   []*IndCpaTestVector `json:"tests,omitempty"`
    60  		Type    interface{}         `json:"type,omitempty"`
    61  	}
    62  
    63  	// Root
    64  	type Root struct {
    65  
    66  		// the primitive tested in the test file
    67  		Algorithm string `json:"algorithm,omitempty"`
    68  
    69  		// the version of the test vectors.
    70  		GeneratorVersion string `json:"generatorVersion,omitempty"`
    71  
    72  		// additional documentation
    73  		Header []string `json:"header,omitempty"`
    74  
    75  		// a description of the labels used in the test vectors
    76  		Notes *Notes `json:"notes,omitempty"`
    77  
    78  		// the number of test vectors in this test
    79  		NumberOfTests int                `json:"numberOfTests,omitempty"`
    80  		Schema        interface{}        `json:"schema,omitempty"`
    81  		TestGroups    []*IndCpaTestGroup `json:"testGroups,omitempty"`
    82  	}
    83  
    84  	var root Root
    85  	readTestVector(t, "aes_cbc_pkcs5_test.json", &root)
    86  	for _, tg := range root.TestGroups {
    87  	tests:
    88  		for _, tv := range tg.Tests {
    89  			block, err := aes.NewCipher(decodeHex(tv.Key))
    90  			if err != nil {
    91  				t.Fatalf("#%d: %v", tv.TcId, err)
    92  			}
    93  			mode := cipher.NewCBCDecrypter(block, decodeHex(tv.Iv))
    94  			ct := decodeHex(tv.Ct)
    95  			if len(ct)%aes.BlockSize != 0 {
    96  				panic(fmt.Sprintf("#%d: ciphertext is not a multiple of the block size", tv.TcId))
    97  			}
    98  			mode.CryptBlocks(ct, ct) // decrypt the block in place
    99  
   100  			// Skip the tests that are broken due to bad padding. Panic if there are any
   101  			// tests left that are invalid for some other reason in the future, to
   102  			// evaluate what to do with those tests.
   103  			for _, flag := range tv.Flags {
   104  				if flag == "BadPadding" {
   105  					continue tests
   106  				}
   107  			}
   108  			if !shouldPass(tv.Result, tv.Flags, nil) {
   109  				panic(fmt.Sprintf("#%d: found an invalid test that is broken for some reason other than bad padding", tv.TcId))
   110  			}
   111  
   112  			// Remove the PKCS#5 padding from the given ciphertext to validate it
   113  			padding := ct[len(ct)-1]
   114  			paddingNum := int(padding)
   115  			for i := paddingNum; i > 0; i-- {
   116  				if ct[len(ct)-i] != padding { // panic if the padding is unexpectedly bad
   117  					panic(fmt.Sprintf("#%d: bad padding at index=%d of %v", tv.TcId, i, ct))
   118  				}
   119  			}
   120  			ct = ct[:len(ct)-paddingNum]
   121  
   122  			if got, want := hex.EncodeToString(ct), tv.Msg; got != want {
   123  				t.Errorf("#%d, type: %s, comment: %q, decoded ciphertext not equal: %s, want %s", tv.TcId, tv.Result, tv.Comment, got, want)
   124  			}
   125  		}
   126  	}
   127  }
   128  

View as plain text