...

Source file src/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go

Documentation: github.com/ProtonMail/go-crypto/openpgp/packet

     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  
     5  package packet
     6  
     7  import (
     8  	"io"
     9  
    10  	"github.com/ProtonMail/go-crypto/openpgp/errors"
    11  )
    12  
    13  const 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.
    18  type 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  
    33  const (
    34  	symmetricallyEncryptedVersionMdc  = 1
    35  	symmetricallyEncryptedVersionAead = 2
    36  )
    37  
    38  func (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.
    66  func (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 config is nil, sensible defaults will be used.
    78  func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, aeadSupported bool, cipherSuite CipherSuite, key []byte, config *Config) (Contents io.WriteCloser, err error) {
    79  	writeCloser := noOpCloser{w}
    80  	ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedIntegrityProtected)
    81  	if err != nil {
    82  		return
    83  	}
    84  
    85  	if aeadSupported {
    86  		return serializeSymmetricallyEncryptedAead(ciphertext, cipherSuite, config.AEADConfig.ChunkSizeByte(), config.Random(), key)
    87  	}
    88  
    89  	return serializeSymmetricallyEncryptedMdc(ciphertext, c, key, config)
    90  }
    91  

View as plain text