...

Source file src/edge-infra.dev/pkg/edge/edgeencrypt/decrypt.go

Documentation: edge-infra.dev/pkg/edge/edgeencrypt

     1  package edgeencrypt
     2  
     3  import (
     4  	"context"
     5  	"crypto/aes"
     6  	"crypto/cipher"
     7  	"fmt"
     8  )
     9  
    10  // DecryptFunc is a function that decrypts data, key decryption is handled externally by GCP
    11  type DecryptFunc func(ctx context.Context, keyRing, key, keyVersion string, data []byte) ([]byte, error)
    12  
    13  // DecryptData data using RSA private key, using 256 bit AES key
    14  func DecryptData(ctx context.Context, e *EncryptedData, ec *EncryptionClaims, decrypt DecryptFunc) ([]byte, error) {
    15  	if ec.Role != Decryption {
    16  		return nil, fmt.Errorf("invalid role for decryption: %s", ec.Role)
    17  	}
    18  	if len(e.Data) < KeySize {
    19  		return nil, fmt.Errorf("encrypted data is less than key size")
    20  	}
    21  	encryptedKey, encryptedData := splitEncryptedData(e.Data)
    22  	decryptedKey, err := decrypt(ctx, e.BannerEdgeID, e.ChannelID, e.KeyVersion, encryptedKey)
    23  	if err != nil {
    24  		return nil, fmt.Errorf("failed to decrypt key: %w", err)
    25  	}
    26  	decryptedData, err := decryptData(encryptedData, decryptedKey)
    27  	if err != nil {
    28  		return nil, fmt.Errorf("failed to decrypt data: %w", err)
    29  	}
    30  	return decryptedData, nil
    31  }
    32  
    33  func decryptData(data, aesKey []byte) ([]byte, error) {
    34  	block, err := aes.NewCipher(aesKey)
    35  	if err != nil {
    36  		return nil, fmt.Errorf("failed to create cipher: %w", err)
    37  	}
    38  	gcm, err := cipher.NewGCM(block)
    39  	if err != nil {
    40  		return nil, fmt.Errorf("failed to create cipher block: %w", err)
    41  	}
    42  	nonceSize := gcm.NonceSize()
    43  	if len(data) < nonceSize {
    44  		return nil, fmt.Errorf("data is too short")
    45  	}
    46  	nonce, data := data[:nonceSize], data[nonceSize:]
    47  	plaintext, err := gcm.Open(nil, nonce, data, nil)
    48  	if err != nil {
    49  		return nil, fmt.Errorf("failed to decrypt data: %w", err)
    50  	}
    51  	return plaintext, nil
    52  }
    53  
    54  // splitEncryptedData splits data into two parts, first part is 256 bit AES key, second part is encrypted data
    55  func splitEncryptedData(data []byte) ([]byte, []byte) {
    56  	return data[:KeySize], data[KeySize:]
    57  }
    58  

View as plain text