encrypt encrypts payload, adding the appropriate nonce and/or MAC, and appends it to record, which must already contain the record header.
(record, payload []byte, rand io.Reader)
| 485 | // encrypt encrypts payload, adding the appropriate nonce and/or MAC, and |
| 486 | // appends it to record, which must already contain the record header. |
| 487 | func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) { |
| 488 | if hc.cipher == nil { |
| 489 | return append(record, payload...), nil |
| 490 | } |
| 491 | |
| 492 | var explicitNonce []byte |
| 493 | if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 { |
| 494 | record, explicitNonce = sliceForAppend(record, explicitNonceLen) |
| 495 | if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 { |
| 496 | // The AES-GCM construction in TLS has an explicit nonce so that the |
| 497 | // nonce can be random. However, the nonce is only 8 bytes which is |
| 498 | // too small for a secure, random nonce. Therefore we use the |
| 499 | // sequence number as the nonce. The 3DES-CBC construction also has |
| 500 | // an 8 bytes nonce but its nonces must be unpredictable (see RFC |
| 501 | // 5246, Appendix F.3), forcing us to use randomness. That's not |
| 502 | // 3DES' biggest problem anyway because the birthday bound on block |
| 503 | // collision is reached first due to its similarly small block size |
| 504 | // (see the Sweet32 attack). |
| 505 | copy(explicitNonce, hc.seq[:]) |
| 506 | } else { |
| 507 | if _, err := io.ReadFull(rand, explicitNonce); err != nil { |
| 508 | return nil, err |
| 509 | } |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | var dst []byte |
| 514 | switch c := hc.cipher.(type) { |
| 515 | case cipher.Stream: |
| 516 | mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) |
| 517 | record, dst = sliceForAppend(record, len(payload)+len(mac)) |
| 518 | c.XORKeyStream(dst[:len(payload)], payload) |
| 519 | c.XORKeyStream(dst[len(payload):], mac) |
| 520 | case aead: |
| 521 | nonce := explicitNonce |
| 522 | if len(nonce) == 0 { |
| 523 | nonce = hc.seq[:] |
| 524 | } |
| 525 | |
| 526 | if hc.version == VersionTLS13 { |
| 527 | record = append(record, payload...) |
| 528 | |
| 529 | // Encrypt the actual ContentType and replace the plaintext one. |
| 530 | record = append(record, record[0]) |
| 531 | padding := 0 |
| 532 | if recordType(record[0]) == recordTypeHandshake && hc.handshakeLen[1] != 0 { |
| 533 | switch payload[0] { |
| 534 | case typeEncryptedExtensions: |
| 535 | padding = hc.handshakeLen[2] |
| 536 | hc.handshakeLen[2] = 0 |
| 537 | case typeCertificate: |
| 538 | padding = hc.handshakeLen[3] |
| 539 | hc.handshakeLen[3] = 0 |
| 540 | case typeCertificateVerify: |
| 541 | padding = hc.handshakeLen[4] |
| 542 | hc.handshakeLen[4] = 0 |
| 543 | case typeFinished: |
| 544 | padding = hc.handshakeLen[5] |
no test coverage detected