1package vault
2
3import (
4	"context"
5	"crypto/aes"
6	"crypto/cipher"
7	"crypto/rand"
8	"crypto/subtle"
9	"encoding/binary"
10	"errors"
11	"fmt"
12	"io"
13	"strings"
14	"sync"
15	"time"
16
17	"github.com/armon/go-metrics"
18	"github.com/hashicorp/errwrap"
19	"github.com/hashicorp/vault/sdk/helper/jsonutil"
20	"github.com/hashicorp/vault/sdk/helper/strutil"
21	"github.com/hashicorp/vault/sdk/logical"
22	"github.com/hashicorp/vault/sdk/physical"
23	"go.uber.org/atomic"
24)
25
26const (
27	// initialKeyTerm is the hard coded initial key term. This is
28	// used only for values that are not encrypted with the keyring.
29	initialKeyTerm = 1
30
31	// termSize the number of bytes used for the key term.
32	termSize = 4
33)
34
35// Versions of the AESGCM storage methodology
36const (
37	AESGCMVersion1 = 0x1
38	AESGCMVersion2 = 0x2
39)
40
41// barrierInit is the JSON encoded value stored
42type barrierInit struct {
43	Version int    // Version is the current format version
44	Key     []byte // Key is the primary encryption key
45}
46
47// Validate AESGCMBarrier satisfies SecurityBarrier interface
48var _ SecurityBarrier = &AESGCMBarrier{}
49
50// AESGCMBarrier is a SecurityBarrier implementation that uses the AES
51// cipher core and the Galois Counter Mode block mode. It defaults to
52// the golang NONCE default value of 12 and a key size of 256
53// bit. AES-GCM is high performance, and provides both confidentiality
54// and integrity.
55type AESGCMBarrier struct {
56	backend physical.Backend
57
58	l      sync.RWMutex
59	sealed bool
60
61	// keyring is used to maintain all of the encryption keys, including
62	// the active key used for encryption, but also prior keys to allow
63	// decryption of keys encrypted under previous terms.
64	keyring *Keyring
65
66	// cache is used to reduce the number of AEAD constructions we do
67	cache     map[uint32]cipher.AEAD
68	cacheLock sync.RWMutex
69
70	// currentAESGCMVersionByte is prefixed to a message to allow for
71	// future versioning of barrier implementations. It's var instead
72	// of const to allow for testing
73	currentAESGCMVersionByte byte
74
75	initialized atomic.Bool
76}
77
78// NewAESGCMBarrier is used to construct a new barrier that uses
79// the provided physical backend for storage.
80func NewAESGCMBarrier(physical physical.Backend) (*AESGCMBarrier, error) {
81	b := &AESGCMBarrier{
82		backend:                  physical,
83		sealed:                   true,
84		cache:                    make(map[uint32]cipher.AEAD),
85		currentAESGCMVersionByte: byte(AESGCMVersion2),
86	}
87	return b, nil
88}
89
90// Initialized checks if the barrier has been initialized
91// and has a master key set.
92func (b *AESGCMBarrier) Initialized(ctx context.Context) (bool, error) {
93	if b.initialized.Load() {
94		return true, nil
95	}
96
97	// Read the keyring file
98	keys, err := b.backend.List(ctx, keyringPrefix)
99	if err != nil {
100		return false, errwrap.Wrapf("failed to check for initialization: {{err}}", err)
101	}
102	if strutil.StrListContains(keys, "keyring") {
103		b.initialized.Store(true)
104		return true, nil
105	}
106
107	// Fallback, check for the old sentinel file
108	out, err := b.backend.Get(ctx, barrierInitPath)
109	if err != nil {
110		return false, errwrap.Wrapf("failed to check for initialization: {{err}}", err)
111	}
112	b.initialized.Store(out != nil)
113	return out != nil, nil
114}
115
116// Initialize works only if the barrier has not been initialized
117// and makes use of the given master key.
118func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, reader io.Reader) error {
119	// Verify the key size
120	min, max := b.KeyLength()
121	if len(key) < min || len(key) > max {
122		return fmt.Errorf("key size must be %d or %d", min, max)
123	}
124
125	// Check if already initialized
126	if alreadyInit, err := b.Initialized(ctx); err != nil {
127		return err
128	} else if alreadyInit {
129		return ErrBarrierAlreadyInit
130	}
131
132	// Generate encryption key
133	encrypt, err := b.GenerateKey(reader)
134	if err != nil {
135		return errwrap.Wrapf("failed to generate encryption key: {{err}}", err)
136	}
137
138	// Create a new keyring, install the keys
139	keyring := NewKeyring()
140	keyring = keyring.SetMasterKey(key)
141	keyring, err = keyring.AddKey(&Key{
142		Term:    1,
143		Version: 1,
144		Value:   encrypt,
145	})
146	if err != nil {
147		return errwrap.Wrapf("failed to create keyring: {{err}}", err)
148	}
149
150	err = b.persistKeyring(ctx, keyring)
151	if err != nil {
152		return err
153	}
154
155	if len(sealKey) > 0 {
156		primary, err := b.aeadFromKey(encrypt)
157		if err != nil {
158			return err
159		}
160
161		err = b.putInternal(ctx, 1, primary, &logical.StorageEntry{
162			Key:   shamirKekPath,
163			Value: sealKey,
164		})
165		if err != nil {
166			return errwrap.Wrapf("failed to store new seal key: {{err}}", err)
167		}
168	}
169
170	return nil
171}
172
173// persistKeyring is used to write out the keyring using the
174// master key to encrypt it.
175func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) error {
176	// Create the keyring entry
177	keyringBuf, err := keyring.Serialize()
178	defer memzero(keyringBuf)
179	if err != nil {
180		return errwrap.Wrapf("failed to serialize keyring: {{err}}", err)
181	}
182
183	// Create the AES-GCM
184	gcm, err := b.aeadFromKey(keyring.MasterKey())
185	if err != nil {
186		return err
187	}
188
189	// Encrypt the barrier init value
190	value, err := b.encrypt(keyringPath, initialKeyTerm, gcm, keyringBuf)
191	if err != nil {
192		return err
193	}
194
195	// Create the keyring physical entry
196	pe := &physical.Entry{
197		Key:   keyringPath,
198		Value: value,
199	}
200	if err := b.backend.Put(ctx, pe); err != nil {
201		return errwrap.Wrapf("failed to persist keyring: {{err}}", err)
202	}
203
204	// Serialize the master key value
205	key := &Key{
206		Term:    1,
207		Version: 1,
208		Value:   keyring.MasterKey(),
209	}
210	keyBuf, err := key.Serialize()
211	defer memzero(keyBuf)
212	if err != nil {
213		return errwrap.Wrapf("failed to serialize master key: {{err}}", err)
214	}
215
216	// Encrypt the master key
217	activeKey := keyring.ActiveKey()
218	aead, err := b.aeadFromKey(activeKey.Value)
219	if err != nil {
220		return err
221	}
222	value, err = b.encrypt(masterKeyPath, activeKey.Term, aead, keyBuf)
223	if err != nil {
224		return err
225	}
226
227	// Update the masterKeyPath for standby instances
228	pe = &physical.Entry{
229		Key:   masterKeyPath,
230		Value: value,
231	}
232	if err := b.backend.Put(ctx, pe); err != nil {
233		return errwrap.Wrapf("failed to persist master key: {{err}}", err)
234	}
235	return nil
236}
237
238// GenerateKey is used to generate a new key
239func (b *AESGCMBarrier) GenerateKey(reader io.Reader) ([]byte, error) {
240	// Generate a 256bit key
241	buf := make([]byte, 2*aes.BlockSize)
242	_, err := reader.Read(buf)
243
244	return buf, err
245}
246
247// KeyLength is used to sanity check a key
248func (b *AESGCMBarrier) KeyLength() (int, int) {
249	return aes.BlockSize, 2 * aes.BlockSize
250}
251
252// Sealed checks if the barrier has been unlocked yet. The Barrier
253// is not expected to be able to perform any CRUD until it is unsealed.
254func (b *AESGCMBarrier) Sealed() (bool, error) {
255	b.l.RLock()
256	sealed := b.sealed
257	b.l.RUnlock()
258	return sealed, nil
259}
260
261// VerifyMaster is used to check if the given key matches the master key
262func (b *AESGCMBarrier) VerifyMaster(key []byte) error {
263	b.l.RLock()
264	defer b.l.RUnlock()
265	if b.sealed {
266		return ErrBarrierSealed
267	}
268	if subtle.ConstantTimeCompare(key, b.keyring.MasterKey()) != 1 {
269		return ErrBarrierInvalidKey
270	}
271	return nil
272}
273
274// ReloadKeyring is used to re-read the underlying keyring.
275// This is used for HA deployments to ensure the latest keyring
276// is present in the leader.
277func (b *AESGCMBarrier) ReloadKeyring(ctx context.Context) error {
278	b.l.Lock()
279	defer b.l.Unlock()
280
281	// Create the AES-GCM
282	gcm, err := b.aeadFromKey(b.keyring.MasterKey())
283	if err != nil {
284		return err
285	}
286
287	// Read in the keyring
288	out, err := b.backend.Get(ctx, keyringPath)
289	if err != nil {
290		return errwrap.Wrapf("failed to check for keyring: {{err}}", err)
291	}
292
293	// Ensure that the keyring exists. This should never happen,
294	// and indicates something really bad has happened.
295	if out == nil {
296		return errors.New("keyring unexpectedly missing")
297	}
298
299	// Verify the term is always just one
300	term := binary.BigEndian.Uint32(out.Value[:4])
301	if term != initialKeyTerm {
302		return errors.New("term mis-match")
303	}
304
305	// Decrypt the barrier init key
306	plain, err := b.decrypt(keyringPath, gcm, out.Value)
307	defer memzero(plain)
308	if err != nil {
309		if strings.Contains(err.Error(), "message authentication failed") {
310			return ErrBarrierInvalidKey
311		}
312		return err
313	}
314
315	// Recover the keyring
316	keyring, err := DeserializeKeyring(plain)
317	if err != nil {
318		return errwrap.Wrapf("keyring deserialization failed: {{err}}", err)
319	}
320
321	// Setup the keyring and finish
322	b.cache = make(map[uint32]cipher.AEAD)
323	b.keyring = keyring
324	return nil
325}
326
327// ReloadMasterKey is used to re-read the underlying masterkey.
328// This is used for HA deployments to ensure the latest master key
329// is available for keyring reloading.
330func (b *AESGCMBarrier) ReloadMasterKey(ctx context.Context) error {
331	// Read the masterKeyPath upgrade
332	out, err := b.Get(ctx, masterKeyPath)
333	if err != nil {
334		return errwrap.Wrapf("failed to read master key path: {{err}}", err)
335	}
336
337	// The masterKeyPath could be missing (backwards incompatible),
338	// we can ignore this and attempt to make progress with the current
339	// master key.
340	if out == nil {
341		return nil
342	}
343
344	// Grab write lock and refetch
345	b.l.Lock()
346	defer b.l.Unlock()
347
348	out, err = b.lockSwitchedGet(ctx, masterKeyPath, false)
349	if err != nil {
350		return errwrap.Wrapf("failed to read master key path: {{err}}", err)
351	}
352
353	if out == nil {
354		return nil
355	}
356
357	// Deserialize the master key
358	key, err := DeserializeKey(out.Value)
359	memzero(out.Value)
360	if err != nil {
361		return errwrap.Wrapf("failed to deserialize key: {{err}}", err)
362	}
363
364	// Check if the master key is the same
365	if subtle.ConstantTimeCompare(b.keyring.MasterKey(), key.Value) == 1 {
366		return nil
367	}
368
369	// Update the master key
370	oldKeyring := b.keyring
371	b.keyring = b.keyring.SetMasterKey(key.Value)
372	oldKeyring.Zeroize(false)
373	return nil
374}
375
376// Unseal is used to provide the master key which permits the barrier
377// to be unsealed. If the key is not correct, the barrier remains sealed.
378func (b *AESGCMBarrier) Unseal(ctx context.Context, key []byte) error {
379	b.l.Lock()
380	defer b.l.Unlock()
381
382	// Do nothing if already unsealed
383	if !b.sealed {
384		return nil
385	}
386
387	// Create the AES-GCM
388	gcm, err := b.aeadFromKey(key)
389	if err != nil {
390		return err
391	}
392
393	// Read in the keyring
394	out, err := b.backend.Get(ctx, keyringPath)
395	if err != nil {
396		return errwrap.Wrapf("failed to check for keyring: {{err}}", err)
397	}
398	if out != nil {
399		// Verify the term is always just one
400		term := binary.BigEndian.Uint32(out.Value[:4])
401		if term != initialKeyTerm {
402			return errors.New("term mis-match")
403		}
404
405		// Decrypt the barrier init key
406		plain, err := b.decrypt(keyringPath, gcm, out.Value)
407		defer memzero(plain)
408		if err != nil {
409			if strings.Contains(err.Error(), "message authentication failed") {
410				return ErrBarrierInvalidKey
411			}
412			return err
413		}
414
415		// Recover the keyring
416		keyring, err := DeserializeKeyring(plain)
417		if err != nil {
418			return errwrap.Wrapf("keyring deserialization failed: {{err}}", err)
419		}
420
421		// Setup the keyring and finish
422		b.keyring = keyring
423		b.sealed = false
424		return nil
425	}
426
427	// Read the barrier initialization key
428	out, err = b.backend.Get(ctx, barrierInitPath)
429	if err != nil {
430		return errwrap.Wrapf("failed to check for initialization: {{err}}", err)
431	}
432	if out == nil {
433		return ErrBarrierNotInit
434	}
435
436	// Verify the term is always just one
437	term := binary.BigEndian.Uint32(out.Value[:4])
438	if term != initialKeyTerm {
439		return errors.New("term mis-match")
440	}
441
442	// Decrypt the barrier init key
443	plain, err := b.decrypt(barrierInitPath, gcm, out.Value)
444	if err != nil {
445		if strings.Contains(err.Error(), "message authentication failed") {
446			return ErrBarrierInvalidKey
447		}
448		return err
449	}
450	defer memzero(plain)
451
452	// Unmarshal the barrier init
453	var init barrierInit
454	if err := jsonutil.DecodeJSON(plain, &init); err != nil {
455		return fmt.Errorf("failed to unmarshal barrier init file")
456	}
457
458	// Setup a new keyring, this is for backwards compatibility
459	keyringNew := NewKeyring()
460	keyring := keyringNew.SetMasterKey(key)
461
462	// AddKey reuses the master, so we are only zeroizing after this call
463	defer keyringNew.Zeroize(false)
464
465	keyring, err = keyring.AddKey(&Key{
466		Term:    1,
467		Version: 1,
468		Value:   init.Key,
469	})
470	if err != nil {
471		return errwrap.Wrapf("failed to create keyring: {{err}}", err)
472	}
473	if err := b.persistKeyring(ctx, keyring); err != nil {
474		return err
475	}
476
477	// Delete the old barrier entry
478	if err := b.backend.Delete(ctx, barrierInitPath); err != nil {
479		return errwrap.Wrapf("failed to delete barrier init file: {{err}}", err)
480	}
481
482	// Set the vault as unsealed
483	b.keyring = keyring
484	b.sealed = false
485	return nil
486}
487
488// Seal is used to re-seal the barrier. This requires the barrier to
489// be unsealed again to perform any further operations.
490func (b *AESGCMBarrier) Seal() error {
491	b.l.Lock()
492	defer b.l.Unlock()
493
494	// Remove the primary key, and seal the vault
495	b.cache = make(map[uint32]cipher.AEAD)
496	b.keyring.Zeroize(true)
497	b.keyring = nil
498	b.sealed = true
499	return nil
500}
501
502// Rotate is used to create a new encryption key. All future writes
503// should use the new key, while old values should still be decryptable.
504func (b *AESGCMBarrier) Rotate(ctx context.Context, reader io.Reader) (uint32, error) {
505	b.l.Lock()
506	defer b.l.Unlock()
507	if b.sealed {
508		return 0, ErrBarrierSealed
509	}
510
511	// Generate a new key
512	encrypt, err := b.GenerateKey(reader)
513	if err != nil {
514		return 0, errwrap.Wrapf("failed to generate encryption key: {{err}}", err)
515	}
516
517	// Get the next term
518	term := b.keyring.ActiveTerm()
519	newTerm := term + 1
520
521	// Add a new encryption key
522	newKeyring, err := b.keyring.AddKey(&Key{
523		Term:    newTerm,
524		Version: 1,
525		Value:   encrypt,
526	})
527	if err != nil {
528		return 0, errwrap.Wrapf("failed to add new encryption key: {{err}}", err)
529	}
530
531	// Persist the new keyring
532	if err := b.persistKeyring(ctx, newKeyring); err != nil {
533		return 0, err
534	}
535
536	// Swap the keyrings
537	b.keyring = newKeyring
538	return newTerm, nil
539}
540
541// CreateUpgrade creates an upgrade path key to the given term from the previous term
542func (b *AESGCMBarrier) CreateUpgrade(ctx context.Context, term uint32) error {
543	b.l.RLock()
544	if b.sealed {
545		b.l.RUnlock()
546		return ErrBarrierSealed
547	}
548
549	// Get the key for this term
550	termKey := b.keyring.TermKey(term)
551	buf, err := termKey.Serialize()
552	defer memzero(buf)
553	if err != nil {
554		b.l.RUnlock()
555		return err
556	}
557
558	// Get the AEAD for the previous term
559	prevTerm := term - 1
560	primary, err := b.aeadForTerm(prevTerm)
561	if err != nil {
562		b.l.RUnlock()
563		return err
564	}
565
566	key := fmt.Sprintf("%s%d", keyringUpgradePrefix, prevTerm)
567	value, err := b.encrypt(key, prevTerm, primary, buf)
568	b.l.RUnlock()
569	if err != nil {
570		return err
571	}
572	// Create upgrade key
573	pe := &physical.Entry{
574		Key:   key,
575		Value: value,
576	}
577	return b.backend.Put(ctx, pe)
578}
579
580// DestroyUpgrade destroys the upgrade path key to the given term
581func (b *AESGCMBarrier) DestroyUpgrade(ctx context.Context, term uint32) error {
582	path := fmt.Sprintf("%s%d", keyringUpgradePrefix, term-1)
583	return b.Delete(ctx, path)
584}
585
586// CheckUpgrade looks for an upgrade to the current term and installs it
587func (b *AESGCMBarrier) CheckUpgrade(ctx context.Context) (bool, uint32, error) {
588	b.l.RLock()
589	if b.sealed {
590		b.l.RUnlock()
591		return false, 0, ErrBarrierSealed
592	}
593
594	// Get the current term
595	activeTerm := b.keyring.ActiveTerm()
596
597	// Check for an upgrade key
598	upgrade := fmt.Sprintf("%s%d", keyringUpgradePrefix, activeTerm)
599	entry, err := b.lockSwitchedGet(ctx, upgrade, false)
600	if err != nil {
601		b.l.RUnlock()
602		return false, 0, err
603	}
604
605	// Nothing to do if no upgrade
606	if entry == nil {
607		b.l.RUnlock()
608		return false, 0, nil
609	}
610
611	// Upgrade from read lock to write lock
612	b.l.RUnlock()
613	b.l.Lock()
614	defer b.l.Unlock()
615
616	// Validate base cases and refetch values again
617
618	if b.sealed {
619		return false, 0, ErrBarrierSealed
620	}
621
622	activeTerm = b.keyring.ActiveTerm()
623
624	upgrade = fmt.Sprintf("%s%d", keyringUpgradePrefix, activeTerm)
625	entry, err = b.lockSwitchedGet(ctx, upgrade, false)
626	if err != nil {
627		return false, 0, err
628	}
629
630	if entry == nil {
631		return false, 0, nil
632	}
633
634	// Deserialize the key
635	key, err := DeserializeKey(entry.Value)
636	memzero(entry.Value)
637	if err != nil {
638		return false, 0, err
639	}
640
641	// Update the keyring
642	newKeyring, err := b.keyring.AddKey(key)
643	if err != nil {
644		return false, 0, errwrap.Wrapf("failed to add new encryption key: {{err}}", err)
645	}
646	b.keyring = newKeyring
647
648	// Done!
649	return true, key.Term, nil
650}
651
652// ActiveKeyInfo is used to inform details about the active key
653func (b *AESGCMBarrier) ActiveKeyInfo() (*KeyInfo, error) {
654	b.l.RLock()
655	defer b.l.RUnlock()
656	if b.sealed {
657		return nil, ErrBarrierSealed
658	}
659
660	// Determine the key install time
661	term := b.keyring.ActiveTerm()
662	key := b.keyring.TermKey(term)
663
664	// Return the key info
665	info := &KeyInfo{
666		Term:        int(term),
667		InstallTime: key.InstallTime,
668	}
669	return info, nil
670}
671
672// Rekey is used to change the master key used to protect the keyring
673func (b *AESGCMBarrier) Rekey(ctx context.Context, key []byte) error {
674	b.l.Lock()
675	defer b.l.Unlock()
676
677	newKeyring, err := b.updateMasterKeyCommon(key)
678	if err != nil {
679		return err
680	}
681
682	// Persist the new keyring
683	if err := b.persistKeyring(ctx, newKeyring); err != nil {
684		return err
685	}
686
687	// Swap the keyrings
688	oldKeyring := b.keyring
689	b.keyring = newKeyring
690	oldKeyring.Zeroize(false)
691	return nil
692}
693
694// SetMasterKey updates the keyring's in-memory master key but does not persist
695// anything to storage
696func (b *AESGCMBarrier) SetMasterKey(key []byte) error {
697	b.l.Lock()
698	defer b.l.Unlock()
699
700	newKeyring, err := b.updateMasterKeyCommon(key)
701	if err != nil {
702		return err
703	}
704
705	// Swap the keyrings
706	oldKeyring := b.keyring
707	b.keyring = newKeyring
708	oldKeyring.Zeroize(false)
709	return nil
710}
711
712// Performs common tasks related to updating the master key; note that the lock
713// must be held before calling this function
714func (b *AESGCMBarrier) updateMasterKeyCommon(key []byte) (*Keyring, error) {
715	if b.sealed {
716		return nil, ErrBarrierSealed
717	}
718
719	// Verify the key size
720	min, max := b.KeyLength()
721	if len(key) < min || len(key) > max {
722		return nil, fmt.Errorf("key size must be %d or %d", min, max)
723	}
724
725	return b.keyring.SetMasterKey(key), nil
726}
727
728// Put is used to insert or update an entry
729func (b *AESGCMBarrier) Put(ctx context.Context, entry *logical.StorageEntry) error {
730	defer metrics.MeasureSince([]string{"barrier", "put"}, time.Now())
731	b.l.RLock()
732	if b.sealed {
733		b.l.RUnlock()
734		return ErrBarrierSealed
735	}
736
737	term := b.keyring.ActiveTerm()
738	primary, err := b.aeadForTerm(term)
739	b.l.RUnlock()
740	if err != nil {
741		return err
742	}
743
744	return b.putInternal(ctx, term, primary, entry)
745}
746
747func (b *AESGCMBarrier) putInternal(ctx context.Context, term uint32, primary cipher.AEAD, entry *logical.StorageEntry) error {
748	value, err := b.encrypt(entry.Key, term, primary, entry.Value)
749	if err != nil {
750		return err
751	}
752	pe := &physical.Entry{
753		Key:      entry.Key,
754		Value:    value,
755		SealWrap: entry.SealWrap,
756	}
757	return b.backend.Put(ctx, pe)
758}
759
760// Get is used to fetch an entry
761func (b *AESGCMBarrier) Get(ctx context.Context, key string) (*logical.StorageEntry, error) {
762	return b.lockSwitchedGet(ctx, key, true)
763}
764
765func (b *AESGCMBarrier) lockSwitchedGet(ctx context.Context, key string, getLock bool) (*logical.StorageEntry, error) {
766	defer metrics.MeasureSince([]string{"barrier", "get"}, time.Now())
767	if getLock {
768		b.l.RLock()
769	}
770	if b.sealed {
771		if getLock {
772			b.l.RUnlock()
773		}
774		return nil, ErrBarrierSealed
775	}
776
777	// Read the key from the backend
778	pe, err := b.backend.Get(ctx, key)
779	if err != nil {
780		if getLock {
781			b.l.RUnlock()
782		}
783		return nil, err
784	} else if pe == nil {
785		if getLock {
786			b.l.RUnlock()
787		}
788		return nil, nil
789	}
790
791	if len(pe.Value) < 4 {
792		if getLock {
793			b.l.RUnlock()
794		}
795		return nil, errors.New("invalid value")
796	}
797
798	// Verify the term
799	term := binary.BigEndian.Uint32(pe.Value[:4])
800
801	// Get the GCM by term
802	// It is expensive to do this first but it is not a
803	// normal case that this won't match
804	gcm, err := b.aeadForTerm(term)
805	if getLock {
806		b.l.RUnlock()
807	}
808	if err != nil {
809		return nil, err
810	}
811	if gcm == nil {
812		return nil, fmt.Errorf("no decryption key available for term %d", term)
813	}
814
815	// Decrypt the ciphertext
816	plain, err := b.decrypt(key, gcm, pe.Value)
817	if err != nil {
818		return nil, errwrap.Wrapf("decryption failed: {{err}}", err)
819	}
820
821	// Wrap in a logical entry
822	entry := &logical.StorageEntry{
823		Key:      key,
824		Value:    plain,
825		SealWrap: pe.SealWrap,
826	}
827	return entry, nil
828}
829
830// Delete is used to permanently delete an entry
831func (b *AESGCMBarrier) Delete(ctx context.Context, key string) error {
832	defer metrics.MeasureSince([]string{"barrier", "delete"}, time.Now())
833	b.l.RLock()
834	sealed := b.sealed
835	b.l.RUnlock()
836	if sealed {
837		return ErrBarrierSealed
838	}
839
840	return b.backend.Delete(ctx, key)
841}
842
843// List is used ot list all the keys under a given
844// prefix, up to the next prefix.
845func (b *AESGCMBarrier) List(ctx context.Context, prefix string) ([]string, error) {
846	defer metrics.MeasureSince([]string{"barrier", "list"}, time.Now())
847	b.l.RLock()
848	sealed := b.sealed
849	b.l.RUnlock()
850	if sealed {
851		return nil, ErrBarrierSealed
852	}
853
854	return b.backend.List(ctx, prefix)
855}
856
857// aeadForTerm returns the AES-GCM AEAD for the given term
858func (b *AESGCMBarrier) aeadForTerm(term uint32) (cipher.AEAD, error) {
859	// Check for the keyring
860	keyring := b.keyring
861	if keyring == nil {
862		return nil, nil
863	}
864
865	// Check the cache for the aead
866	b.cacheLock.RLock()
867	aead, ok := b.cache[term]
868	b.cacheLock.RUnlock()
869	if ok {
870		return aead, nil
871	}
872
873	// Read the underlying key
874	key := keyring.TermKey(term)
875	if key == nil {
876		return nil, nil
877	}
878
879	// Create a new aead
880	aead, err := b.aeadFromKey(key.Value)
881	if err != nil {
882		return nil, err
883	}
884
885	// Update the cache
886	b.cacheLock.Lock()
887	b.cache[term] = aead
888	b.cacheLock.Unlock()
889	return aead, nil
890}
891
892// aeadFromKey returns an AES-GCM AEAD using the given key.
893func (b *AESGCMBarrier) aeadFromKey(key []byte) (cipher.AEAD, error) {
894	// Create the AES cipher
895	aesCipher, err := aes.NewCipher(key)
896	if err != nil {
897		return nil, errwrap.Wrapf("failed to create cipher: {{err}}", err)
898	}
899
900	// Create the GCM mode AEAD
901	gcm, err := cipher.NewGCM(aesCipher)
902	if err != nil {
903		return nil, fmt.Errorf("failed to initialize GCM mode")
904	}
905	return gcm, nil
906}
907
908// encrypt is used to encrypt a value
909func (b *AESGCMBarrier) encrypt(path string, term uint32, gcm cipher.AEAD, plain []byte) ([]byte, error) {
910	// Allocate the output buffer with room for tern, version byte,
911	// nonce, GCM tag and the plaintext
912	capacity := termSize + 1 + gcm.NonceSize() + gcm.Overhead() + len(plain)
913	size := termSize + 1 + gcm.NonceSize()
914	out := make([]byte, size, capacity)
915
916	// Set the key term
917	binary.BigEndian.PutUint32(out[:4], term)
918
919	// Set the version byte
920	out[4] = b.currentAESGCMVersionByte
921
922	// Generate a random nonce
923	nonce := out[5 : 5+gcm.NonceSize()]
924	n, err := rand.Read(nonce)
925	if err != nil {
926		return nil, err
927	}
928	if n != len(nonce) {
929		return nil, errors.New("unable to read enough random bytes to fill gcm nonce")
930	}
931
932	// Seal the output
933	switch b.currentAESGCMVersionByte {
934	case AESGCMVersion1:
935		out = gcm.Seal(out, nonce, plain, nil)
936	case AESGCMVersion2:
937		aad := []byte(nil)
938		if path != "" {
939			aad = []byte(path)
940		}
941		out = gcm.Seal(out, nonce, plain, aad)
942	default:
943		panic("Unknown AESGCM version")
944	}
945
946	return out, nil
947}
948
949// decrypt is used to decrypt a value using the keyring
950func (b *AESGCMBarrier) decrypt(path string, gcm cipher.AEAD, cipher []byte) ([]byte, error) {
951	// Capture the parts
952	nonce := cipher[5 : 5+gcm.NonceSize()]
953	raw := cipher[5+gcm.NonceSize():]
954	out := make([]byte, 0, len(raw)-gcm.NonceSize())
955
956	// Attempt to open
957	switch cipher[4] {
958	case AESGCMVersion1:
959		return gcm.Open(out, nonce, raw, nil)
960	case AESGCMVersion2:
961		aad := []byte(nil)
962		if path != "" {
963			aad = []byte(path)
964		}
965		return gcm.Open(out, nonce, raw, aad)
966	default:
967		return nil, fmt.Errorf("version bytes mis-match")
968	}
969}
970
971// Encrypt is used to encrypt in-memory for the BarrierEncryptor interface
972func (b *AESGCMBarrier) Encrypt(ctx context.Context, key string, plaintext []byte) ([]byte, error) {
973	b.l.RLock()
974	if b.sealed {
975		b.l.RUnlock()
976		return nil, ErrBarrierSealed
977	}
978
979	term := b.keyring.ActiveTerm()
980	primary, err := b.aeadForTerm(term)
981	b.l.RUnlock()
982	if err != nil {
983		return nil, err
984	}
985
986	ciphertext, err := b.encrypt(key, term, primary, plaintext)
987	if err != nil {
988		return nil, err
989	}
990	return ciphertext, nil
991}
992
993// Decrypt is used to decrypt in-memory for the BarrierEncryptor interface
994func (b *AESGCMBarrier) Decrypt(ctx context.Context, key string, ciphertext []byte) ([]byte, error) {
995	b.l.RLock()
996	if b.sealed {
997		b.l.RUnlock()
998		return nil, ErrBarrierSealed
999	}
1000
1001	// Verify the term
1002	term := binary.BigEndian.Uint32(ciphertext[:4])
1003
1004	// Get the GCM by term
1005	// It is expensive to do this first but it is not a
1006	// normal case that this won't match
1007	gcm, err := b.aeadForTerm(term)
1008	b.l.RUnlock()
1009	if err != nil {
1010		return nil, err
1011	}
1012	if gcm == nil {
1013		return nil, fmt.Errorf("no decryption key available for term %d", term)
1014	}
1015
1016	// Decrypt the ciphertext
1017	plain, err := b.decrypt(key, gcm, ciphertext)
1018	if err != nil {
1019		return nil, errwrap.Wrapf("decryption failed: {{err}}", err)
1020	}
1021
1022	return plain, nil
1023}
1024
1025func (b *AESGCMBarrier) Keyring() (*Keyring, error) {
1026	b.l.RLock()
1027	defer b.l.RUnlock()
1028	if b.sealed {
1029		return nil, ErrBarrierSealed
1030	}
1031
1032	return b.keyring.Clone(), nil
1033}
1034