mirror of
https://github.com/minio/minio.git
synced 2025-11-29 13:28:17 -05:00
kms: encrypt IAM/config data with the KMS (#12041)
This commit changes the config/IAM encryption process. Instead of encrypting config data (users, policies etc.) with the root credentials MinIO now encrypts this data with a KMS - if configured. Therefore, this PR moves the MinIO-KMS configuration (via env. variables) to a "top-level" configuration. The KMS configuration cannot be stored in the config file since it is used to decrypt the config file in the first place. As a consequence, this commit also removes support for Hashicorp Vault - which has been deprecated anyway. Signed-off-by: Andreas Auernhammer <aead@mail.de>
This commit is contained in:
committed by
Harshavardhana
parent
e05e14309c
commit
3455f786fa
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2018 MinIO, Inc.
|
||||
* MinIO Cloud Storage, (C) 2018-2021 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,21 +19,18 @@ package madmin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/minio/minio/pkg/argon2"
|
||||
"github.com/minio/minio/pkg/fips"
|
||||
"github.com/secure-io/sio-go"
|
||||
"github.com/secure-io/sio-go/sioutil"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
var idKey func([]byte, []byte, []byte, []byte, uint32) []byte
|
||||
|
||||
func init() {
|
||||
idKey = argon2.NewIDKey(1, 64*1024, 4)
|
||||
}
|
||||
|
||||
// EncryptData encrypts the data with an unique key
|
||||
// derived from password using the Argon2id PBKDF.
|
||||
//
|
||||
@@ -43,24 +40,35 @@ func init() {
|
||||
func EncryptData(password string, data []byte) ([]byte, error) {
|
||||
salt := sioutil.MustRandom(32)
|
||||
|
||||
// Derive an unique 256 bit key from the password and the random salt.
|
||||
key := idKey([]byte(password), salt, nil, nil, 32)
|
||||
|
||||
var (
|
||||
id byte
|
||||
err error
|
||||
stream *sio.Stream
|
||||
)
|
||||
if useAES() { // Only use AES-GCM if we can use an optimized implementation
|
||||
id = aesGcm
|
||||
if fips.Enabled() {
|
||||
key := pbkdf2.Key([]byte(password), salt, pbkdf2Cost, 32, sha256.New)
|
||||
stream, err = sio.AES_256_GCM.Stream(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id = pbkdf2AESGCM
|
||||
} else {
|
||||
id = c20p1305
|
||||
stream, err = sio.ChaCha20Poly1305.Stream(key)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
key := argon2.IDKey([]byte(password), salt, argon2idTime, argon2idMemory, argon2idThreads, 32)
|
||||
if sioutil.NativeAES() {
|
||||
stream, err = sio.AES_256_GCM.Stream(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id = argon2idAESGCM
|
||||
} else {
|
||||
stream, err = sio.ChaCha20Poly1305.Stream(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id = argon2idChaCHa20Poly1305
|
||||
}
|
||||
}
|
||||
|
||||
nonce := sioutil.MustRandom(stream.NonceSize())
|
||||
|
||||
// ciphertext = salt || AEAD ID | nonce | encrypted data
|
||||
@@ -110,33 +118,43 @@ func DecryptData(password string, data io.Reader) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key := idKey([]byte(password), salt[:], nil, nil, 32)
|
||||
var (
|
||||
err error
|
||||
stream *sio.Stream
|
||||
)
|
||||
switch id[0] {
|
||||
case aesGcm:
|
||||
switch {
|
||||
case id[0] == argon2idAESGCM:
|
||||
key := argon2.IDKey([]byte(password), salt[:], argon2idTime, argon2idMemory, argon2idThreads, 32)
|
||||
stream, err = sio.AES_256_GCM.Stream(key)
|
||||
case c20p1305:
|
||||
case id[0] == argon2idChaCHa20Poly1305:
|
||||
key := argon2.IDKey([]byte(password), salt[:], argon2idTime, argon2idMemory, argon2idThreads, 32)
|
||||
stream, err = sio.ChaCha20Poly1305.Stream(key)
|
||||
case id[0] == pbkdf2AESGCM:
|
||||
key := pbkdf2.Key([]byte(password), salt[:], pbkdf2Cost, 32, sha256.New)
|
||||
stream, err = sio.AES_256_GCM.Stream(key)
|
||||
default:
|
||||
err = errors.New("madmin: invalid AEAD algorithm ID")
|
||||
err = errors.New("madmin: invalid encryption algorithm ID")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
enBytes, err := ioutil.ReadAll(stream.DecryptReader(data, nonce[:], nil))
|
||||
plaintext, err := ioutil.ReadAll(stream.DecryptReader(data, nonce[:], nil))
|
||||
if err != nil {
|
||||
if err == sio.NotAuthentic {
|
||||
return enBytes, ErrMaliciousData
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return enBytes, err
|
||||
return plaintext, err
|
||||
}
|
||||
|
||||
const (
|
||||
aesGcm = 0x00
|
||||
c20p1305 = 0x01
|
||||
argon2idAESGCM = 0x00
|
||||
argon2idChaCHa20Poly1305 = 0x01
|
||||
pbkdf2AESGCM = 0x02
|
||||
)
|
||||
|
||||
const (
|
||||
argon2idTime = 1
|
||||
argon2idMemory = 64 * 1024
|
||||
argon2idThreads = 4
|
||||
pbkdf2Cost = 8192
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user