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 }