gitee.com/aurawing/surguard-go@v0.3.1-0.20240409071558-96509a61ecf3/device/noise-helpers.go (about)

     1  /* SPDX-License-Identifier: MIT
     2   *
     3   * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
     4   */
     5  
     6  package device
     7  
     8  import (
     9  	"crypto/elliptic"
    10  	"crypto/hmac"
    11  	"crypto/rand"
    12  	"crypto/subtle"
    13  	"errors"
    14  	"hash"
    15  	"math/big"
    16  
    17  	"github.com/emmansun/gmsm/sm2"
    18  	ecrypto "github.com/ethereum/go-ethereum/crypto"
    19  	"golang.org/x/crypto/blake2s"
    20  )
    21  
    22  /* KDF related functions.
    23   * HMAC-based Key Derivation Function (HKDF)
    24   * https://tools.ietf.org/html/rfc5869
    25   */
    26  
    27  func HMAC1(sum *[blake2s.Size]byte, key, in0 []byte) {
    28  	mac := hmac.New(func() hash.Hash {
    29  		h, _ := blake2s.New256(nil)
    30  		return h
    31  	}, key)
    32  	mac.Write(in0)
    33  	mac.Sum(sum[:0])
    34  }
    35  
    36  func HMAC2(sum *[blake2s.Size]byte, key, in0, in1 []byte) {
    37  	mac := hmac.New(func() hash.Hash {
    38  		h, _ := blake2s.New256(nil)
    39  		return h
    40  	}, key)
    41  	mac.Write(in0)
    42  	mac.Write(in1)
    43  	mac.Sum(sum[:0])
    44  }
    45  
    46  func KDF1(t0 *[blake2s.Size]byte, key, input []byte) {
    47  	HMAC1(t0, key, input)
    48  	HMAC1(t0, t0[:], []byte{0x1})
    49  }
    50  
    51  func KDF2(t0, t1 *[blake2s.Size]byte, key, input []byte) {
    52  	var prk [blake2s.Size]byte
    53  	HMAC1(&prk, key, input)
    54  	HMAC1(t0, prk[:], []byte{0x1})
    55  	HMAC2(t1, prk[:], t0[:], []byte{0x2})
    56  	setZero(prk[:])
    57  }
    58  
    59  func KDF3(t0, t1, t2 *[blake2s.Size]byte, key, input []byte) {
    60  	var prk [blake2s.Size]byte
    61  	HMAC1(&prk, key, input)
    62  	HMAC1(t0, prk[:], []byte{0x1})
    63  	HMAC2(t1, prk[:], t0[:], []byte{0x2})
    64  	HMAC2(t2, prk[:], t1[:], []byte{0x3})
    65  	setZero(prk[:])
    66  }
    67  
    68  func isZero(val []byte) bool {
    69  	acc := 1
    70  	for _, b := range val {
    71  		acc &= subtle.ConstantTimeByteEq(b, 0)
    72  	}
    73  	return acc == 1
    74  }
    75  
    76  /* This function is not used as pervasively as it should because this is mostly impossible in Go at the moment */
    77  func setZero(arr []byte) {
    78  	for i := range arr {
    79  		arr[i] = 0
    80  	}
    81  }
    82  
    83  func (sk *NoisePrivateKey) clamp() {
    84  	//sk[0] &= 248
    85  	//sk[31] = (sk[31] & 127) | 64
    86  }
    87  
    88  func newPrivateKey() (sk NoisePrivateKey, err error) {
    89  	if ALGO == SECP256K1 {
    90  		privKey, e := ecrypto.GenerateKey()
    91  		if e == nil {
    92  			sk = NoisePrivateKey(ecrypto.FromECDSA(privKey))
    93  		} else {
    94  			err = e
    95  		}
    96  		return sk, err
    97  	} else if ALGO == SM2 {
    98  		for {
    99  			privKey, e := sm2.GenerateKey(rand.Reader)
   100  			if e == nil {
   101  				b := privKey.D.Bytes()
   102  				if len(b) != NoisePrivateKeySize {
   103  					continue
   104  				}
   105  				sk = NoisePrivateKey(b)
   106  			} else {
   107  				err = e
   108  			}
   109  			return sk, err
   110  		}
   111  	}
   112  	// _, err = rand.Read(sk[:])
   113  	// sk.clamp()
   114  	return sk, errors.New("no such algorithm")
   115  }
   116  
   117  func (sk *NoisePrivateKey) publicKey() (pk NoisePublicKey) {
   118  	if ALGO == SECP256K1 {
   119  		privKey, _ := ecrypto.ToECDSA((*sk)[:])
   120  		pubKey := privKey.PublicKey
   121  		pk = NoisePublicKey(ecrypto.CompressPubkey(&pubKey))
   122  	} else if ALGO == SM2 {
   123  		d := new(big.Int).SetBytes((*sk)[:])
   124  		privKey := new(sm2.PrivateKey)
   125  		privKey.Curve = sm2.P256()
   126  		privKey.D = d
   127  		privKey.PublicKey.X, privKey.PublicKey.Y = privKey.ScalarBaseMult(privKey.D.Bytes())
   128  		pk = NoisePublicKey(elliptic.MarshalCompressed(privKey.Curve, privKey.PublicKey.X, privKey.PublicKey.Y))
   129  	}
   130  
   131  	// apk := (*[NoisePublicKeySize]byte)(&pk)
   132  	// ask := (*[NoisePrivateKeySize]byte)(sk)
   133  	// curve25519.ScalarBaseMult(apk, ask)
   134  	return pk
   135  }
   136  
   137  var errInvalidPublicKey = errors.New("invalid public key")
   138  
   139  func (sk *NoisePrivateKey) sharedSecret(pk NoisePublicKey) (ss [NoisePresharedKeySize]byte, err error) {
   140  	var secKeyX *big.Int
   141  	if ALGO == SECP256K1 {
   142  		privKey, e := ecrypto.ToECDSA((*sk)[:])
   143  		if e != nil {
   144  			return ss, e
   145  		}
   146  		pubKey, e := ecrypto.DecompressPubkey(pk[:])
   147  		if e != nil {
   148  			return ss, e
   149  		}
   150  		secKeyX, _ = ecrypto.S256().ScalarMult(pubKey.X, pubKey.Y, privKey.D.Bytes())
   151  	} else if ALGO == SM2 {
   152  		d := new(big.Int).SetBytes((*sk)[:])
   153  		privKey := new(sm2.PrivateKey)
   154  		privKey.Curve = sm2.P256()
   155  		privKey.D = d
   156  		x, y := elliptic.UnmarshalCompressed(privKey.Curve, pk[:])
   157  		secKeyX, _ = privKey.Curve.ScalarMult(x, y, privKey.D.Bytes())
   158  	}
   159  	if secKeyX == nil {
   160  		return ss, errors.New("no such algorithm")
   161  	}
   162  	presharedKey := secKeyX.Bytes()
   163  	keysize := len(presharedKey)
   164  	if keysize < 32 {
   165  		arr := make([]byte, 32-keysize, 32)
   166  		for i := 0; i < 32-keysize; i++ {
   167  			arr[i] = 0
   168  		}
   169  		arr = append(arr, presharedKey...)
   170  		presharedKey = arr
   171  	}
   172  	return ([NoisePresharedKeySize]byte)(presharedKey), nil
   173  
   174  	// apk := (*[NoisePublicKeySize]byte)(&pk)
   175  	// ask := (*[NoisePrivateKeySize]byte)(sk)
   176  	// curve25519.ScalarMult(&ss, ask, apk)
   177  	// if isZero(ss[:]) {
   178  	// 	return ss, errInvalidPublicKey
   179  	// }
   180  	// return ss, nil
   181  }