github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/crypto/doc.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  // Package crypto implements AWS S3 related cryptographic building blocks
    19  // for implementing Server-Side-Encryption (SSE-S3) and Server-Side-Encryption
    20  // with customer provided keys (SSE-C).
    21  //
    22  // All objects are encrypted with an unique and randomly generated 'ObjectKey'.
    23  // The ObjectKey itself is never stored in plaintext. Instead it is only stored
    24  // in a sealed from. The sealed 'ObjectKey' is created by encrypting the 'ObjectKey'
    25  // with an unique key-encryption-key. Given the correct key-encryption-key the
    26  // sealed 'ObjectKey' can be unsealed and the object can be decrypted.
    27  //
    28  // ## SSE-C
    29  //
    30  // SSE-C computes the key-encryption-key from the client-provided key, an
    31  // initialization vector (IV) and the bucket/object path.
    32  //
    33  //  1. Encrypt:
    34  //     Input: ClientKey, bucket, object, metadata, object_data
    35  //     -              IV := Random({0,1}²⁵⁶)
    36  //     -       ObjectKey := SHA256(ClientKey || Random({0,1}²⁵⁶))
    37  //     -       KeyEncKey := HMAC-SHA256(ClientKey, IV || 'SSE-C' || 'DAREv2-HMAC-SHA256' || bucket || '/' || object)
    38  //     -       SealedKey := DAREv2_Enc(KeyEncKey, ObjectKey)
    39  //     - enc_object_data := DAREv2_Enc(ObjectKey, object_data)
    40  //     -        metadata <- IV
    41  //     -        metadata <- SealedKey
    42  //     Output: enc_object_data, metadata
    43  //
    44  //  2. Decrypt:
    45  //     Input: ClientKey, bucket, object, metadata, enc_object_data
    46  //     -          IV <- metadata
    47  //     -   SealedKey <- metadata
    48  //     -   KeyEncKey := HMAC-SHA256(ClientKey, IV || 'SSE-C' || 'DAREv2-HMAC-SHA256' || bucket || '/' || object)
    49  //     -   ObjectKey := DAREv2_Dec(KeyEncKey, SealedKey)
    50  //     - object_data := DAREv2_Dec(ObjectKey, enc_object_data)
    51  //     Output: object_data
    52  //
    53  // ## SSE-S3
    54  //
    55  // SSE-S3 can use either a master key or a KMS as root-of-trust.
    56  // The en/decryption slightly depens upon which root-of-trust is used.
    57  //
    58  // ### SSE-S3 and single master key
    59  //
    60  // The master key is used to derive unique object- and key-encryption-keys.
    61  // SSE-S3 with a single master key works as SSE-C where the master key is
    62  // used as the client-provided key.
    63  //
    64  //  1. Encrypt:
    65  //     Input: MasterKey, bucket, object, metadata, object_data
    66  //     -              IV := Random({0,1}²⁵⁶)
    67  //     -       ObjectKey := SHA256(MasterKey || Random({0,1}²⁵⁶))
    68  //     -       KeyEncKey := HMAC-SHA256(MasterKey, IV || 'SSE-S3' || 'DAREv2-HMAC-SHA256' || bucket || '/' || object)
    69  //     -       SealedKey := DAREv2_Enc(KeyEncKey, ObjectKey)
    70  //     - enc_object_data := DAREv2_Enc(ObjectKey, object_data)
    71  //     -        metadata <- IV
    72  //     -        metadata <- SealedKey
    73  //     Output: enc_object_data, metadata
    74  //
    75  //  2. Decrypt:
    76  //     Input: MasterKey, bucket, object, metadata, enc_object_data
    77  //     -          IV <- metadata
    78  //     -   SealedKey <- metadata
    79  //     -   KeyEncKey := HMAC-SHA256(MasterKey, IV || 'SSE-S3' || 'DAREv2-HMAC-SHA256' || bucket || '/' || object)
    80  //     -   ObjectKey := DAREv2_Dec(KeyEncKey, SealedKey)
    81  //     - object_data := DAREv2_Dec(ObjectKey, enc_object_data)
    82  //     Output: object_data
    83  //
    84  // ### SSE-S3 and KMS
    85  //
    86  // SSE-S3 requires that the KMS provides two functions:
    87  //
    88  //  1. Generate(KeyID) -> (Key, EncKey)
    89  //
    90  //  2. Unseal(KeyID, EncKey) -> Key
    91  //
    92  //  1. Encrypt:
    93  //     Input: KeyID, bucket, object, metadata, object_data
    94  //     -     Key, EncKey := Generate(KeyID)
    95  //     -              IV := Random({0,1}²⁵⁶)
    96  //     -       ObjectKey := SHA256(Key, Random({0,1}²⁵⁶))
    97  //     -       KeyEncKey := HMAC-SHA256(Key, IV || 'SSE-S3' || 'DAREv2-HMAC-SHA256' || bucket || '/' || object)
    98  //     -       SealedKey := DAREv2_Enc(KeyEncKey, ObjectKey)
    99  //     - enc_object_data := DAREv2_Enc(ObjectKey, object_data)
   100  //     -        metadata <- IV
   101  //     -        metadata <- KeyID
   102  //     -        metadata <- EncKey
   103  //     -        metadata <- SealedKey
   104  //     Output: enc_object_data, metadata
   105  //
   106  //  2. Decrypt:
   107  //     Input: bucket, object, metadata, enc_object_data
   108  //     -      KeyID  <- metadata
   109  //     -      EncKey <- metadata
   110  //     -          IV <- metadata
   111  //     -   SealedKey <- metadata
   112  //     -         Key := Unseal(KeyID, EncKey)
   113  //     -   KeyEncKey := HMAC-SHA256(Key, IV || 'SSE-S3' || 'DAREv2-HMAC-SHA256' || bucket || '/' || object)
   114  //     -   ObjectKey := DAREv2_Dec(KeyEncKey, SealedKey)
   115  //     - object_data := DAREv2_Dec(ObjectKey, enc_object_data)
   116  //     Output: object_data
   117  package crypto