Class: Familia::Encryption::Providers::SecureXChaCha20Poly1305Provider

Inherits:
Familia::Encryption::Provider show all
Defined in:
lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb

Overview

Enhanced XChaCha20Poly1305Provider with improved memory security

While complete avoidance of Ruby strings for secrets is challenging due to RbNaCl’s internal implementation, this provider implements several security improvements:

  1. Minimizes key lifetime in memory
  2. Uses immediate secure wiping after operations
  3. Avoids unnecessary key duplication
  4. Uses locked memory where possible (future enhancement)

Constant Summary collapse

ALGORITHM =
'xchacha20poly1305-secure'.freeze
NONCE_SIZE =
24
AUTH_TAG_SIZE =
16

Instance Attribute Summary

Attributes inherited from Familia::Encryption::Provider

#algorithm, #auth_tag_size, #nonce_size

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Familia::Encryption::Provider

#initialize

Constructor Details

This class inherits a constructor from Familia::Encryption::Provider

Class Method Details

.available?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 52

def self.available?
  !!defined?(RbNaCl) && !!defined?(FFI)
end

.priorityObject



56
57
58
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 56

def self.priority
  110 # Higher than regular XChaCha20Poly1305Provider
end

Instance Method Details

#decrypt(ciphertext, key, nonce, auth_tag, additional_data = nil) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 75

def decrypt(ciphertext, key, nonce, auth_tag, additional_data = nil)
  validate_key_length!(key)

  # Minimize key exposure by performing operation immediately
  begin
    result = perform_decryption(ciphertext, key, nonce, auth_tag, additional_data)
  ensure
    # Attempt to clear the key parameter (if mutable)
    secure_wipe(key)
  end

  result
end

#derive_key(master_key, context, personal: nil) ⇒ Object

Enhanced key derivation with immediate cleanup



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 94

def derive_key(master_key, context, personal: nil)
  validate_key_length!(master_key)

  raw_personal = personal || Familia.config.encryption_personalization
  if raw_personal.include?("\0")
    raise EncryptionError, 'Personalization string must not contain null bytes'
  end

  personal_string = raw_personal.ljust(16, "\0")

  # Perform derivation and immediately clear intermediate values
  derived_key = RbNaCl::Hash.blake2b(
    context.force_encoding('BINARY'),
    key: master_key,
    digest_size: 32,
    personal: personal_string
  )

  # Clear personalization string from memory
  personal_string.clear

  # Return derived key (caller responsible for secure cleanup)
  derived_key
end

#encrypt(plaintext, key, additional_data = nil) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 60

def encrypt(plaintext, key, additional_data = nil)
  validate_key_length!(key)

  # Generate nonce first to avoid holding onto key longer than necessary
  nonce = generate_nonce

  # Minimize key exposure by performing operation immediately
  result = perform_encryption(plaintext, key, nonce, additional_data)

  # Attempt to clear the key parameter (if mutable)
  secure_wipe(key)

  result
end

#generate_nonceObject



89
90
91
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 89

def generate_nonce
  RbNaCl::Random.random_bytes(NONCE_SIZE)
end

#secure_wipe(key) ⇒ Object

Clear key from memory (still no security guarantees in Ruby)



120
121
122
# File 'lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb', line 120

def secure_wipe(key)
  key&.clear
end