// DeriveKey is used to derive the encryption key that should // be used depending on the policy. If derivation is disabled the // raw key is used and no context is required, otherwise the KDF // mode is used with the context to derive the proper key. func (p *Policy) DeriveKey(context []byte, ver int) ([]byte, error) { if p.Keys == nil || len(p.Keys) == 0 { if p.Key == nil || len(p.Key) == 0 { return nil, certutil.InternalError{Err: "unable to access the key; no key versions found"} } p.migrateKeyToKeysMap() } if len(p.Keys) == 0 { return nil, certutil.InternalError{Err: "unable to access the key; no key versions found"} } if ver <= 0 || ver > len(p.Keys) { return nil, certutil.UserError{Err: "invalid key version"} } // Fast-path non-derived keys if !p.Derived { return p.Keys[ver].Key, nil } // Ensure a context is provided if len(context) == 0 { return nil, certutil.UserError{Err: "missing 'context' for key deriviation. The key was created using a derived key, which means additional, per-request information must be included in order to encrypt or decrypt information"} } switch p.KDFMode { case kdfMode: prf := kdf.HMACSHA256PRF prfLen := kdf.HMACSHA256PRFLen return kdf.CounterMode(prf, prfLen, p.Keys[ver].Key, context, 256) default: return nil, certutil.InternalError{Err: "unsupported key derivation mode"} } }
// DeriveKey is used to derive the encryption key that should be used depending // on the policy. If derivation is disabled the raw key is used and no context // is required, otherwise the KDF mode is used with the context to derive the // proper key. func (p *policy) DeriveKey(context []byte, ver int) ([]byte, error) { if !p.Type.DerivationSupported() { return nil, errutil.UserError{Err: fmt.Sprintf("derivation not supported for key type %v", p.Type)} } if p.Keys == nil || p.LatestVersion == 0 { return nil, errutil.InternalError{Err: "unable to access the key; no key versions found"} } if ver <= 0 || ver > p.LatestVersion { return nil, errutil.UserError{Err: "invalid key version"} } // Fast-path non-derived keys if !p.Derived { return p.Keys[ver].AESKey, nil } // Ensure a context is provided if len(context) == 0 { return nil, errutil.UserError{Err: "missing 'context' for key deriviation. The key was created using a derived key, which means additional, per-request information must be included in order to encrypt or decrypt information"} } switch p.KDF { case kdf_hmac_sha256_counter: prf := kdf.HMACSHA256PRF prfLen := kdf.HMACSHA256PRFLen return kdf.CounterMode(prf, prfLen, p.Keys[ver].AESKey, context, 256) case kdf_hkdf_sha256: reader := hkdf.New(sha256.New, p.Keys[ver].AESKey, nil, context) derBytes := bytes.NewBuffer(nil) derBytes.Grow(32) limReader := &io.LimitedReader{ R: reader, N: 32, } n, err := derBytes.ReadFrom(limReader) if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("error reading returned derived bytes: %v", err)} } if n != 32 { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to read enough derived bytes, needed 32, got %d", n)} } return derBytes.Bytes(), nil default: return nil, errutil.InternalError{Err: "unsupported key derivation mode"} } }
// DeriveKey is used to derive the encryption key that should // be used depending on the policy. If derivation is disabled the // raw key is used and no context is required, otherwise the KDF // mode is used with the context to derive the proper key. func (p *Policy) DeriveKey(context []byte) ([]byte, error) { // Fast-path non-derived keys if !p.Derived { return p.Key, nil } // Ensure a context is provided if len(context) == 0 { return nil, fmt.Errorf("missing 'context' for key deriviation. The key was created using a derived key, which means additional, per-request information must be included in order to encrypt or decrypt information.") } switch p.KDFMode { case kdfMode: prf := kdf.HMACSHA256PRF prfLen := kdf.HMACSHA256PRFLen return kdf.CounterMode(prf, prfLen, p.Key, context, 256) default: return nil, fmt.Errorf("unsupported key derivation mode") } }