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

crypto/hmac: detect reuse of hash.Hash value #41089

Closed
dvsekhvalnov opened this issue Aug 28, 2020 · 9 comments
Closed

crypto/hmac: detect reuse of hash.Hash value #41089

dvsekhvalnov opened this issue Aug 28, 2020 · 9 comments
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@dvsekhvalnov
Copy link

dvsekhvalnov commented Aug 28, 2020

Good time of the day,

with go 1.15 release it seems there is some regression issue introduced with respect to crypto/hmac package.

Was troubleshooting dvsekhvalnov/jose2go#26 and found that hmac.Reset() is no longer behave same way as it was before (at least when called first), crafted minimal test case:

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"hash"
)

func main() {
	sha := sha256.New()
	hmac := hmac.New(func() hash.Hash { return sha }, []byte("anything"))

	hmac.Reset()        // if you try to comment / uncomment that line, go 1.15 will produce different results
	hmac.Write([]byte("salt"))

	test := hmac.Sum(nil)

	fmt.Printf("test = %v\n", test)
}

Is it producing output:

  1. [169 238 50 31 23 163 57 12 228 112 77 219 51 95 12 6 185 17 156 244 116 243 186 227 89 79 64 19 227 242 86 186] on go v1.15
  2. [213 21 105 177 57 151 62 247 23 137 16 75 59 26 241 187 229 148 88 219 30 222 223 77 186 120 81 74 247 237 232 66] on go v.14 and below

, more over toggling leading hmac.Reset() will produce different results with 1.15 vs. previous versions.

It seems change was introduced by 97240d5
So will tag @magical and @FiloSottile here.

Honestly i don't know may be calling hmac.Reset before everything else is not sane idea, but it's not documented anywhere and clearly was behaving differently before.

Thank you.

@ALTree ALTree changed the title "crypto/hmac" on 1.15 is no longer compatible with previous verisons? crypto/hmac: 1.15 change in behaviour of the Reset method Aug 28, 2020
@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 28, 2020
@FiloSottile
Copy link
Contributor

Thank you for the report, this should absolutely work and is a regression. @gopherbot, open a Go 1.15 backport issue, please.

@gopherbot
Copy link

Backport issue(s) opened: #41097 (for 1.15).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases.

@FiloSottile
Copy link
Contributor

FiloSottile commented Aug 28, 2020

Hmm, at a first look I had not noticed that the first argument to New is func() hash.Hash { return sha }, a function that returns always the same hash instance. That is not how it's meant to be used, it should be func() hash.Hash { return sha256.New() } or simply sha256.New.

Now I'm surprised this ever worked, because that makes the inner and outer hash share state.

With the correct argument, calling Reset before any input works as expected. https://play.golang.org/p/PbneuUK9F0Y

@FiloSottile
Copy link
Contributor

FiloSottile commented Aug 28, 2020

This sort of used to work because a single HMAC used to serialize to these operations

h.inner.Write(hm.ipad)      // New
h.inner.Reset()             // Reset
h.inner.Write(hm.ipad)      // Reset
h.inner.Write(p)            // Write
h.inner.Sum(in)             // Sum
h.outer.Reset()             // Sum
h.outer.Write(h.opad)       // Sum
h.outer.Write(in[origLen:]) // Sum
h.outer.Sum(in[:origLen])   // Sum

unless the key was longer than the blocksize (in which case outer gets used in New).

If you tried calling Sum a second time, it would also have broken, because inner gets corrupted by the use of outer.

So this never worked. We could add a panic to make sure the returned values are different, so no one else makes this mistake.

@FiloSottile FiloSottile added Documentation NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Aug 28, 2020
@FiloSottile FiloSottile added this to the Go1.16 milestone Aug 28, 2020
@FiloSottile FiloSottile changed the title crypto/hmac: 1.15 change in behaviour of the Reset method crypto/hmac: detect reuse of hash.Hash value Aug 28, 2020
@dvsekhvalnov
Copy link
Author

Thanks @FiloSottile ! Changing from value to New func made it.

dgryski added a commit to dgryski/semgrep-go that referenced this issue Aug 28, 2020
@katiehockman katiehockman self-assigned this Sep 22, 2020
@katiehockman
Copy link
Contributor

We're going to panic if inner and outer are the same in the hmac.New function, indicating that the hash function doesn't produce unique outputs.

@gopherbot
Copy link

Change https://golang.org/cl/261960 mentions this issue: crypto/hmac: panic if reusing hash.Hash values

@magical
Copy link
Contributor

magical commented Oct 13, 2020

SGTM. My only worry is that the check may panic if the underlying values are not comparable, but that seems unlikely to ever come up in practice.

e.g. https://play.golang.org/p/ZtuAvkQZMFX

@katiehockman
Copy link
Contributor

@magical Thanks for pointing that out. I went ahead and updated the PR to reflect that concern.

anthraxx added a commit to anthraxx/alicloud-vault that referenced this issue Mar 1, 2021
This resolves a problem that arises with Go 1.16 where the hmac API has
been changed to detect passed hash functions that return a static value
instead of distinguish values:
golang/go#41089
golang/go@2a206c7#diff-0b6881eef540c340af6cd0a8d8258c625f8c950ff091a22abd0778c4dad5dcaaR138-R144

The new keyring version internally pulls in a bumped jose2go version,
which is required to properly handle the passed hmac hash function.

dvsekhvalnov/jose2go@85193dd

Signed-off-by: Levente Polyak <levente@leventepolyak.net>
wy65701436 added a commit to wy65701436/harbor that referenced this issue Jun 29, 2021
Fixes goharbor#14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you're already on Harbor v2.2.0 ~ v2.2.2 and have signed images with notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
wy65701436 added a commit to wy65701436/harbor that referenced this issue Jun 29, 2021
Fixes goharbor#14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you pushed and signed image using Harbor v2.2.0 ~ v2.2.2 and created new repository key in notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
wy65701436 added a commit to wy65701436/harbor that referenced this issue Jun 29, 2021
Fixes goharbor#14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you pushed and signed image using Harbor v2.2.0 ~ v2.2.2 and created new repository key in notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
wy65701436 added a commit to wy65701436/harbor that referenced this issue Jun 29, 2021
Fixes goharbor#14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you pushed and signed image using Harbor v2.2.0 ~ v2.2.2 and created new repository key in notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
wy65701436 added a commit to goharbor/harbor that referenced this issue Jun 29, 2021
Fixes #14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you pushed and signed image using Harbor v2.2.0 ~ v2.2.2 and created new repository key in notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
wy65701436 added a commit to goharbor/harbor that referenced this issue Jun 29, 2021
Fixes #14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you pushed and signed image using Harbor v2.2.0 ~ v2.2.2 and created new repository key in notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
yunkunrao pushed a commit to yunkunrao/harbor that referenced this issue Aug 19, 2021
Fixes goharbor#14932

Harbor recompiles the notary v0.6.1 with go 1.15 from v2.2.0, which introduces an break change that leads to notary key not found after migration.

[Root cause]
Notary v0.6.1 consumed an old version dvsekhvalnov/jose2, which is not compatible with go 1.15.

[References]
dvsekhvalnov/jose2go#26
golang/go#41089

[Resolve]
To resolve this issue, we have to roll back go vesrion to v1.14 for notary v0.6.1 binary and keep it until upstream have a patch release to support go 1.15 or above.

[Break change]
If you pushed and signed image using Harbor v2.2.0 ~ v2.2.2 and created new repository key in notary, you will encouter the same issue after migrate to v2.2.3(or above) or v2.3.1(or above) because of the go version downgrade. We will have a FAQ to help you to resovle this particular scenario.

The influence path of the particular case:
Harbor v2.1.0(or lower) --> [v2.2.0 ~ v2.2.2] --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.0 --> v2.3.1(or above)

The non influence path of the paticular case:
Harbor v2.1.0(or lower) --> v2.2.3(or above)
Harbor v2.1.0(or lower) --> v2.3.1(or above)

[Fix in Version]
Harbor v2.2.3 or above
Harbor v2.3.1 or above

[Note]
If you're a heavy user of notary, avoid using v2.2.0, v2.2.1, v2.2.2 and v2.3.0, and use the fixed version for instead.

Signed-off-by: Wang Yan <wangyan@vmware.com>
@golang golang locked and limited conversation to collaborators Oct 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants