Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:golang-github-tillitis-tkeyclient
User: [email protected]
Usertags: pu

[ Reason ]
Hi!  Upstream has provided an advisory:

https://github.com/tillitis/tkeyclient/security/advisories/GHSA-4w7r-3222-8h6v

While this could be handled by a security patch, due to the complexity
of upstream's recommended solution (involving patches to
'tkey-ssh-agent' too) and low impact, it was suggested on
#debian-security to use the proposed-updated mechanism instead to just
update both packages to latest upstream version.

I'm attaching the debdiff between 1.2.0 and 1.3.0 and I suggest
something similar could be uploaded to trixie-proposed-updates.

What do you think?  Is this an acceptable way to resolve this?

If so I can prepare a similar debdiff bug report for 'tkey-ssh-agent'
for your additional review.  These two would have to go together.

[ Impact ]
If this isn't adopted, one out of 256 users that provides a USS secret
will not actually make use of the USS, thus possibly lowering their
perceived security.

[ Tests ]
This is upstream patches, so presumably well tested.

[ Risks ]
There is always a risk upstream's patches are buggy and cause unrelated
problems.

[ Checklist ]
  [ ] *all* changes are documented in the d/changelog
  [ ] I reviewed all changes and I approve them
  [ ] attach debdiff against the package in (old)stable
  [ ] the issue is verified as fixed in unstable

[ Changes ]
(Explain *all* the changes)

[ Other info ]
(Anything else the release team should know.)
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/debian/changelog golang-github-tillitis-tkeyclient-1.3.0/debian/changelog
--- golang-github-tillitis-tkeyclient-1.2.0/debian/changelog	2025-12-07 21:20:28.000000000 +0100
+++ golang-github-tillitis-tkeyclient-1.3.0/debian/changelog	2026-03-16 21:00:48.000000000 +0100
@@ -1,3 +1,15 @@
+golang-github-tillitis-tkeyclient (1.3.0-1) unstable; urgency=medium
+
+  * New upstream release
+   - Fixes GHSA-4w7r-3222-8h6v
+  * Use gbp sign-tags and upstream-vcs-tag
+  * Drop Priority: optional
+  * Standards-Version: 4.7.3
+  * Bump debian/* copyright years
+  * Drop upstreamed patch
+
+ -- Simon Josefsson <[email protected]>  Mon, 16 Mar 2026 21:00:48 +0100
+
 golang-github-tillitis-tkeyclient (1.2.0-2) unstable; urgency=medium
 
   * Upload to unstable
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/debian/control golang-github-tillitis-tkeyclient-1.3.0/debian/control
--- golang-github-tillitis-tkeyclient-1.2.0/debian/control	2025-12-07 21:20:28.000000000 +0100
+++ golang-github-tillitis-tkeyclient-1.3.0/debian/control	2026-03-16 20:59:15.000000000 +0100
@@ -1,6 +1,5 @@
 Source: golang-github-tillitis-tkeyclient
 Section: golang
-Priority: optional
 Maintainer: Debian Go Packaging Team <[email protected]>
 Uploaders:
  Simon Josefsson <[email protected]>,
@@ -12,7 +11,7 @@
  golang-github-ccoveille-go-safecast-dev (>> 2.0.0~),
  golang-golang-x-crypto-dev,
 Testsuite: autopkgtest-pkg-go
-Standards-Version: 4.7.2
+Standards-Version: 4.7.3
 Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-tillitis-tkeyclient
 Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-tillitis-tkeyclient.git
 Homepage: https://github.com/tillitis/tkeyclient
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/debian/copyright golang-github-tillitis-tkeyclient-1.3.0/debian/copyright
--- golang-github-tillitis-tkeyclient-1.2.0/debian/copyright	2025-12-07 21:20:28.000000000 +0100
+++ golang-github-tillitis-tkeyclient-1.3.0/debian/copyright	2026-03-16 20:59:23.000000000 +0100
@@ -7,7 +7,7 @@
 License: BSD-2-clause
 
 Files: debian/*
-Copyright: 2024-2025 Simon Josefsson <[email protected]>
+Copyright: 2024-2026 Simon Josefsson <[email protected]>
 License: BSD-2-clause
 Comment: Debian packaging is licensed under the same terms as upstream
 
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/debian/gbp.conf golang-github-tillitis-tkeyclient-1.3.0/debian/gbp.conf
--- golang-github-tillitis-tkeyclient-1.2.0/debian/gbp.conf	2025-12-07 21:20:28.000000000 +0100
+++ golang-github-tillitis-tkeyclient-1.3.0/debian/gbp.conf	2026-03-16 20:58:55.000000000 +0100
@@ -1,3 +1,5 @@
 [DEFAULT]
 debian-branch = debian/sid
 dist = DEP14
+sign-tags = True
+upstream-vcs-tag = v%(version%~%-)s
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/debian/patches/Bump-go-safecast-to-v2.0.0.patch golang-github-tillitis-tkeyclient-1.3.0/debian/patches/Bump-go-safecast-to-v2.0.0.patch
--- golang-github-tillitis-tkeyclient-1.2.0/debian/patches/Bump-go-safecast-to-v2.0.0.patch	2025-12-07 21:20:28.000000000 +0100
+++ golang-github-tillitis-tkeyclient-1.3.0/debian/patches/Bump-go-safecast-to-v2.0.0.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,54 +0,0 @@
-From b078fe3e4fa515f1e2f7a9b055c61d3193260a01 Mon Sep 17 00:00:00 2001
-From: Simon Josefsson <[email protected]>
-Date: Sun, 7 Dec 2025 11:09:07 +0100
-Subject: [PATCH] Bump go-safecast to v2.0.0 closes #23
-
----
- go.mod        |  3 ++-
- go.sum        |  4 ++--
- tkeyclient.go | 10 +++++-----
- 3 files changed, 9 insertions(+), 8 deletions(-)
-
-diff --git a/tkeyclient.go b/tkeyclient.go
-index e5a05d3..8a90765 100644
---- a/tkeyclient.go
-+++ b/tkeyclient.go
-@@ -35,7 +35,7 @@ import (
- 	"os"
- 	"time"
- 
--	"github.com/ccoveille/go-safecast"
-+	"github.com/ccoveille/go-safecast/v2"
- 	"go.bug.st/serial"
- 	"golang.org/x/crypto/blake2s"
- )
-@@ -212,22 +212,22 @@ func (u *UDI) Unpack(raw []byte) error {
- 	var err error
- 
- 	vpr := binary.LittleEndian.Uint32(raw[0:4])
--	u.Unnamed, err = safecast.ToUint8((vpr >> 28) & 0xf)
-+	u.Unnamed, err = safecast.Convert[uint8]((vpr >> 28) & 0xf)
- 	if err != nil {
- 		return fmt.Errorf("%w", err)
- 	}
- 
--	u.VendorID, err = safecast.ToUint16((vpr >> 12) & 0xffff)
-+	u.VendorID, err = safecast.Convert[uint16]((vpr >> 12) & 0xffff)
- 	if err != nil {
- 		return fmt.Errorf("%w", err)
- 	}
- 
--	u.ProductID, err = safecast.ToUint8((vpr >> 6) & 0x3f)
-+	u.ProductID, err = safecast.Convert[uint8]((vpr >> 6) & 0x3f)
- 	if err != nil {
- 		return fmt.Errorf("%w", err)
- 	}
- 
--	u.ProductRevision, err = safecast.ToUint8(vpr & 0x3f)
-+	u.ProductRevision, err = safecast.Convert[uint8](vpr & 0x3f)
- 	if err != nil {
- 		return fmt.Errorf("%w", err)
- 	}
--- 
-2.52.0
-
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/debian/patches/series golang-github-tillitis-tkeyclient-1.3.0/debian/patches/series
--- golang-github-tillitis-tkeyclient-1.2.0/debian/patches/series	2025-12-07 21:20:28.000000000 +0100
+++ golang-github-tillitis-tkeyclient-1.3.0/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-Bump-go-safecast-to-v2.0.0.patch
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/.github/workflows/golangci-lint.yml golang-github-tillitis-tkeyclient-1.3.0/.github/workflows/golangci-lint.yml
--- golang-github-tillitis-tkeyclient-1.2.0/.github/workflows/golangci-lint.yml	2025-08-19 15:14:14.000000000 +0200
+++ golang-github-tillitis-tkeyclient-1.3.0/.github/workflows/golangci-lint.yml	2026-03-16 13:23:29.000000000 +0100
@@ -15,10 +15,10 @@
     name: lint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
-      - uses: actions/setup-go@v5
+      - uses: actions/checkout@v6
+      - uses: actions/setup-go@v6
         with:
-          go-version: '1.21'
+          go-version: '1.23'
           cache: false
       - name: golangci-lint
         uses: golangci/golangci-lint-action@v6
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/go.mod golang-github-tillitis-tkeyclient-1.3.0/go.mod
--- golang-github-tillitis-tkeyclient-1.2.0/go.mod	2025-08-19 15:14:14.000000000 +0200
+++ golang-github-tillitis-tkeyclient-1.3.0/go.mod	2026-03-16 13:23:29.000000000 +0100
@@ -3,7 +3,7 @@
 go 1.23.0
 
 require (
-	github.com/ccoveille/go-safecast v1.1.0
+	github.com/ccoveille/go-safecast/v2 v2.0.0
 	go.bug.st/serial v1.6.2
 	golang.org/x/crypto v0.40.0
 )
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/go.sum golang-github-tillitis-tkeyclient-1.3.0/go.sum
--- golang-github-tillitis-tkeyclient-1.2.0/go.sum	2025-08-19 15:14:14.000000000 +0200
+++ golang-github-tillitis-tkeyclient-1.3.0/go.sum	2026-03-16 13:23:29.000000000 +0100
@@ -1,5 +1,5 @@
-github.com/ccoveille/go-safecast v1.1.0 h1:iHKNWaZm+OznO7Eh6EljXPjGfGQsSfa6/sxPlIEKO+g=
-github.com/ccoveille/go-safecast v1.1.0/go.mod h1:QqwNjxQ7DAqY0C721OIO9InMk9zCwcsO7tnRuHytad8=
+github.com/ccoveille/go-safecast/v2 v2.0.0 h1:+5eyITXAUj3wMjad6cRVJKGnC7vDS55zk0INzJagub0=
+github.com/ccoveille/go-safecast/v2 v2.0.0/go.mod h1:JIYA4CAR33blIDuE6fSwCp2sz1oOBahXnvmdBhOAABs=
 github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
 github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/RELEASE.md golang-github-tillitis-tkeyclient-1.3.0/RELEASE.md
--- golang-github-tillitis-tkeyclient-1.2.0/RELEASE.md	2025-08-19 15:14:14.000000000 +0200
+++ golang-github-tillitis-tkeyclient-1.3.0/RELEASE.md	2026-03-16 13:23:29.000000000 +0100
@@ -1,5 +1,18 @@
 # Release notes
 
+## v1.3.0
+
+- Version v1.2.0 and earlier had a protocol vulnerability leaving some
+  USSs unused. A CDI generated from use of this package might be
+  changed since earlier versions! Read more here:
+
+  https://github.com/tillitis/tkeyclient/security/advisories/GHSA-4w7r-3222-8h6v
+
+Complete
+[changelog](https://github.com/tillitis/tkeyclient/compare/v1.2.0...v1.3.0).
+
+- Adds new option function WithFullUss() for use with Connect().
+
 ## v1.2.0
 
 - Detect new Castor USB VID/PID and older TKey models.
diff -Nru golang-github-tillitis-tkeyclient-1.2.0/tkeyclient.go golang-github-tillitis-tkeyclient-1.3.0/tkeyclient.go
--- golang-github-tillitis-tkeyclient-1.2.0/tkeyclient.go	2025-08-19 15:14:14.000000000 +0200
+++ golang-github-tillitis-tkeyclient-1.3.0/tkeyclient.go	2026-03-16 13:23:29.000000000 +0100
@@ -35,7 +35,7 @@
 	"os"
 	"time"
 
-	"github.com/ccoveille/go-safecast"
+	"github.com/ccoveille/go-safecast/v2"
 	"go.bug.st/serial"
 	"golang.org/x/crypto/blake2s"
 )
@@ -66,8 +66,9 @@
 // TillitisKey is a serial connection to a TKey and the commands that
 // the firmware supports.
 type TillitisKey struct {
-	speed int
-	conn  serial.Port
+	speed        int
+	conn         serial.Port
+	forceFullUss bool
 }
 
 // New allocates a new TillitisKey. Use the Connect() method to
@@ -77,18 +78,27 @@
 	return tk
 }
 
+// Option to set serial speed. For use with Connect.
 func WithSpeed(speed int) func(*TillitisKey) {
 	return func(tk *TillitisKey) {
 		tk.speed = speed
 	}
 }
 
+// Option to force use of 32 byte USS digest on Bellatrix and earlier. For use with Connect.
+func WithFullUss() func(*TillitisKey) {
+	return func(tk *TillitisKey) {
+		tk.forceFullUss = true
+	}
+}
+
 // Connect connects to a TKey serial port using the provided port
 // device and options.
 func (tk *TillitisKey) Connect(port string, options ...func(*TillitisKey)) error {
 	var err error
 
 	tk.speed = SerialSpeed
+	tk.forceFullUss = false
 	for _, opt := range options {
 		opt(tk)
 	}
@@ -218,22 +228,22 @@
 	var err error
 
 	vpr := binary.LittleEndian.Uint32(raw[0:4])
-	u.Unnamed, err = safecast.ToUint8((vpr >> 28) & 0xf)
+	u.Unnamed, err = safecast.Convert[uint8]((vpr >> 28) & 0xf)
 	if err != nil {
 		return fmt.Errorf("%w", err)
 	}
 
-	u.VendorID, err = safecast.ToUint16((vpr >> 12) & 0xffff)
+	u.VendorID, err = safecast.Convert[uint16]((vpr >> 12) & 0xffff)
 	if err != nil {
 		return fmt.Errorf("%w", err)
 	}
 
-	u.ProductID, err = safecast.ToUint8((vpr >> 6) & 0x3f)
+	u.ProductID, err = safecast.Convert[uint8]((vpr >> 6) & 0x3f)
 	if err != nil {
 		return fmt.Errorf("%w", err)
 	}
 
-	u.ProductRevision, err = safecast.ToUint8(vpr & 0x3f)
+	u.ProductRevision, err = safecast.Convert[uint8](vpr & 0x3f)
 	if err != nil {
 		return fmt.Errorf("%w", err)
 	}
@@ -287,17 +297,22 @@
 	return tk.LoadApp(content, secretPhrase)
 }
 
-// LoadApp loads the USS (User Supplied Secret), and contents of bin
-// into the TKey, running the app after verifying that the digest
-// calculated on the host is the same as the digest from the TKey.
+// LoadApp sends a device app in bin and optionally a User Supplied
+// Secret digest to the TKey.
+//
+// After successfully sending the device app it computes a digest over
+// bin and compares it to what was returned from the TKey, returning
+// an error if it isn't equal.
+//
+// The USS is a BLAKE2s digest of the secretPhrase argument. How much
+// of the digest is used differs on different hardware:
+//
+//   - Bellatrix and earlier: last 31 bytes of the digest for backward
+//     compatibility reasons.
 //
-// The USS is a 32 bytes digest hashed from secretPhrase (which is
-// provided by the user). If secretPhrase is an empty slice, 32 bytes
-// of zeroes will be loaded as USS.
+//   - Castor and later: all 32 bytes used.
 //
-// Loading USS is always done together with loading and running an
-// app, because the host program can't otherwise be sure that the
-// expected USS is used.
+// Returns ErrResponseStatusNotOK if firmware is not detected.
 func (tk TillitisKey) LoadApp(bin []byte, secretPhrase []byte) error {
 	binLen := len(bin)
 	if binLen > AppMaxSize {
@@ -306,8 +321,13 @@
 
 	le.Printf("app size: %v, 0x%x, 0b%b\n", binLen, binLen, binLen)
 
-	err := tk.loadApp(binLen, secretPhrase)
+	udi, err := tk.GetUDI()
 	if err != nil {
+		// Probably not running firmware? Or communication error
+		return err
+	}
+
+	if err = tk.loadApp(binLen, secretPhrase, udi.ProductID); err != nil {
 		return err
 	}
 
@@ -346,7 +366,7 @@
 }
 
 // loadApp sets the size and USS of the app to be loaded into the TKey.
-func (tk TillitisKey) loadApp(size int, secretPhrase []byte) error {
+func (tk TillitisKey) loadApp(size int, secretPhrase []byte, pid uint8) error {
 	id := 2
 	tx, err := NewFrameBuf(cmdLoadApp, id)
 	if err != nil {
@@ -365,7 +385,13 @@
 		tx[6] = 1
 		// Hash user's phrase as USS
 		uss := blake2s.Sum256(secretPhrase)
-		copy(tx[6:], uss[:])
+
+		if pid >= UDIPIDCastor || tk.forceFullUss {
+			copy(tx[7:], uss[:])
+		} else {
+			// skip first byte for backwards compatibility, 31 byte uss
+			copy(tx[7:], uss[1:])
+		}
 	}
 
 	Dump("LoadApp tx", tx)

Attachment: signature.asc
Description: PGP signature

Reply via email to