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