main
Raw Download raw file
 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}