main
1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package packet
6
7import (
8 "io"
9
10 "github.com/ProtonMail/go-crypto/openpgp/errors"
11)
12
13const aeadSaltSize = 32
14
15// SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
16// encrypted Contents will consist of more OpenPGP packets. See RFC 4880,
17// sections 5.7 and 5.13.
18type SymmetricallyEncrypted struct {
19 Version int
20 Contents io.Reader // contains tag for version 2
21 IntegrityProtected bool // If true it is type 18 (with MDC or AEAD). False is packet type 9
22
23 // Specific to version 1
24 prefix []byte
25
26 // Specific to version 2
27 Cipher CipherFunction
28 Mode AEADMode
29 ChunkSizeByte byte
30 Salt [aeadSaltSize]byte
31}
32
33const (
34 symmetricallyEncryptedVersionMdc = 1
35 symmetricallyEncryptedVersionAead = 2
36)
37
38func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
39 if se.IntegrityProtected {
40 // See RFC 4880, section 5.13.
41 var buf [1]byte
42 _, err := readFull(r, buf[:])
43 if err != nil {
44 return err
45 }
46
47 switch buf[0] {
48 case symmetricallyEncryptedVersionMdc:
49 se.Version = symmetricallyEncryptedVersionMdc
50 case symmetricallyEncryptedVersionAead:
51 se.Version = symmetricallyEncryptedVersionAead
52 if err := se.parseAead(r); err != nil {
53 return err
54 }
55 default:
56 return errors.UnsupportedError("unknown SymmetricallyEncrypted version")
57 }
58 }
59 se.Contents = r
60 return nil
61}
62
63// Decrypt returns a ReadCloser, from which the decrypted Contents of the
64// packet can be read. An incorrect key will only be detected after trying
65// to decrypt the entire data.
66func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
67 if se.Version == symmetricallyEncryptedVersionAead {
68 return se.decryptAead(key)
69 }
70
71 return se.decryptMdc(c, key)
72}
73
74// SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
75// to w and returns a WriteCloser to which the to-be-encrypted packets can be
76// written.
77// If aeadSupported is set to true, SEIPDv2 is used with the indicated CipherSuite.
78// Otherwise, SEIPDv1 is used with the indicated CipherFunction.
79// Note: aeadSupported MUST match the value passed to SerializeEncryptedKeyAEAD
80// and/or SerializeSymmetricKeyEncryptedAEADReuseKey.
81// If config is nil, sensible defaults will be used.
82func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, aeadSupported bool, cipherSuite CipherSuite, key []byte, config *Config) (Contents io.WriteCloser, err error) {
83 writeCloser := noOpCloser{w}
84 ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedIntegrityProtected)
85 if err != nil {
86 return
87 }
88
89 if aeadSupported {
90 return serializeSymmetricallyEncryptedAead(ciphertext, cipherSuite, config.AEADConfig.ChunkSizeByte(), config.Random(), key)
91 }
92
93 return serializeSymmetricallyEncryptedMdc(ciphertext, c, key, config)
94}