github.com/ethereum/go-ethereum@v1.16.1/p2p/discover/v5wire/encoding.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package v5wire 18 19 import ( 20 "bytes" 21 "crypto/aes" 22 "crypto/cipher" 23 "crypto/ecdsa" 24 crand "crypto/rand" 25 "crypto/sha256" 26 "encoding/binary" 27 "errors" 28 "fmt" 29 "hash" 30 31 "github.com/ethereum/go-ethereum/common/mclock" 32 "github.com/ethereum/go-ethereum/p2p/enode" 33 "github.com/ethereum/go-ethereum/p2p/enr" 34 "github.com/ethereum/go-ethereum/rlp" 35 ) 36 37 // TODO concurrent WHOAREYOU tie-breaker 38 // TODO rehandshake after X packets 39 40 // Header represents a packet header. 41 type Header struct { 42 IV [sizeofMaskingIV]byte 43 StaticHeader 44 AuthData []byte 45 46 src enode.ID // used by decoder 47 } 48 49 // StaticHeader contains the static fields of a packet header. 50 type StaticHeader struct { 51 ProtocolID [6]byte 52 Version uint16 53 Flag byte 54 Nonce Nonce 55 AuthSize uint16 56 } 57 58 // Authdata layouts. 59 type ( 60 whoareyouAuthData struct { 61 IDNonce [16]byte // ID proof data 62 RecordSeq uint64 // highest known ENR sequence of requester 63 } 64 65 handshakeAuthData struct { 66 h struct { 67 SrcID enode.ID 68 SigSize byte // signature data 69 PubkeySize byte // offset of 70 } 71 // Trailing variable-size data. 72 signature, pubkey, record []byte 73 } 74 75 messageAuthData struct { 76 SrcID enode.ID 77 } 78 ) 79 80 // Packet header flag values. 81 const ( 82 flagMessage = iota 83 flagWhoareyou 84 flagHandshake 85 ) 86 87 // Protocol constants. 88 const ( 89 version = 1 90 minVersion = 1 91 sizeofMaskingIV = 16 92 93 // The minimum size of any Discovery v5 packet is 63 bytes. 94 // Should reject packets smaller than minPacketSize. 95 minPacketSize = 63 96 97 maxPacketSize = 1280 98 99 minMessageSize = 48 // this refers to data after static headers 100 randomPacketMsgSize = 20 101 ) 102 103 var DefaultProtocolID = [6]byte{'d', 'i', 's', 'c', 'v', '5'} 104 105 // Errors. 106 var ( 107 errTooShort = errors.New("packet too short") 108 errInvalidHeader = errors.New("invalid packet header") 109 errInvalidFlag = errors.New("invalid flag value in header") 110 errMinVersion = errors.New("version of packet header below minimum") 111 errMsgTooShort = errors.New("message/handshake packet below minimum size") 112 errAuthSize = errors.New("declared auth size is beyond packet length") 113 errUnexpectedHandshake = errors.New("unexpected auth response, not in handshake") 114 errInvalidAuthKey = errors.New("invalid ephemeral pubkey") 115 errNoRecord = errors.New("expected ENR in handshake but none sent") 116 errInvalidNonceSig = errors.New("invalid ID nonce signature") 117 errMessageTooShort = errors.New("message contains no data") 118 errMessageDecrypt = errors.New("cannot decrypt message") 119 ) 120 121 // Public errors. 122 var ( 123 // ErrInvalidReqID represents error when the ID is invalid. 124 ErrInvalidReqID = errors.New("request ID larger than 8 bytes") 125 ) 126 127 // IsInvalidHeader reports whether 'err' is related to an invalid packet header. When it 128 // returns false, it is pretty certain that the packet causing the error does not belong 129 // to discv5. 130 func IsInvalidHeader(err error) bool { 131 return err == errTooShort || err == errInvalidHeader || err == errMsgTooShort 132 } 133 134 // Packet sizes. 135 var ( 136 sizeofStaticHeader = binary.Size(StaticHeader{}) 137 sizeofWhoareyouAuthData = binary.Size(whoareyouAuthData{}) 138 sizeofHandshakeAuthData = binary.Size(handshakeAuthData{}.h) 139 sizeofMessageAuthData = binary.Size(messageAuthData{}) 140 sizeofStaticPacketData = sizeofMaskingIV + sizeofStaticHeader 141 ) 142 143 // Codec encodes and decodes Discovery v5 packets. 144 // This type is not safe for concurrent use. 145 type Codec struct { 146 sha256 hash.Hash 147 localnode *enode.LocalNode 148 privkey *ecdsa.PrivateKey 149 sc *SessionCache 150 protocolID [6]byte 151 152 // encoder buffers 153 buf bytes.Buffer // whole packet 154 headbuf bytes.Buffer // packet header 155 msgbuf bytes.Buffer // message RLP plaintext 156 msgctbuf []byte // message data ciphertext 157 158 // decoder buffer 159 decbuf []byte 160 reader bytes.Reader 161 } 162 163 // NewCodec creates a wire codec. 164 func NewCodec(ln *enode.LocalNode, key *ecdsa.PrivateKey, clock mclock.Clock, protocolID *[6]byte) *Codec { 165 c := &Codec{ 166 sha256: sha256.New(), 167 localnode: ln, 168 privkey: key, 169 sc: NewSessionCache(1024, clock), 170 protocolID: DefaultProtocolID, 171 decbuf: make([]byte, maxPacketSize), 172 } 173 if protocolID != nil { 174 c.protocolID = *protocolID 175 } 176 return c 177 } 178 179 // Encode encodes a packet to a node. 'id' and 'addr' specify the destination node. The 180 // 'challenge' parameter should be the most recently received WHOAREYOU packet from that 181 // node. 182 func (c *Codec) Encode(id enode.ID, addr string, packet Packet, challenge *Whoareyou) ([]byte, Nonce, error) { 183 // Create the packet header. 184 var ( 185 head Header 186 session *session 187 msgData []byte 188 err error 189 ) 190 switch { 191 case packet.Kind() == WhoareyouPacket: 192 // just send the WHOAREYOU packet raw again, rather than the re-encoded challenge data 193 w := packet.(*Whoareyou) 194 if len(w.Encoded) > 0 { 195 return w.Encoded, w.Nonce, nil 196 } 197 head, err = c.encodeWhoareyou(id, packet.(*Whoareyou)) 198 case challenge != nil: 199 // We have an unanswered challenge, send handshake. 200 head, session, err = c.encodeHandshakeHeader(id, addr, challenge) 201 default: 202 session = c.sc.session(id, addr) 203 if session != nil { 204 // There is a session, use it. 205 head, err = c.encodeMessageHeader(id, session) 206 } else { 207 // No keys, send random data to kick off the handshake. 208 head, msgData, err = c.encodeRandom(id) 209 } 210 } 211 if err != nil { 212 return nil, Nonce{}, err 213 } 214 215 // Generate masking IV. 216 if err := c.sc.maskingIVGen(head.IV[:]); err != nil { 217 return nil, Nonce{}, fmt.Errorf("can't generate masking IV: %v", err) 218 } 219 220 // Encode header data. 221 c.writeHeaders(&head) 222 223 // Store sent WHOAREYOU challenges. 224 if challenge, ok := packet.(*Whoareyou); ok { 225 challenge.ChallengeData = bytesCopy(&c.buf) 226 enc, err := c.EncodeRaw(id, head, msgData) 227 if err != nil { 228 return nil, Nonce{}, err 229 } 230 challenge.Encoded = bytes.Clone(enc) 231 c.sc.storeSentHandshake(id, addr, challenge) 232 return enc, head.Nonce, err 233 } 234 235 if msgData == nil { 236 headerData := c.buf.Bytes() 237 msgData, err = c.encryptMessage(session, packet, &head, headerData) 238 if err != nil { 239 return nil, Nonce{}, err 240 } 241 } 242 enc, err := c.EncodeRaw(id, head, msgData) 243 return enc, head.Nonce, err 244 } 245 246 // EncodeRaw encodes a packet with the given header. 247 func (c *Codec) EncodeRaw(id enode.ID, head Header, msgdata []byte) ([]byte, error) { 248 c.writeHeaders(&head) 249 250 // Apply masking. 251 masked := c.buf.Bytes()[sizeofMaskingIV:] 252 mask := head.mask(id) 253 mask.XORKeyStream(masked[:], masked[:]) 254 255 // Write message data. 256 c.buf.Write(msgdata) 257 return c.buf.Bytes(), nil 258 } 259 260 // CurrentChallenge returns the latest challenge sent to the given node. 261 // This will return non-nil while a handshake is in progress. 262 func (c *Codec) CurrentChallenge(id enode.ID, addr string) *Whoareyou { 263 return c.sc.getHandshake(id, addr) 264 } 265 266 func (c *Codec) writeHeaders(head *Header) { 267 c.buf.Reset() 268 c.buf.Write(head.IV[:]) 269 binary.Write(&c.buf, binary.BigEndian, &head.StaticHeader) 270 c.buf.Write(head.AuthData) 271 } 272 273 // makeHeader creates a packet header. 274 func (c *Codec) makeHeader(toID enode.ID, flag byte, authsizeExtra int) Header { 275 var authsize int 276 switch flag { 277 case flagMessage: 278 authsize = sizeofMessageAuthData 279 case flagWhoareyou: 280 authsize = sizeofWhoareyouAuthData 281 case flagHandshake: 282 authsize = sizeofHandshakeAuthData 283 default: 284 panic(fmt.Errorf("BUG: invalid packet header flag %x", flag)) 285 } 286 authsize += authsizeExtra 287 if authsize > int(^uint16(0)) { 288 panic(fmt.Errorf("BUG: auth size %d overflows uint16", authsize)) 289 } 290 return Header{ 291 StaticHeader: StaticHeader{ 292 ProtocolID: c.protocolID, 293 Version: version, 294 Flag: flag, 295 AuthSize: uint16(authsize), 296 }, 297 } 298 } 299 300 // encodeRandom encodes a packet with random content. 301 func (c *Codec) encodeRandom(toID enode.ID) (Header, []byte, error) { 302 head := c.makeHeader(toID, flagMessage, 0) 303 304 // Encode auth data. 305 auth := messageAuthData{SrcID: c.localnode.ID()} 306 if _, err := crand.Read(head.Nonce[:]); err != nil { 307 return head, nil, fmt.Errorf("can't get random data: %v", err) 308 } 309 c.headbuf.Reset() 310 binary.Write(&c.headbuf, binary.BigEndian, auth) 311 head.AuthData = c.headbuf.Bytes() 312 313 // Fill message ciphertext buffer with random bytes. 314 c.msgctbuf = append(c.msgctbuf[:0], make([]byte, randomPacketMsgSize)...) 315 crand.Read(c.msgctbuf) 316 return head, c.msgctbuf, nil 317 } 318 319 // encodeWhoareyou encodes a WHOAREYOU packet. 320 func (c *Codec) encodeWhoareyou(toID enode.ID, packet *Whoareyou) (Header, error) { 321 // Sanity check node field to catch misbehaving callers. 322 if packet.RecordSeq > 0 && packet.Node == nil { 323 panic("BUG: missing node in whoareyou with non-zero seq") 324 } 325 326 // Create header. 327 head := c.makeHeader(toID, flagWhoareyou, 0) 328 head.AuthData = bytesCopy(&c.buf) 329 head.Nonce = packet.Nonce 330 331 // Encode auth data. 332 auth := &whoareyouAuthData{ 333 IDNonce: packet.IDNonce, 334 RecordSeq: packet.RecordSeq, 335 } 336 c.headbuf.Reset() 337 binary.Write(&c.headbuf, binary.BigEndian, auth) 338 head.AuthData = c.headbuf.Bytes() 339 return head, nil 340 } 341 342 // encodeHandshakeHeader encodes the handshake message packet header. 343 func (c *Codec) encodeHandshakeHeader(toID enode.ID, addr string, challenge *Whoareyou) (Header, *session, error) { 344 // Ensure calling code sets challenge.node. 345 if challenge.Node == nil { 346 panic("BUG: missing challenge.Node in encode") 347 } 348 349 // Generate new secrets. 350 auth, session, err := c.makeHandshakeAuth(toID, addr, challenge) 351 if err != nil { 352 return Header{}, nil, err 353 } 354 355 // Generate nonce for message. 356 nonce, err := c.sc.nextNonce(session) 357 if err != nil { 358 return Header{}, nil, fmt.Errorf("can't generate nonce: %v", err) 359 } 360 361 // TODO: this should happen when the first authenticated message is received 362 c.sc.storeNewSession(toID, addr, session, challenge.Node) 363 364 // Encode the auth header. 365 var ( 366 authsizeExtra = len(auth.pubkey) + len(auth.signature) + len(auth.record) 367 head = c.makeHeader(toID, flagHandshake, authsizeExtra) 368 ) 369 c.headbuf.Reset() 370 binary.Write(&c.headbuf, binary.BigEndian, &auth.h) 371 c.headbuf.Write(auth.signature) 372 c.headbuf.Write(auth.pubkey) 373 c.headbuf.Write(auth.record) 374 head.AuthData = c.headbuf.Bytes() 375 head.Nonce = nonce 376 return head, session, err 377 } 378 379 // makeHandshakeAuth creates the auth header on a request packet following WHOAREYOU. 380 func (c *Codec) makeHandshakeAuth(toID enode.ID, addr string, challenge *Whoareyou) (*handshakeAuthData, *session, error) { 381 auth := new(handshakeAuthData) 382 auth.h.SrcID = c.localnode.ID() 383 384 // Create the ephemeral key. This needs to be first because the 385 // key is part of the ID nonce signature. 386 var remotePubkey = new(ecdsa.PublicKey) 387 if err := challenge.Node.Load((*enode.Secp256k1)(remotePubkey)); err != nil { 388 return nil, nil, errors.New("can't find secp256k1 key for recipient") 389 } 390 ephkey, err := c.sc.ephemeralKeyGen() 391 if err != nil { 392 return nil, nil, errors.New("can't generate ephemeral key") 393 } 394 ephpubkey := EncodePubkey(&ephkey.PublicKey) 395 auth.pubkey = ephpubkey[:] 396 auth.h.PubkeySize = byte(len(auth.pubkey)) 397 398 // Add ID nonce signature to response. 399 cdata := challenge.ChallengeData 400 idsig, err := makeIDSignature(c.sha256, c.privkey, cdata, ephpubkey[:], toID) 401 if err != nil { 402 return nil, nil, fmt.Errorf("can't sign: %v", err) 403 } 404 auth.signature = idsig 405 auth.h.SigSize = byte(len(auth.signature)) 406 407 // Add our record to response if it's newer than what remote side has. 408 ln := c.localnode.Node() 409 if challenge.RecordSeq < ln.Seq() { 410 auth.record, _ = rlp.EncodeToBytes(ln.Record()) 411 } 412 413 // Create session keys. 414 sec := deriveKeys(sha256.New, ephkey, remotePubkey, c.localnode.ID(), challenge.Node.ID(), cdata) 415 if sec == nil { 416 return nil, nil, errors.New("key derivation failed") 417 } 418 return auth, sec, err 419 } 420 421 // encodeMessageHeader encodes an encrypted message packet. 422 func (c *Codec) encodeMessageHeader(toID enode.ID, s *session) (Header, error) { 423 head := c.makeHeader(toID, flagMessage, 0) 424 425 // Create the header. 426 nonce, err := c.sc.nextNonce(s) 427 if err != nil { 428 return Header{}, fmt.Errorf("can't generate nonce: %v", err) 429 } 430 auth := messageAuthData{SrcID: c.localnode.ID()} 431 c.buf.Reset() 432 binary.Write(&c.buf, binary.BigEndian, &auth) 433 head.AuthData = bytesCopy(&c.buf) 434 head.Nonce = nonce 435 return head, err 436 } 437 438 func (c *Codec) encryptMessage(s *session, p Packet, head *Header, headerData []byte) ([]byte, error) { 439 // Encode message plaintext. 440 c.msgbuf.Reset() 441 c.msgbuf.WriteByte(p.Kind()) 442 if err := rlp.Encode(&c.msgbuf, p); err != nil { 443 return nil, err 444 } 445 messagePT := c.msgbuf.Bytes() 446 447 // Encrypt into message ciphertext buffer. 448 messageCT, err := encryptGCM(c.msgctbuf[:0], s.writeKey, head.Nonce[:], messagePT, headerData) 449 if err == nil { 450 c.msgctbuf = messageCT 451 } 452 return messageCT, err 453 } 454 455 // Decode decodes a discovery packet. 456 func (c *Codec) Decode(inputData []byte, addr string) (src enode.ID, n *enode.Node, p Packet, err error) { 457 if len(inputData) < minPacketSize { 458 return enode.ID{}, nil, nil, errTooShort 459 } 460 // Copy the packet to a tmp buffer to avoid modifying it. 461 c.decbuf = append(c.decbuf[:0], inputData...) 462 input := c.decbuf 463 // Unmask the static header. 464 var head Header 465 copy(head.IV[:], input[:sizeofMaskingIV]) 466 mask := head.mask(c.localnode.ID()) 467 staticHeader := input[sizeofMaskingIV:sizeofStaticPacketData] 468 mask.XORKeyStream(staticHeader, staticHeader) 469 470 // Decode and verify the static header. 471 c.reader.Reset(staticHeader) 472 binary.Read(&c.reader, binary.BigEndian, &head.StaticHeader) 473 remainingInput := len(input) - sizeofStaticPacketData 474 if err := head.checkValid(remainingInput, c.protocolID); err != nil { 475 return enode.ID{}, nil, nil, err 476 } 477 478 // Unmask auth data. 479 authDataEnd := sizeofStaticPacketData + int(head.AuthSize) 480 authData := input[sizeofStaticPacketData:authDataEnd] 481 mask.XORKeyStream(authData, authData) 482 head.AuthData = authData 483 484 // Delete timed-out handshakes. This must happen before decoding to avoid 485 // processing the same handshake twice. 486 c.sc.handshakeGC() 487 488 // Decode auth part and message. 489 headerData := input[:authDataEnd] 490 msgData := input[authDataEnd:] 491 switch head.Flag { 492 case flagWhoareyou: 493 p, err = c.decodeWhoareyou(&head, headerData) 494 case flagHandshake: 495 n, p, err = c.decodeHandshakeMessage(addr, &head, headerData, msgData) 496 case flagMessage: 497 p, err = c.decodeMessage(addr, &head, headerData, msgData) 498 default: 499 err = errInvalidFlag 500 } 501 return head.src, n, p, err 502 } 503 504 // decodeWhoareyou reads packet data after the header as a WHOAREYOU packet. 505 func (c *Codec) decodeWhoareyou(head *Header, headerData []byte) (Packet, error) { 506 if len(head.AuthData) != sizeofWhoareyouAuthData { 507 return nil, fmt.Errorf("invalid auth size %d for WHOAREYOU", len(head.AuthData)) 508 } 509 var auth whoareyouAuthData 510 c.reader.Reset(head.AuthData) 511 binary.Read(&c.reader, binary.BigEndian, &auth) 512 p := &Whoareyou{ 513 Nonce: head.Nonce, 514 IDNonce: auth.IDNonce, 515 RecordSeq: auth.RecordSeq, 516 ChallengeData: make([]byte, len(headerData)), 517 } 518 copy(p.ChallengeData, headerData) 519 return p, nil 520 } 521 522 func (c *Codec) decodeHandshakeMessage(fromAddr string, head *Header, headerData, msgData []byte) (n *enode.Node, p Packet, err error) { 523 node, auth, session, err := c.decodeHandshake(fromAddr, head) 524 if err != nil { 525 c.sc.deleteHandshake(auth.h.SrcID, fromAddr) 526 return nil, nil, err 527 } 528 529 // Decrypt the message using the new session keys. 530 msg, err := c.decryptMessage(msgData, head.Nonce[:], headerData, session.readKey) 531 if err != nil { 532 c.sc.deleteHandshake(auth.h.SrcID, fromAddr) 533 return node, msg, err 534 } 535 536 // Handshake OK, drop the challenge and store the new session keys. 537 c.sc.storeNewSession(auth.h.SrcID, fromAddr, session, node) 538 c.sc.deleteHandshake(auth.h.SrcID, fromAddr) 539 return node, msg, nil 540 } 541 542 func (c *Codec) decodeHandshake(fromAddr string, head *Header) (n *enode.Node, auth handshakeAuthData, s *session, err error) { 543 if auth, err = c.decodeHandshakeAuthData(head); err != nil { 544 return nil, auth, nil, err 545 } 546 547 // Verify against our last WHOAREYOU. 548 challenge := c.sc.getHandshake(auth.h.SrcID, fromAddr) 549 if challenge == nil { 550 return nil, auth, nil, errUnexpectedHandshake 551 } 552 // Get node record. 553 n, err = c.decodeHandshakeRecord(challenge.Node, auth.h.SrcID, auth.record) 554 if err != nil { 555 return nil, auth, nil, err 556 } 557 // Verify ID nonce signature. 558 sig := auth.signature 559 cdata := challenge.ChallengeData 560 err = verifyIDSignature(c.sha256, sig, n, cdata, auth.pubkey, c.localnode.ID()) 561 if err != nil { 562 return nil, auth, nil, err 563 } 564 // Verify ephemeral key is on curve. 565 ephkey, err := DecodePubkey(c.privkey.Curve, auth.pubkey) 566 if err != nil { 567 return nil, auth, nil, errInvalidAuthKey 568 } 569 // Derive session keys. 570 session := deriveKeys(sha256.New, c.privkey, ephkey, auth.h.SrcID, c.localnode.ID(), cdata) 571 session = session.keysFlipped() 572 return n, auth, session, nil 573 } 574 575 // decodeHandshakeAuthData reads the authdata section of a handshake packet. 576 func (c *Codec) decodeHandshakeAuthData(head *Header) (auth handshakeAuthData, err error) { 577 // Decode fixed size part. 578 if len(head.AuthData) < sizeofHandshakeAuthData { 579 return auth, fmt.Errorf("header authsize %d too low for handshake", head.AuthSize) 580 } 581 c.reader.Reset(head.AuthData) 582 binary.Read(&c.reader, binary.BigEndian, &auth.h) 583 head.src = auth.h.SrcID 584 585 // Decode variable-size part. 586 var ( 587 vardata = head.AuthData[sizeofHandshakeAuthData:] 588 sigAndKeySize = int(auth.h.SigSize) + int(auth.h.PubkeySize) 589 keyOffset = int(auth.h.SigSize) 590 recOffset = keyOffset + int(auth.h.PubkeySize) 591 ) 592 if len(vardata) < sigAndKeySize { 593 return auth, errTooShort 594 } 595 auth.signature = vardata[:keyOffset] 596 auth.pubkey = vardata[keyOffset:recOffset] 597 auth.record = vardata[recOffset:] 598 return auth, nil 599 } 600 601 // decodeHandshakeRecord verifies the node record contained in a handshake packet. The 602 // remote node should include the record if we don't have one or if ours is older than the 603 // latest sequence number. 604 func (c *Codec) decodeHandshakeRecord(local *enode.Node, wantID enode.ID, remote []byte) (*enode.Node, error) { 605 node := local 606 if len(remote) > 0 { 607 var record enr.Record 608 if err := rlp.DecodeBytes(remote, &record); err != nil { 609 return nil, err 610 } 611 if local == nil || local.Seq() < record.Seq() { 612 n, err := enode.New(enode.ValidSchemes, &record) 613 if err != nil { 614 return nil, fmt.Errorf("invalid node record: %v", err) 615 } 616 if n.ID() != wantID { 617 return nil, fmt.Errorf("record in handshake has wrong ID: %v", n.ID()) 618 } 619 node = n 620 } 621 } 622 if node == nil { 623 return nil, errNoRecord 624 } 625 return node, nil 626 } 627 628 // decodeMessage reads packet data following the header as an ordinary message packet. 629 func (c *Codec) decodeMessage(fromAddr string, head *Header, headerData, msgData []byte) (Packet, error) { 630 if len(head.AuthData) != sizeofMessageAuthData { 631 return nil, fmt.Errorf("invalid auth size %d for message packet", len(head.AuthData)) 632 } 633 var auth messageAuthData 634 c.reader.Reset(head.AuthData) 635 binary.Read(&c.reader, binary.BigEndian, &auth) 636 head.src = auth.SrcID 637 638 // Try decrypting the message. 639 key := c.sc.readKey(auth.SrcID, fromAddr) 640 msg, err := c.decryptMessage(msgData, head.Nonce[:], headerData, key) 641 if errors.Is(err, errMessageDecrypt) { 642 // It didn't work. Start the handshake since this is an ordinary message packet. 643 return &Unknown{Nonce: head.Nonce}, nil 644 } 645 return msg, err 646 } 647 648 func (c *Codec) decryptMessage(input, nonce, headerData, readKey []byte) (Packet, error) { 649 msgdata, err := decryptGCM(readKey, nonce, input, headerData) 650 if err != nil { 651 return nil, errMessageDecrypt 652 } 653 if len(msgdata) == 0 { 654 return nil, errMessageTooShort 655 } 656 return DecodeMessage(msgdata[0], msgdata[1:]) 657 } 658 659 func (c *Codec) SessionNode(id enode.ID, addr string) *enode.Node { 660 return c.sc.readNode(id, addr) 661 } 662 663 // checkValid performs some basic validity checks on the header. 664 // The packetLen here is the length remaining after the static header. 665 func (h *StaticHeader) checkValid(packetLen int, protocolID [6]byte) error { 666 if h.ProtocolID != protocolID { 667 return errInvalidHeader 668 } 669 if h.Version < minVersion { 670 return errMinVersion 671 } 672 if h.Flag != flagWhoareyou && packetLen < minMessageSize { 673 return errMsgTooShort 674 } 675 if int(h.AuthSize) > packetLen { 676 return errAuthSize 677 } 678 return nil 679 } 680 681 // mask returns a cipher for 'masking' / 'unmasking' packet headers. 682 func (h *Header) mask(destID enode.ID) cipher.Stream { 683 block, err := aes.NewCipher(destID[:16]) 684 if err != nil { 685 panic("can't create cipher") 686 } 687 return cipher.NewCTR(block, h.IV[:]) 688 } 689 690 func bytesCopy(r *bytes.Buffer) []byte { 691 b := make([]byte, r.Len()) 692 copy(b, r.Bytes()) 693 return b 694 }