func UnmarshalMark(c elliptic.Curve, bytes []byte) *Mark { bytelen := (c.Params().BitSize + 7) >> 3 pointlen := 1 + 2*bytelen if len(bytes) != 2*pointlen { return nil } ret := new(Mark) ret.ax, ret.ay = elliptic.Unmarshal(c, bytes[:pointlen]) ret.bx, ret.by = elliptic.Unmarshal(c, bytes[pointlen:2*pointlen]) return ret }
// Decode Q point from CKA_EC_POINT attribute func readECPoint(curve elliptic.Curve, ecpoint []byte) (*big.Int, *big.Int) { x, y := elliptic.Unmarshal(curve, ecpoint) if x == nil { // http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/os/pkcs11-curr-v2.40-os.html#_ftn1 // PKCS#11 v2.20 specified that the CKA_EC_POINT was to be store in a DER-encoded // OCTET STRING. var point asn1.RawValue asn1.Unmarshal(ecpoint, &point) if len(point.Bytes) > 0 { x, y = elliptic.Unmarshal(curve, point.Bytes) } } return x, y }
func loadPublicKey(csr *CertificateSignatureRequest, req *certificateRequest) bool { var pkInfo = req.Info.PKInfo var algo = pkInfo.Algorithm.Algorithm switch { case algo.Equal(asn1RSAEncryption): csr.Algo = RSA var pub rsa.PublicKey _, err := asn1.Unmarshal(pkInfo.Public.Bytes, &pub) if err != nil { return false } csr.Public = pub return true case algo.Equal(asn1ECCEncryption): csr.Algo = ECDSA var pub ecdsa.PublicKey curveOID := decodeOID(req.Info.PKInfo.Algorithm.Parameters.FullBytes) if curveOID == nil { return false } pub.Curve = oidToCurve(curveOID) if pub.Curve == nil { return false } pub.X, pub.Y = elliptic.Unmarshal(pub.Curve, req.Info.PKInfo.Public.Bytes) if pub.X == nil { return false } csr.Public = pub return true default: return false } }
// Decode a DER-encoded public key. func UnmarshalPublic(in []byte) (pub *PublicKey, err error) { var subj asnSubjectPublicKeyInfo if _, err = asn1.Unmarshal(in, &subj); err != nil { return } if !subj.Algorithm.Equal(idEcPublicKeySupplemented) { err = ErrInvalidPublicKey return } pub = new(PublicKey) pub.Curve = namedCurveFromOID(subj.Supplements.ECDomain) x, y := elliptic.Unmarshal(pub.Curve, subj.PublicKey.Bytes) if x == nil { err = ErrInvalidPublicKey return } pub.X = x pub.Y = y pub.Params = new(ECIESParams) asnECIEStoParams(subj.Supplements.ECCAlgorithms.ECIES, pub.Params) asnECDHtoParams(subj.Supplements.ECCAlgorithms.ECDH, pub.Params) if pub.Params == nil { if pub.Params = ParamsFromCurve(pub.Curve); pub.Params == nil { err = ErrInvalidPublicKey } } return }
func CreateExchangedCipher(peerPub, priv []byte) (Cipher, Cipher, error) { x, y := elliptic.Unmarshal(curve, peerPub) sx, _ := curve.ScalarMult(x, y, priv) secret := cryptohash(sx.Bytes()) aesKey1 := secret[0:aes.BlockSize] aesKey2 := secret[aes.BlockSize : 2*aes.BlockSize] vector1 := secret[2*aes.BlockSize : 3*aes.BlockSize] vector2 := secret[3*aes.BlockSize : 4*aes.BlockSize] block1, err := aes.NewCipher(aesKey1) if err != nil { return nil, nil, err } block2, err := aes.NewCipher(aesKey2) if err != nil { return nil, nil, err } stream1 := cipher.NewOFB(block1, vector1) stream2 := cipher.NewOFB(block2, vector2) return stream1, stream2, nil }
// verify a signature given the hash func (v *ECDSAVerifier) VerifyHash(h, sig []byte) (err error) { r, s := elliptic.Unmarshal(v.c, sig) if r == nil || s == nil || !ecdsa.Verify(v.k, h, r, s) { err = ErrInvalidSignature } return }
func ToECDSAPub(pub []byte) *ecdsa.PublicKey { if len(pub) == 0 { return nil } x, y := elliptic.Unmarshal(secp256k1.S256(), pub) return &ecdsa.PublicKey{Curve: secp256k1.S256(), X: x, Y: y} }
// UnmarshalSignerProto decodes a signing key from a CryptoKey protobuf // message. func UnmarshalSignerProto(ck *CryptoKey) (*Signer, error) { if *ck.Version != CryptoVersion_CRYPTO_VERSION_1 { return nil, newError("bad version") } if *ck.Purpose != CryptoKey_SIGNING { return nil, newError("bad purpose") } if *ck.Algorithm != CryptoKey_ECDSA_SHA { return nil, newError("bad algorithm") } var k ECDSA_SHA_SigningKeyV1 defer ZeroBytes(k.EcPrivate) if err := proto.Unmarshal(ck.Key, &k); err != nil { return nil, err } if *k.Curve != NamedEllipticCurve_PRIME256_V1 { return nil, newError("bad Curve") } x, y := elliptic.Unmarshal(elliptic.P256(), k.EcPublic) pk := &ecdsa.PrivateKey{ D: new(big.Int).SetBytes(k.EcPrivate), PublicKey: ecdsa.PublicKey{ Curve: elliptic.P256(), X: x, Y: y, }, } return &Signer{pk}, nil }
// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) { var identifier []byte var ok bool if identifier, in, ok = parseString(in); !ok { return nil, nil, errShortRead } key := new(ecdsa.PublicKey) switch string(identifier) { case "nistp256": key.Curve = elliptic.P256() case "nistp384": key.Curve = elliptic.P384() case "nistp521": key.Curve = elliptic.P521() default: return nil, nil, errors.New("ssh: unsupported curve") } var keyBytes []byte if keyBytes, in, ok = parseString(in); !ok { return nil, nil, errShortRead } key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes) if key.X == nil || key.Y == nil { return nil, nil, errors.New("ssh: invalid curve point") } return (*ecdsaPublicKey)(key), in, nil }
func (p *curvePoint) UnmarshalBinary(buf []byte) error { p.x, p.y = elliptic.Unmarshal(p.c, buf) if p.x == nil || !p.Valid() { return errors.New("invalid elliptic curve point") } return nil }
// UnmarshalSignerProto decodes a signing key from a CryptoKey protobuf // message. func UnmarshalSignerProto(ck *CryptoKey) (*Signer, error) { if *ck.Version != CryptoVersion_CRYPTO_VERSION_1 { return nil, newError("bad version") } if *ck.Purpose != CryptoKey_SIGNING { return nil, newError("bad purpose") } if *ck.Algorithm != CryptoKey_ECDSA_SHA { return nil, newError("bad algorithm") } k := new(ECDSA_SHA_SigningKeyV1) defer ZeroBytes(k.EcPrivate) if err := proto.Unmarshal(ck.Key, k); err != nil { return nil, err } if *k.Curve != NamedEllipticCurve_PRIME256_V1 { return nil, newError("bad Curve") } s := new(Signer) s.ec = new(ecdsa.PrivateKey) s.ec.D = new(big.Int).SetBytes(k.EcPrivate) s.ec.Curve = elliptic.P256() s.ec.X, s.ec.Y = elliptic.Unmarshal(elliptic.P256(), k.EcPublic) if s.ec.X == nil || s.ec.Y == nil { return nil, fmt.Errorf("failed to unmarshal EC point: X=%v, Y=%v", s.ec.X, s.ec.Y) } return s, nil }
// Decrypt authentications and recovers the original message from // its input using the private key and the ephemeral key included in // the message. func Decrypt(priv *ecdsa.PrivateKey, in []byte) (out []byte, err error) { ephLen := int(in[0]) ephPub := in[1 : 1+ephLen] ct := in[1+ephLen:] if len(ct) < (sha1.Size + aes.BlockSize) { return nil, errors.New("Invalid ciphertext") } x, y := elliptic.Unmarshal(Curve(), ephPub) if x == nil { return nil, errors.New("Invalid public key") } x, _ = priv.Curve.ScalarMult(x, y, priv.D.Bytes()) if x == nil { return nil, errors.New("Failed to generate encryption key") } shared := sha256.Sum256(x.Bytes()) tagStart := len(ct) - sha1.Size h := hmac.New(sha1.New, shared[16:]) h.Write(ct[:tagStart]) mac := h.Sum(nil) if !hmac.Equal(mac, ct[tagStart:]) { return nil, errors.New("Invalid MAC") } paddedOut, err := symcrypt.DecryptCBC(ct[aes.BlockSize:tagStart], ct[:aes.BlockSize], shared[:16]) if err != nil { return } out, err = padding.RemovePadding(paddedOut) return }
// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. func parseECDSA(in []byte) (out *ecdsa.PublicKey, rest []byte, ok bool) { var identifier []byte if identifier, in, ok = parseString(in); !ok { return } key := new(ecdsa.PublicKey) switch string(identifier) { case "nistp256": key.Curve = elliptic.P256() case "nistp384": key.Curve = elliptic.P384() case "nistp521": key.Curve = elliptic.P521() default: ok = false return } var keyBytes []byte if keyBytes, in, ok = parseString(in); !ok { return } key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes) if key.X == nil || key.Y == nil { ok = false return } return key, in, ok }
func ToECDSAPub(pub []byte) *ecdsa.PublicKey { if len(pub) == 0 { return nil } x, y := elliptic.Unmarshal(S256(), pub) return &ecdsa.PublicKey{S256(), x, y} }
func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { if len(skx.key) < 4 { return errServerKeyExchange } if skx.key[0] != 3 { // named curve return errors.New("tls: server selected unsupported curve") } curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) var ok bool if ka.curve, ok = curveForCurveID(curveid); !ok { return errors.New("tls: server selected unsupported curve") } publicLen := int(skx.key[3]) if publicLen+4 > len(skx.key) { return errServerKeyExchange } ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen]) if ka.x == nil { return errServerKeyExchange } serverECDHParams := skx.key[:4+publicLen] sig := skx.key[4+publicLen:] return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig) }
func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { return nil, errClientKeyExchange } if ka.curveid == X25519 { if len(ckx.ciphertext) != 1+32 { return nil, errClientKeyExchange } var theirPublic, sharedKey, scalar [32]byte copy(theirPublic[:], ckx.ciphertext[1:]) copy(scalar[:], ka.privateKey) curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic) return sharedKey[:], nil } curve, ok := curveForCurveID(ka.curveid) if !ok { panic("internal error") } x, y := elliptic.Unmarshal(curve, ckx.ciphertext[1:]) if x == nil { return nil, errClientKeyExchange } if !curve.IsOnCurve(x, y) { return nil, errClientKeyExchange } x, _ = curve.ScalarMult(x, y, ka.privateKey) preMasterSecret := make([]byte, (curve.Params().BitSize+7)>>3) xBytes := x.Bytes() copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) return preMasterSecret, nil }
// UnmarshalVerifierProto decodes a verifying key from a CryptoKey protobuf // message. func UnmarshalVerifierProto(ck *CryptoKey) (*Verifier, error) { if *ck.Version != CryptoVersion_CRYPTO_VERSION_1 { return nil, newError("bad version") } if *ck.Purpose != CryptoKey_VERIFYING { return nil, newError("bad purpose") } if *ck.Algorithm != CryptoKey_ECDSA_SHA { return nil, newError("bad algorithm") } k := new(ECDSA_SHA_VerifyingKeyV1) if err := proto.Unmarshal(ck.Key, k); err != nil { return nil, err } if *k.Curve != NamedEllipticCurve_PRIME256_V1 { return nil, newError("bad curve") } s := new(Verifier) s.ec = new(ecdsa.PublicKey) s.ec.Curve = elliptic.P256() s.ec.X, s.ec.Y = elliptic.Unmarshal(elliptic.P256(), k.EcPublic) return s, nil }
// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) { var w struct { Curve string KeyBytes []byte Rest []byte `ssh:"rest"` } if err := Unmarshal(in, &w); err != nil { return nil, nil, err } key := new(ecdsa.PublicKey) switch w.Curve { case "nistp256": key.Curve = elliptic.P256() case "nistp384": key.Curve = elliptic.P384() case "nistp521": key.Curve = elliptic.P521() default: return nil, nil, errors.New("ssh: unsupported curve") } key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes) if key.X == nil || key.Y == nil { return nil, nil, errors.New("ssh: invalid curve point") } return (*ecdsaPublicKey)(key), w.Rest, nil }
// Encrypt plainText into an Encrypted Message using the given public key. func Encrypt(log chan string, dest_pubkey []byte, plainText string) *EncryptedMessage { // Generate New Public/Private Key Pair D1, X1, Y1 := CreateKey(log) // Unmarshal the Destination's Pubkey X2, Y2 := elliptic.Unmarshal(elliptic.P256(), dest_pubkey) // Point Multiply to get new Pubkey PubX, PubY := elliptic.P256().ScalarMult(X2, Y2, D1) // Generate Pubkey hashes PubHash := sha512.Sum512(elliptic.Marshal(elliptic.P256(), PubX, PubY)) PubHash_E := PubHash[:32] PubHash_M := PubHash[32:64] IV, cipherText, _ := SymmetricEncrypt(PubHash_E, plainText) // Generate HMAC mac := hmac.New(sha256.New, PubHash_M) mac.Write(cipherText) HMAC := mac.Sum(nil) ret := new(EncryptedMessage) copy(ret.IV[:], IV[:]) copy(ret.PublicKey[:], elliptic.Marshal(elliptic.P256(), X1, Y1)) ret.CipherText = cipherText copy(ret.HMAC[:], HMAC) return ret }
// ComputeSharedKey computes and returns the shared key based on the local private key and the remote public key. func (this *p256) ComputeSharedKey(remotePublicKey []byte) (error, []byte) { remotePublicX, remotePublicY := elliptic.Unmarshal(this.curve, remotePublicKey) if !this.curve.IsOnCurve(remotePublicX, remotePublicY) { return errors.New("ECDH : invalid P-256 KeyExchange"), nil } x, _ := this.curve.ScalarMult(remotePublicX, remotePublicY, this.privateKey) return nil, x.Bytes() }
func parseECDSAPublicKey(raw []byte) (key *ecdsa.PublicKey, err error) { buf := bytes.NewBuffer(raw) var algorithm, curveName, public []byte var length int32 err = binary.Read(buf, binary.BigEndian, &length) if err != nil { return } algorithm = make([]byte, length) _, err = io.ReadFull(buf, algorithm) if err != nil { return } err = binary.Read(buf, binary.BigEndian, &length) if err != nil { return } curveName = make([]byte, length) _, err = io.ReadFull(buf, curveName) if err != nil { return } err = binary.Read(buf, binary.BigEndian, &length) if err != nil { return } public = make([]byte, length) _, err = io.ReadFull(buf, public) if err != nil { return } key = new(ecdsa.PublicKey) var curve elliptic.Curve switch string(curveName) { case "nistp256": curve = elliptic.P256() case "nistp384": curve = elliptic.P384() case "nistp521": curve = elliptic.P521() default: err = ErrUnsupportedPublicKey return } key.X, key.Y = elliptic.Unmarshal(curve, public) if key.X == nil { err = ErrInvalidPublicKey return } key.Curve = curve return }
// kexECDH performs Elliptic Curve Diffie-Hellman key exchange as // described in RFC 5656, section 4. func (c *ClientConn) kexECDH(curve elliptic.Curve, magics *handshakeMagics, hostKeyAlgo string) (*kexResult, error) { ephKey, err := ecdsa.GenerateKey(curve, c.config.rand()) if err != nil { return nil, err } kexInit := kexECDHInitMsg{ ClientPubKey: elliptic.Marshal(curve, ephKey.PublicKey.X, ephKey.PublicKey.Y), } serialized := marshal(msgKexECDHInit, kexInit) if err := c.writePacket(serialized); err != nil { return nil, err } packet, err := c.readPacket() if err != nil { return nil, err } var reply kexECDHReplyMsg if err = unmarshal(&reply, packet, msgKexECDHReply); err != nil { return nil, err } x, y := elliptic.Unmarshal(curve, reply.EphemeralPubKey) if x == nil { return nil, errors.New("ssh: elliptic.Unmarshal failure") } if !validateECPublicKey(curve, x, y) { return nil, errors.New("ssh: ephemeral server key not on curve") } // generate shared secret secret, _ := curve.ScalarMult(x, y, ephKey.D.Bytes()) hashFunc := ecHash(curve) h := hashFunc.New() writeString(h, magics.clientVersion) writeString(h, magics.serverVersion) writeString(h, magics.clientKexInit) writeString(h, magics.serverKexInit) writeString(h, reply.HostKey) writeString(h, kexInit.ClientPubKey) writeString(h, reply.EphemeralPubKey) K := make([]byte, intLength(secret)) marshalInt(K, secret) h.Write(K) return &kexResult{ H: h.Sum(nil), K: K, HostKey: reply.HostKey, Signature: reply.Signature, Hash: hashFunc, }, nil }
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { s, err := Ecrecover(hash, sig) if err != nil { return nil, err } x, y := elliptic.Unmarshal(S256(), s) return &ecdsa.PublicKey{S256(), x, y}, nil }
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { s, err := Ecrecover(hash, sig) if err != nil { return nil, err } x, y := elliptic.Unmarshal(secp256k1.S256(), s) return &ecdsa.PublicKey{Curve: secp256k1.S256(), X: x, Y: y}, nil }
func (t *Tack) Verify() bool { curve := elliptic.P256() x, y := elliptic.Unmarshal(curve, append([]byte{4}, t.PublicKey...)) pubKey := ecdsa.PublicKey{curve, x, y} var r, s big.Int r.SetBytes(t.Signature[:SIG_LENGTH/2]) s.SetBytes(t.Signature[SIG_LENGTH/2:]) return ecdsa.Verify(&pubKey, t.hashForSig(), &r, &s) }
// Q' = curve.G * k' // K(x,y) = Q' * k = G * k' * k func (k *ECKey) ComputeKey(bobPub []byte) ([]byte, error) { curve := k.curve bobX, bobY := elliptic.Unmarshal(curve, bobPub) if bobX == nil || bobY == nil { // the point is not on the curve return nil, InvalidECCParam } xk, _ := curve.ScalarMult(bobX, bobY, k.priv) return xk.Bytes(), nil }
// unmarshalECKey parses and checks an EC key. func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) { x, y = elliptic.Unmarshal(curve, pubkey) if x == nil { return nil, nil, errors.New("ssh: elliptic.Unmarshal failure") } if !validateECPublicKey(curve, x, y) { return nil, nil, errors.New("ssh: public key not on curve") } return x, y, nil }
func verify(signerKeyFile, userKeyFile, sigFile string) bool { rawSigner, err := ioutil.ReadFile(signerKeyFile) if err != nil { fmt.Printf("Failed to read signature key: %v\n", err) return false } var signer ecdsa.PublicKey signer.X, signer.Y = elliptic.Unmarshal(elliptic.P521(), rawSigner) if signer.X == nil { fmt.Println("Invalid signature key.") return false } signer.Curve = elliptic.P521() rawUser, err := ioutil.ReadFile(userKeyFile) if err != nil { fmt.Printf("Failed to read user key: %v\n", err) return false } x, _ := elliptic.Unmarshal(elliptic.P521(), rawUser) if x == nil { fmt.Println("Invalid user key.") return false } rawSig, err := ioutil.ReadFile(sigFile) if err != nil { fmt.Printf("Failed to load signature: %v\n", err) return false } var sig ECDSASignature _, err = asn1.Unmarshal(rawSig, &sig) if err != nil { fmt.Printf("Failed to parse signature: %v\n", err) return false } h := sha512.Sum384(rawUser) return ecdsa.Verify(&signer, h[:], sig.R, sig.S) }
func UnmarshalCheckbox(c elliptic.Curve, bytes []byte) *Checkbox { bytelen := (c.Params().BitSize + 7) >> 3 pointlen := 1 + 2*bytelen scalarlen := bytelen if len(bytes) != 2*pointlen+4*scalarlen { return nil } ret := new(Checkbox) ret.ax, ret.ay = elliptic.Unmarshal(c, bytes[:pointlen]) ret.bx, ret.by = elliptic.Unmarshal(c, bytes[pointlen:2*pointlen]) ret.c1 = new(big.Int) ret.c2 = new(big.Int) ret.r1 = new(big.Int) ret.r2 = new(big.Int) ret.c1.SetBytes(bytes[2*pointlen : 2*pointlen+scalarlen]) ret.c2.SetBytes(bytes[2*pointlen+scalarlen : 2*pointlen+2*scalarlen]) ret.r1.SetBytes(bytes[2*pointlen+2*scalarlen : 2*pointlen+3*scalarlen]) ret.r2.SetBytes(bytes[2*pointlen+3*scalarlen : 2*pointlen+4*scalarlen]) return ret }
func UnmarshalPublicCertificate(data []byte) PublicCertificate { x, y := elliptic.Unmarshal(curve, data) cert := new(ecdsa.PublicKey) cert.Curve = curve cert.X = x cert.Y = y return cert }