Skip to content

Commit

Permalink
Derive BastionID (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCutter authored Jun 12, 2024
1 parent 835ddb3 commit 08806a1
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/prometheus/client_golang v1.19.1
github.com/transparency-dev/armored-witness-boot v0.1.0
github.com/transparency-dev/armored-witness-common v0.0.0-20240313170947-0b19d0fb8b95
github.com/transparency-dev/armored-witness-os v0.1.2
github.com/transparency-dev/armored-witness-os v0.1.3-0.20240524123036-bdd4b0b96386
github.com/transparency-dev/formats v0.0.0-20231205184308-949529efd6b3
github.com/transparency-dev/serverless-log v0.0.0-20231215122707-66f68a7705f5
github.com/transparency-dev/witness v0.0.0-20240311170858-5de1177dc362
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ github.com/transparency-dev/armored-witness-boot v0.1.0 h1:OBlz71PCmPju9cDI1VEmy
github.com/transparency-dev/armored-witness-boot v0.1.0/go.mod h1:XpiSLWNiDplWVYjtR1FY/wyFqiWK++5pLCiYe3PZZC8=
github.com/transparency-dev/armored-witness-common v0.0.0-20240313170947-0b19d0fb8b95 h1:qOh9vp/TLfJ1X46bk756se0wdlKHSV2TrGUMa3kz91w=
github.com/transparency-dev/armored-witness-common v0.0.0-20240313170947-0b19d0fb8b95/go.mod h1:cb6aKsLVU2OUk8+UjD8xvzxU84miHXLMHJaxO2gHDus=
github.com/transparency-dev/armored-witness-os v0.1.2 h1:t8IrQQ9n0+lqvhASGfc9NOuEH3bykPSjtcMbWnARMZE=
github.com/transparency-dev/armored-witness-os v0.1.2/go.mod h1:Yt2PelPhnZ5Vc+/XJRPHoFaV5gTBw9xBXcMQJZTwSVM=
github.com/transparency-dev/armored-witness-os v0.1.3-0.20240524123036-bdd4b0b96386 h1:WHmJqV1L7dqAR5WXhOpFDL5jo4Rp2gCzvtmDh5FcX7E=
github.com/transparency-dev/armored-witness-os v0.1.3-0.20240524123036-bdd4b0b96386/go.mod h1:N+hTvqWTb08EeJC+DLEIPvnG4uI9ibnJVIA+oZaOBn4=
github.com/transparency-dev/formats v0.0.0-20231205184308-949529efd6b3 h1:Mpx9pqc7bKrx2QQxKL3SPbLIGH4gTBR1ZFrNuKq3CcY=
github.com/transparency-dev/formats v0.0.0-20231205184308-949529efd6b3/go.mod h1:tY9Z9oBaYdQt4NWIhsFAtv0altwLk+K9Gg/2tbS0eBQ=
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
Expand Down
48 changes: 48 additions & 0 deletions trusted_applet/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package main

import (
"crypto/aes"
"crypto/ed25519"
"crypto/sha256"
"encoding/binary"
"fmt"
Expand All @@ -37,6 +38,8 @@ var (
witnessPublicKey string
witnessSigningKey string
witnessPublicKeyAttestation string
bastionSigningKey ed25519.PrivateKey
bastionIDAttestation string
)

// deriveIdentityKeys creates this witness' signing and attestation identities.
Expand Down Expand Up @@ -68,6 +71,8 @@ func deriveIdentityKeys() {
prefix = "DEV:"
}

// Other than via the identity counter, the diversifier and key name in here
// MUST NOT be changed, or we'll break the invariant that this key is static.
witnessSigningKey, witnessPublicKey = deriveNoteSigner(
fmt.Sprintf("%sWitnessKey-id:%d", prefix, status.IdentityCounter),
status.Serial,
Expand All @@ -89,6 +94,18 @@ func deriveIdentityKeys() {
// were derived on a known armored witness unit.
witnessPublicKeyAttestation = attestID(&status, witnessPublicKey)

// Other than via the counter, the diversifier and key name in here
// MUST NOT be changed, or we'll break the invariant that this key is static.
bastionSec, bastionPub := deriveEd25519(
fmt.Sprintf("%sBastionKey-id:0", prefix),
status.Serial)
bastionSigningKey = bastionSec
bastionID := fmt.Sprintf("%064x", sha256.Sum256(bastionPub))

// Attest to the bastion ID so we can convince others that this ID
// was derived on a known armored witness unit
bastionIDAttestation = attestBastion(&status, bastionID)

}

// attestID uses attestSigningKey to sign a note which binds the passed in witness ID to this device's
Expand All @@ -109,6 +126,24 @@ func attestID(status *api.Status, pubkey string) string {
return attestNote(status, aN)
}

// attestBastion uses attestSigningKey to sign a note which binds the passed in witness ID to this device's
// serial number and current identity counter.
//
// The witness ID attestation note contents is formatted like so:
//
// "ArmoredWitness BastionID attestation v1"
// <Device serial string>
// <Witness BastionID counter in decimal>
// <Witness BastionID ASCII hex string>
//
// Returns the note verifier string which can be used to open the note, and the note containing the witness ID attestation.
func attestBastion(status *api.Status, bastionID string) string {
aN := &note.Note{
Text: fmt.Sprintf("ArmoredWitness BastionID attestation v1\n%s\n%d\n%s\n", status.Serial, 0, bastionID),
}
return attestNote(status, aN)
}

func attestNote(status *api.Status, aN *note.Note) string {
aSigner, err := note.NewSigner(attestSigningKey)
if err != nil {
Expand Down Expand Up @@ -137,6 +172,19 @@ func deriveNoteSigner(diversifier string, uniqueID string, keyName func(io.Reade
return sec, pub
}

// deriveEd25519 uses the hardware secret to device a new ed25519 keypair.
//
// diversifier should uniquely specify the key's intended usage, uniqueID should be the
// device's h/w unique identifier.
func deriveEd25519(diversifier string, uniqueID string) (ed25519.PrivateKey, ed25519.PublicKey) {
r := deriveHKDF(diversifier, uniqueID)
pub, priv, err := ed25519.GenerateKey(r)
if err != nil {
log.Fatalf("Failed to generate derived ed25519 key: %v", err)
}
return priv, pub
}

// randomName generates a random human-friendly name.
func randomName(rnd io.Reader) string {
// Figure out our name
Expand Down
2 changes: 2 additions & 0 deletions trusted_applet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ func main() {
Identity: witnessPublicKey,
IDAttestPublicKey: attestPublicKey,
AttestedID: witnessPublicKeyAttestation,
AttestedBastionID: bastionIDAttestation,
}, nil)

klog.Infof("Attestation key:\n%s", attestPublicKey)
Expand Down Expand Up @@ -281,6 +282,7 @@ func runWithNetworking(ctx context.Context) error {
Identity: witnessPublicKey,
IDAttestPublicKey: attestPublicKey,
AttestedID: witnessPublicKeyAttestation,
AttestedBastionID: bastionIDAttestation,
IP: addr.Address.String(),
}, nil)

Expand Down

0 comments on commit 08806a1

Please sign in to comment.