Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a secretbox and AES-CBC path for encrypt at rest #46916

Merged
merged 4 commits into from
Jun 8, 2017

Conversation

smarterclayton
Copy link
Contributor

@smarterclayton smarterclayton commented Jun 3, 2017

Add a secretbox and AES-CBC encrypt at rest provider and alter the config, based on feedback from security review. AES-CBC is more well reviewed and generally fits better with common criteria and FIPS, secretbox is newer and faster than CBC.

Add secretbox and AES-CBC encryption modes to at rest encryption.  AES-CBC is considered superior to AES-GCM because it is resistant to nonce-reuse attacks, and secretbox uses Poly1305 and XSalsa20.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jun 3, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: smarterclayton

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot k8s-github-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. release-note-label-needed labels Jun 3, 2017
@smarterclayton smarterclayton added this to the v1.7 milestone Jun 3, 2017
@smarterclayton
Copy link
Contributor Author

We may decide to go with this to avoid nonce collisions and reduce the need to rotate.

@smarterclayton smarterclayton assigned jcbsmpsn and destijl and unassigned timothysc and jcbsmpsn Jun 3, 2017
@k8s-github-robot k8s-github-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 3, 2017
@smarterclayton smarterclayton force-pushed the secretbox branch 2 times, most recently from 27094db to 21c67d7 Compare June 4, 2017 03:44
@smarterclayton
Copy link
Contributor Author

smarterclayton commented Jun 4, 2017

Added a CBC mode for comparison:

go test ./vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/ -bench=Bench* -test.run=XXX
BenchmarkGCMRead_16_1024-8          	 2000000	       791 ns/op
BenchmarkGCMRead_32_1024-8          	 2000000	       862 ns/op
BenchmarkGCMRead_32_16384-8         	  200000	      8199 ns/op
BenchmarkGCMRead_32_16384_Stale-8   	  200000	      8236 ns/op
BenchmarkGCMWrite_16_1024-8         	 1000000	      2156 ns/op
BenchmarkGCMWrite_32_1024-8         	 1000000	      2253 ns/op
BenchmarkGCMWrite_32_16384-8        	  100000	     14217 ns/op
BenchmarkCBCRead_32_1024-8          	  500000	      2902 ns/op
BenchmarkCBCRead_32_16384-8         	   30000	     42035 ns/op
BenchmarkCBCRead_32_16384_Stale-8   	   30000	     41715 ns/op
BenchmarkCBCWrite_32_1024-8         	  300000	      4766 ns/op
BenchmarkCBCWrite_32_16384-8        	   30000	     53546 ns/op
BenchmarkSecretboxRead_32_1024-8         1000000              2032 ns/op
BenchmarkSecretboxRead_32_16384-8         100000             22749 ns/op
BenchmarkSecretboxRead_32_16384_Stale-8   100000             22696 ns/op
BenchmarkSecretboxWrite_32_1024-8         300000              4132 ns/op
BenchmarkSecretboxWrite_32_16384-8         50000             30591 ns/op

@k8s-github-robot k8s-github-robot removed the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 5, 2017
@sakshamsharma
Copy link
Contributor

@smarterclayton In context of your comment on #46460 (which is merged now)

We'll need to update this based on #46916

I believe we simply need another configuration option for CBC? Is a small change, but perhaps we have to wait till next month for it (and the above changes) to go in now?

@smarterclayton
Copy link
Contributor Author

smarterclayton commented Jun 6, 2017 via email

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 6, 2017
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 6, 2017
@destijl
Copy link
Member

destijl commented Jun 6, 2017

@smarterclayton this seems like a good idea to me. I can update the extension thread with a request to get this in, plus the config change to allow people to use it. Are you writing the config change too?

@smarterclayton
Copy link
Contributor Author

I need to sync with @sakshamsharma on that.

@smarterclayton
Copy link
Contributor Author

Yeah @simo5 signed off on the encryption stuff so we're only reviewing config.

@sakshamsharma
Copy link
Contributor

sakshamsharma commented Jun 7, 2017

Maybe we can replace the Boolean with an enumerated variable? We can easily add more underlying encryption algorithms later, which have the same parsing logic.

It may help reduce a lot of code reuse.

@smarterclayton
Copy link
Contributor Author

@destijl did we get release approval for the exception?

@smarterclayton smarterclayton added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-label-needed labels Jun 7, 2017
@smarterclayton smarterclayton changed the title Add a secretbox implementation for encryption Add a secretbox and AES-CBC path for encrypt at rest Jun 7, 2017
@destijl
Copy link
Member

destijl commented Jun 7, 2017

I asked dawn on the thread I started for the exemption, I believe so.

aesTransformerPrefixV1 = "k8s:enc:aes:v1:"
aesCBCTransformerPrefixV1 = "k8s:enc:aescbc:v1:"
aesGCMTransformerPrefixV1 = "k8s:enc:aesgcm:v1:"
secretboxTransformerPrefixV1 = "k8s:enc:secretbox:v1"
)
Copy link
Contributor

@sakshamsharma sakshamsharma Jun 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smarterclayton

Context:

sakshamsharma 23 hours ago
I would ideally think that we need shorter prefixes. Like: gcm, cbc, secb.
smarterclayton 9 hours ago
We will almost certainly need to version them in the future, and we want to ensure we have enough key space to evolve if we have to.

Versioned prefixes are fine, what I mean is, we could do k8s:enc:secb:v1 etc, because these prefixes are not user/developer/admin facing. Of course, the premise is that these long prefixes are a storage overhead. If this premise is not significant, we can ignore this.

@smarterclayton
Copy link
Contributor Author

smarterclayton commented Jun 7, 2017 via email

@dchen1107
Copy link
Member

dchen1107 commented Jun 8, 2017

The release team's decision on the exception request of encrypt secrets in etcd which includes this pr is yes. Thanks!

cc/ @kubernetes/kubernetes-release-managers

@smarterclayton smarterclayton added approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm "Looks good to me", indicates that a PR is ready to be merged. labels Jun 8, 2017
@smarterclayton
Copy link
Contributor Author

Applying labels based on two part review

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 46979, 47078, 47138, 46916)

@k8s-github-robot k8s-github-robot merged commit d16d64f into kubernetes:master Jun 8, 2017
k8s-github-robot pushed a commit that referenced this pull request Jun 15, 2017
Automatic merge from submit-queue (batch tested with PRs 47510, 47516, 47482, 47521, 47537)

Fix typo in secretbox transformer prefix

Introduced by #46916 via cherry picked commit [here](sakshamsharma@12bb591).

Urgent fix in my opinion, ideally should be merged before production.

@smarterclayton
k8s-github-robot pushed a commit that referenced this pull request Jun 16, 2017
Automatic merge from submit-queue

Add encryption provider support via environment variables

These changes are needed to allow cloud providers to use the encryption providers as an alpha feature. The version checks can be done in the respective cloud providers'.

Context: #46460 and #46916

@destijl @jcbsmpsn @smarterclayton

func TestSecretboxKeyRotation(t *testing.T) {
testErr := fmt.Errorf("test error")
context := value.DefaultContext([]byte("authenticated_data"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we're passing different values as a context here and bellow while secretboxTransformer doesn't use the context at all? Why not pass nil instead?

if stale {
p = value.NewPrefixTransformers(nil,
value.PrefixTransformer{Prefix: []byte("first:"), Transformer: NewSecretboxTransformer(key1)},
value.PrefixTransformer{Prefix: []byte("second:"), Transformer: NewSecretboxTransformer(key2)},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order the same: looks like code or comment is wrong.

if stale {
p = value.NewPrefixTransformers(nil,
value.PrefixTransformer{Prefix: []byte("first:"), Transformer: NewCBCTransformer(block1)},
value.PrefixTransformer{Prefix: []byte("second:"), Transformer: NewCBCTransformer(block2)},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same here: the order hasn't been changed.

return result, fmt.Errorf("could not obtain secret for named key %s: %s", keyData.Name, err)
}

if len(key) != 32 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there are reason why we're validating key length only for Secretbox?

Looks we can do the same for AES-GCM (16,24,32) and AES-CBC (32).

@smarterclayton Let me know if you agree and I'll prepare PR for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're validating it only for secretbox because it requires a fixed size array as input. AES-GCM returns a sane error itself, if the key size is not valid. For secretbox, if we did not validate and convert it to a [32]byte safely, it may throw a runtime error. We need to throw a sane error, and AES-GCM already does that. I'm not sure about CBC though.

}

keyArray := [32]byte{}
copy(keyArray[:], key)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smarterclayton Copying the key looks useless. Why we can't use DecodeString() result as-is?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention of copying was to convert a byte slice to a [32]byte, and, however ugly, this came up as the best way to do it when I verified it via some quick google search 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the explanation!

@lavalamp lavalamp removed their assignment Jul 17, 2017
k8s-github-robot pushed a commit that referenced this pull request Aug 26, 2017
Automatic merge from submit-queue (batch tested with PRs 49850, 47782, 50595, 50730, 51341)

Fix benchmarks to really test reverse order of the keys

**What this PR does / why we need it**:
This PR modifies the code to do what comments says -- reverse the order of keys. It also fixes the logic that was wrong and didn't allow stale data.

**Special notes for your reviewer**:
This change resolves the following review comments:
- #41939 (comment)
- #46916 (comment)
- #46916 (comment)

**Release note**:
```release-note
NONE
```

PTAL @smarterclayton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.