Source file src/crypto/internal/fips140/ecdsa/cast.go

     1  // Copyright 2024 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 ecdsa
     6  
     7  import (
     8  	"bytes"
     9  	"crypto/internal/fips140"
    10  	_ "crypto/internal/fips140/check"
    11  	"crypto/internal/fips140/sha512"
    12  	"errors"
    13  	"sync"
    14  )
    15  
    16  func testPrivateKey() *PrivateKey {
    17  	// https://www.rfc-editor.org/rfc/rfc9500.html#section-2.3
    18  	return &PrivateKey{
    19  		pub: PublicKey{
    20  			curve: p256,
    21  			q: []byte{
    22  				0x04,
    23  				0x42, 0x25, 0x48, 0xF8, 0x8F, 0xB7, 0x82, 0xFF,
    24  				0xB5, 0xEC, 0xA3, 0x74, 0x44, 0x52, 0xC7, 0x2A,
    25  				0x1E, 0x55, 0x8F, 0xBD, 0x6F, 0x73, 0xBE, 0x5E,
    26  				0x48, 0xE9, 0x32, 0x32, 0xCC, 0x45, 0xC5, 0xB1,
    27  				0x6C, 0x4C, 0xD1, 0x0C, 0x4C, 0xB8, 0xD5, 0xB8,
    28  				0xA1, 0x71, 0x39, 0xE9, 0x48, 0x82, 0xC8, 0x99,
    29  				0x25, 0x72, 0x99, 0x34, 0x25, 0xF4, 0x14, 0x19,
    30  				0xAB, 0x7E, 0x90, 0xA4, 0x2A, 0x49, 0x42, 0x72},
    31  		},
    32  		d: []byte{
    33  			0xE6, 0xCB, 0x5B, 0xDD, 0x80, 0xAA, 0x45, 0xAE,
    34  			0x9C, 0x95, 0xE8, 0xC1, 0x54, 0x76, 0x67, 0x9F,
    35  			0xFE, 0xC9, 0x53, 0xC1, 0x68, 0x51, 0xE7, 0x11,
    36  			0xE7, 0x43, 0x93, 0x95, 0x89, 0xC6, 0x4F, 0xC1,
    37  		},
    38  	}
    39  }
    40  
    41  func testHash() []byte {
    42  	return []byte{
    43  		0x17, 0x1b, 0x1f, 0x5e, 0x9f, 0x8f, 0x8c, 0x5c,
    44  		0x42, 0xe8, 0x06, 0x59, 0x7b, 0x54, 0xc7, 0xb4,
    45  		0x49, 0x05, 0xa1, 0xdb, 0x3a, 0x3c, 0x31, 0xd3,
    46  		0xb7, 0x56, 0x45, 0x8c, 0xc2, 0xd6, 0x88, 0x62,
    47  		0x9e, 0xd6, 0x7b, 0x9b, 0x25, 0x68, 0xd6, 0xc6,
    48  		0x18, 0x94, 0x1e, 0xfe, 0xe3, 0x33, 0x78, 0xa6,
    49  		0xe1, 0xce, 0x13, 0x88, 0x81, 0x26, 0x02, 0x52,
    50  		0xdf, 0xc2, 0x0a, 0xf2, 0x67, 0x49, 0x0a, 0x20,
    51  	}
    52  }
    53  
    54  func fipsPCT[P Point[P]](c *Curve[P], k *PrivateKey) error {
    55  	return fips140.PCT("ECDSA PCT", func() error {
    56  		hash := testHash()
    57  		drbg := newDRBG(sha512.New, k.d, bits2octets(P256(), hash), nil)
    58  		sig, err := sign(c, k, drbg, hash)
    59  		if err != nil {
    60  			return err
    61  		}
    62  		return Verify(c, &k.pub, hash, sig)
    63  	})
    64  }
    65  
    66  var fipsSelfTest = sync.OnceFunc(func() {
    67  	fips140.CAST("ECDSA P-256 SHA2-512 sign and verify", func() error {
    68  		k := testPrivateKey()
    69  		Z := []byte{
    70  			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    71  			0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
    72  		}
    73  		persStr := []byte{
    74  			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
    75  			0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
    76  		}
    77  		hash := testHash()
    78  		want := &Signature{
    79  			R: []byte{
    80  				0x33, 0x64, 0x96, 0xff, 0x8a, 0xfe, 0xaa, 0x0b,
    81  				0x2c, 0x4a, 0x1a, 0x97, 0x77, 0xcc, 0x84, 0xa5,
    82  				0x7e, 0x88, 0x1f, 0x16, 0x2d, 0xe0, 0x29, 0xf7,
    83  				0x62, 0xc2, 0x34, 0x18, 0x10, 0x9c, 0x69, 0x8a,
    84  			}, S: []byte{
    85  				0x97, 0x53, 0x2e, 0x13, 0x6e, 0xd0, 0x9b, 0x30,
    86  				0x8a, 0xdf, 0x4f, 0xe0, 0x54, 0x82, 0x14, 0x83,
    87  				0x5e, 0x93, 0xc7, 0x79, 0x4b, 0x18, 0xa3, 0xf1,
    88  				0x8a, 0x60, 0xae, 0x52, 0x31, 0xe4, 0x2e, 0x4e,
    89  			},
    90  		}
    91  		drbg := newDRBG(sha512.New, Z, nil, plainPersonalizationString(persStr))
    92  		got, err := sign(P256(), k, drbg, hash)
    93  		if err != nil {
    94  			return err
    95  		}
    96  		if err := verify(P256(), &k.pub, hash, got); err != nil {
    97  			return err
    98  		}
    99  		if !bytes.Equal(got.R, want.R) || !bytes.Equal(got.S, want.S) {
   100  			return errors.New("unexpected result")
   101  		}
   102  		return nil
   103  	})
   104  })
   105  
   106  var fipsSelfTestDeterministic = sync.OnceFunc(func() {
   107  	fips140.CAST("DetECDSA P-256 SHA2-512 sign", func() error {
   108  		k := testPrivateKey()
   109  		hash := testHash()
   110  		want := &Signature{
   111  			R: []byte{
   112  				0x9f, 0xc3, 0x83, 0x32, 0x6e, 0xd9, 0x4f, 0x8e,
   113  				0x24, 0xa0, 0x19, 0xef, 0x1d, 0x3a, 0xc3, 0x55,
   114  				0xdd, 0x4b, 0x98, 0xae, 0x78, 0xa7, 0xaf, 0xd3,
   115  				0xfd, 0xf3, 0x22, 0x1c, 0x8b, 0xd6, 0x11, 0x7b,
   116  			}, S: []byte{
   117  				0xd6, 0x52, 0x87, 0x41, 0x71, 0xbd, 0x66, 0xd1,
   118  				0xaf, 0x6c, 0x61, 0xdd, 0xd8, 0xa7, 0xbb, 0xd2,
   119  				0xf7, 0xd5, 0x47, 0x70, 0xe9, 0xe4, 0xac, 0x0a,
   120  				0xb9, 0xfa, 0x0f, 0xbd, 0x3b, 0x9b, 0xc2, 0xfe,
   121  			},
   122  		}
   123  		drbg := newDRBG(sha512.New, k.d, bits2octets(P256(), hash), nil)
   124  		got, err := sign(P256(), k, drbg, hash)
   125  		if err != nil {
   126  			return err
   127  		}
   128  		if err := verify(P256(), &k.pub, hash, got); err != nil {
   129  			return err
   130  		}
   131  		if !bytes.Equal(got.R, want.R) || !bytes.Equal(got.S, want.S) {
   132  			return errors.New("unexpected result")
   133  		}
   134  		return nil
   135  	})
   136  })
   137  

View as plain text