crypto

package
v0.0.0-...-6b3dfbf Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2018 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package crypto implements AWS S3 related cryptographic building blocks for implementing Server-Side-Encryption (SSE-S3) and Server-Side-Encryption with customer provided keys (SSE-C).

All objects are encrypted with an unique and randomly generated 'ObjectKey'. The ObjectKey itself is never stored in plaintext. Instead it is only stored in a sealed from. The sealed 'ObjectKey' is created by encrypting the 'ObjectKey' with an unique key-encryption-key. Given the correct key-encryption-key the sealed 'ObjectKey' can be unsealed and the object can be decrypted.

## SSE-C

SSE-C computes the key-encryption-key from the client-provided key, an initialization vector (IV) and the bucket/object path.

  1. Encrypt: Input: ClientKey, bucket, object, metadata, object_data - IV := Random({0,1}²⁵⁶) - ObjectKey := SHA256(ClientKey || Random({0,1}²⁵⁶)) - KeyEncKey := HMAC-SHA256(ClientKey, IV || bucket || object) - SealedKey := DAREv2_Enc(KeyEncKey, ObjectKey) - enc_object_data := DAREv2_Enc(ObjectKey, object_data) - metadata <- IV - metadata <- SealedKey Output: enc_object_data, metadata
  1. Decrypt: Input: ClientKey, bucket, object, metadata, enc_object_data - IV <- metadata - SealedKey <- metadata - KeyEncKey := HMAC-SHA256(ClientKey, IV || bucket || object) - ObjectKey := DAREv2_Dec(KeyEncKey, SealedKey) - object_data := DAREv2_Dec(ObjectKey, enc_object_data) Output: object_data

## SSE-S3

SSE-S3 can use either a master key or a KMS as root-of-trust. The en/decryption slightly depens upon which root-of-trust is used.

### SSE-S3 and single master key

The master key is used to derive unique object- and key-encryption-keys. SSE-S3 with a single master key works as SSE-C where the master key is used as the client-provided key.

  1. Encrypt: Input: MasterKey, bucket, object, metadata, object_data - IV := Random({0,1}²⁵⁶) - ObjectKey := SHA256(MasterKey || Random({0,1}²⁵⁶)) - KeyEncKey := HMAC-SHA256(MasterKey, IV || bucket || object) - SealedKey := DAREv2_Enc(KeyEncKey, ObjectKey) - enc_object_data := DAREv2_Enc(ObjectKey, object_data) - metadata <- IV - metadata <- SealedKey Output: enc_object_data, metadata
  1. Decrypt: Input: MasterKey, bucket, object, metadata, enc_object_data - IV <- metadata - SealedKey <- metadata - KeyEncKey := HMAC-SHA256(MasterKey, IV || bucket || object) - ObjectKey := DAREv2_Dec(KeyEncKey, SealedKey) - object_data := DAREv2_Dec(ObjectKey, enc_object_data) Output: object_data

### SSE-S3 and KMS

SSE-S3 requires that the KMS provides two functions:

  1. Generate(KeyID) -> (Key, EncKey)
  2. Unseal(KeyID, EncKey) -> Key
  1. Encrypt: Input: KeyID, bucket, object, metadata, object_data - Key, EncKey := Generate(KeyID) - IV := Random({0,1}²⁵⁶) - ObjectKey := SHA256(Key, Random({0,1}²⁵⁶)) - KeyEncKey := HMAC-SHA256(Key, IV || bucket || object) - SealedKey := DAREv2_Enc(KeyEncKey, ObjectKey) - enc_object_data := DAREv2_Enc(ObjectKey, object_data) - metadata <- IV - metadata <- KeyID - metadata <- EncKey - metadata <- SealedKey Output: enc_object_data, metadata
  1. Decrypt: Input: bucket, object, metadata, enc_object_data - KeyID <- metadata - EncKey <- metadata - IV <- metadata - SealedKey <- metadata - Key := Unseal(KeyID, EncKey) - KeyEncKey := HMAC-SHA256(Key, IV || bucket || object) - ObjectKey := DAREv2_Dec(KeyEncKey, SealedKey) - object_data := DAREv2_Dec(ObjectKey, enc_object_data) Output: object_data

Index

Constants

View Source
const (
	// S3SealedKey is the metadata key referencing the sealed object-key for SSE-S3.
	S3SealedKey = "X-Minio-Internal-Server-Side-Encryption-S3-Sealed-Key"
	// S3KMSKeyID is the metadata key referencing the KMS key-id used to
	// generate/decrypt the S3-KMS-Sealed-Key. It is only used for SSE-S3 + KMS.
	S3KMSKeyID = "X-Minio-Internal-Server-Side-Encryption-S3-Kms-Key-Id"
	// S3KMSSealedKey is the metadata key referencing the encrypted key generated
	// by KMS. It is only used for SSE-S3 + KMS.
	S3KMSSealedKey = "X-Minio-Internal-Server-Side-Encryption-S3-Kms-Sealed-Key"
)
View Source
const SSEAlgorithmAES256 = "AES256"

SSEAlgorithmAES256 is the only supported value for the SSE-S3 or SSE-C algorithm header. For SSE-S3 see: https://docs.aws.amazon.com/AmazonS3/latest/dev/SSEUsingRESTAPI.html For SSE-C see: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html

View Source
const SSEHeader = "X-Amz-Server-Side-Encryption"

SSEHeader is the general AWS SSE HTTP header key.

Variables

View Source
var (
	// ErrInvalidEncryptionMethod indicates that the specified SSE encryption method
	// is not supported.
	ErrInvalidEncryptionMethod = errors.New("The encryption method is not supported")
)
View Source
var S3 = s3{}

S3 represents AWS SSE-S3. It provides functionality to handle SSE-S3 requests.

Functions

func DecryptSinglePart

func DecryptSinglePart(w io.Writer, offset, length int64, key ObjectKey) io.WriteCloser

DecryptSinglePart decrypts an io.Writer which must an object uploaded with the single-part PUT API. The offset and length specify the requested range.

func EncryptSinglePart

func EncryptSinglePart(r io.Reader, key ObjectKey) io.Reader

EncryptSinglePart encrypts an io.Reader which must be the the body of a single-part PUT request.

Types

type ObjectKey

type ObjectKey [32]byte

ObjectKey is a 256 bit secret key used to encrypt the object. It must never be stored in plaintext.

func GenerateKey

func GenerateKey(extKey [32]byte, random io.Reader) (key ObjectKey)

GenerateKey generates a unique ObjectKey from a 256 bit external key and a source of randomness. If random is nil the default PRNG of system (crypto/rand) is used.

func (ObjectKey) DerivePartKey

func (key ObjectKey) DerivePartKey(id uint32) (partKey [32]byte)

DerivePartKey derives an unique 256 bit key from an ObjectKey and the part index.

func (ObjectKey) Seal

func (key ObjectKey) Seal(extKey, iv [32]byte, bucket, object string) []byte

Seal encrypts the ObjectKey using the 256 bit external key and IV. The sealed key is also cryptographically bound to the object's path (bucket/object).

func (*ObjectKey) Unseal

func (key *ObjectKey) Unseal(sealedKey []byte, extKey, iv [32]byte, bucket, object string) error

Unseal decrypts a sealed key using the 256 bit external key and IV. Since the sealed key is cryptographically bound to the object's path the same bucket/object as during sealing must be provided. On success the ObjectKey contains the decrypted sealed key.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL