1 package edgeencrypt
2
3 import (
4 "context"
5 "crypto/aes"
6 "crypto/cipher"
7 "fmt"
8 )
9
10
11 type DecryptFunc func(ctx context.Context, keyRing, key, keyVersion string, data []byte) ([]byte, error)
12
13
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
55 func splitEncryptedData(data []byte) ([]byte, []byte) {
56 return data[:KeySize], data[KeySize:]
57 }
58
View as plain text