mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-07 14:32:17 -04:00
s3proxy: add intial implementation
INSECURE! The proxy intercepts GetObject and PutObject. A manual deployment guide is included. The decryption only relies on a hardcoded, static key. Do not use with sensitive data; testing only. * Ticket to track ranged GetObject: AB#3466.
This commit is contained in:
parent
957f8ad203
commit
a7ceda37ea
13 changed files with 1233 additions and 0 deletions
79
s3proxy/internal/crypto/crypto.go
Normal file
79
s3proxy/internal/crypto/crypto.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/*
|
||||
Package crypto provides encryption and decryption functions for the s3proxy.
|
||||
It uses AES-256-GCM to encrypt and decrypt data.
|
||||
A new nonce is generated for each encryption operation.
|
||||
*/
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Encrypt takes a 32 byte key and encrypts a plaintext using AES-256-GCM.
|
||||
// Output format is 12 byte nonce + ciphertext.
|
||||
func Encrypt(plaintext, key []byte) ([]byte, error) {
|
||||
// Enforce AES-256
|
||||
if len(key) != 32 {
|
||||
return nil, aes.KeySizeError(len(key))
|
||||
}
|
||||
|
||||
// None should not be reused more often that 2^32 times:
|
||||
// https://pkg.go.dev/crypto/cipher#NewGCM
|
||||
// Assuming n encryption operations per second, the key has to be rotated every:
|
||||
// n=1: 2^32 / (60*60*24*365*10) = 135 years.
|
||||
// n=10: 2^32 / (60*60*24*365*10) = 13.5 years.
|
||||
// n=100: 2^32 / (60*60*24*365*10) = 1.3 years.
|
||||
// n=1000: 2^32 / (60*60*24*365*10) = 50 days.
|
||||
nonce := make([]byte, 12)
|
||||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
|
||||
|
||||
// Prepend the nonce to the ciphertext.
|
||||
ciphertext = append(nonce, ciphertext...)
|
||||
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
||||
// Decrypt takes a 32 byte key and decrypts a ciphertext using AES-256-GCM.
|
||||
// ciphertext is formatted as 12 byte nonce + ciphertext.
|
||||
func Decrypt(ciphertext []byte, key []byte) ([]byte, error) {
|
||||
// Enforce AES-256
|
||||
if len(key) != 32 {
|
||||
return nil, aes.KeySizeError(len(key))
|
||||
}
|
||||
|
||||
// Extract the nonce from the ciphertext.
|
||||
nonce := ciphertext[:12]
|
||||
ciphertext = ciphertext[12:]
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return aesgcm.Open(nil, nonce, ciphertext, nil)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue