...

Source file src/github.com/ThalesIgnite/crypto11/hmac_test.go

Documentation: github.com/ThalesIgnite/crypto11

     1  // Copyright 2018 Thales e-Security, Inc
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining
     4  // a copy of this software and associated documentation files (the
     5  // "Software"), to deal in the Software without restriction, including
     6  // without limitation the rights to use, copy, modify, merge, publish,
     7  // distribute, sublicense, and/or sell copies of the Software, and to
     8  // permit persons to whom the Software is furnished to do so, subject to
     9  // the following conditions:
    10  //
    11  // The above copyright notice and this permission notice shall be
    12  // included in all copies or substantial portions of the Software.
    13  //
    14  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    15  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    16  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    17  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    18  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    19  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    20  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    21  
    22  package crypto11
    23  
    24  import (
    25  	"testing"
    26  
    27  	"github.com/miekg/pkcs11"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestHmac(t *testing.T) {
    32  	ctx, err := ConfigureFromFile("config")
    33  	require.NoError(t, err)
    34  
    35  	defer func() {
    36  		err = ctx.Close()
    37  		require.NoError(t, err)
    38  	}()
    39  
    40  	info, err := ctx.ctx.GetInfo()
    41  	require.NoError(t, err)
    42  
    43  	if info.ManufacturerID == "SoftHSM" {
    44  		t.Skipf("HMAC not implemented on SoftHSM")
    45  	}
    46  	t.Run("HMACSHA1", func(t *testing.T) {
    47  		testHmac(t, ctx, pkcs11.CKK_SHA_1_HMAC, pkcs11.CKM_SHA_1_HMAC, 0, 20, false)
    48  	})
    49  	t.Run("HMACSHA1General", func(t *testing.T) {
    50  		testHmac(t, ctx, pkcs11.CKK_SHA_1_HMAC, pkcs11.CKM_SHA_1_HMAC_GENERAL, 10, 10, true)
    51  	})
    52  	t.Run("HMACSHA256", func(t *testing.T) {
    53  		testHmac(t, ctx, pkcs11.CKK_SHA256_HMAC, pkcs11.CKM_SHA256_HMAC, 0, 32, false)
    54  	})
    55  
    56  }
    57  
    58  func testHmac(t *testing.T, ctx *Context, keytype int, mech int, length int, xlength int, full bool) {
    59  
    60  	skipIfMechUnsupported(t, ctx, uint(mech))
    61  
    62  	id := randomBytes()
    63  	key, err := ctx.GenerateSecretKey(id, 256, Ciphers[keytype])
    64  	require.NoError(t, err)
    65  	require.NotNil(t, key)
    66  	defer key.Delete()
    67  
    68  	t.Run("Short", func(t *testing.T) {
    69  		input := []byte("a short string")
    70  		h1, err := key.NewHMAC(mech, length)
    71  		require.NoError(t, err)
    72  
    73  		n, err := h1.Write(input)
    74  		require.NoError(t, err)
    75  		require.Equal(t, len(input), n)
    76  
    77  		r1 := h1.Sum([]byte{})
    78  		h2, err := key.NewHMAC(mech, length)
    79  		require.NoError(t, err)
    80  
    81  		n, err = h2.Write(input)
    82  		require.NoError(t, err)
    83  		require.Equal(t, len(input), n)
    84  
    85  		r2 := h2.Sum([]byte{})
    86  
    87  		require.Equal(t, r1, r2)
    88  		require.Len(t, r1, xlength)
    89  	})
    90  	if full { // Independent of hash, only do these once
    91  		t.Run("Empty", func(t *testing.T) {
    92  			// Must be able to MAC empty inputs without panicing
    93  			h1, err := key.NewHMAC(mech, length)
    94  			require.NoError(t, err)
    95  			h1.Sum([]byte{})
    96  		})
    97  		t.Run("MultiSum", func(t *testing.T) {
    98  			input := []byte("a different short string")
    99  
   100  			h1, err := key.NewHMAC(mech, length)
   101  			require.NoError(t, err)
   102  
   103  			n, err := h1.Write(input)
   104  			require.NoError(t, err)
   105  			require.Equal(t, len(input), n)
   106  
   107  			r1 := h1.Sum([]byte{})
   108  			r2 := h1.Sum([]byte{})
   109  			require.Equal(t, r1, r2)
   110  
   111  			// Can't add more after Sum()
   112  			_, err = h1.Write(input)
   113  			require.Equal(t, errHmacClosed, err)
   114  
   115  			// 0-length is special
   116  			n, err = h1.Write([]byte{})
   117  			require.NoError(t, err)
   118  			require.Zero(t, n)
   119  		})
   120  		t.Run("Reset", func(t *testing.T) {
   121  
   122  			h1, err := key.NewHMAC(mech, length)
   123  			require.NoError(t, err)
   124  
   125  			n, err := h1.Write([]byte{1})
   126  			require.NoError(t, err)
   127  			require.Equal(t, 1, n)
   128  
   129  			r1 := h1.Sum([]byte{})
   130  			h1.Reset()
   131  
   132  			n, err = h1.Write([]byte{2})
   133  			require.NoError(t, err)
   134  			require.Equal(t, 1, n)
   135  
   136  			r2 := h1.Sum([]byte{})
   137  			h1.Reset()
   138  
   139  			n, err = h1.Write([]byte{1})
   140  			require.NoError(t, err)
   141  			require.Equal(t, 1, n)
   142  
   143  			r3 := h1.Sum([]byte{})
   144  			require.Equal(t, r1, r3)
   145  			require.NotEqual(t, r1, r2)
   146  		})
   147  		t.Run("ResetFast", func(t *testing.T) {
   148  			// Reset() immediately after creation should be safe
   149  
   150  			h1, err := key.NewHMAC(mech, length)
   151  			require.NoError(t, err)
   152  			h1.Reset()
   153  			n, err := h1.Write([]byte{2})
   154  			require.NoError(t, err)
   155  			require.Equal(t, 1, n)
   156  			h1.Sum([]byte{})
   157  		})
   158  	}
   159  }
   160  

View as plain text