Skip to content

Commit a755a00

Browse files
committed
Refactor TPM tests and add encryption unit tests
- Move GetCertHash to evetpm package for better reusability. - Migrate tpmmgr internal tests (testTpmEcdhSupport, testEcdhAES) to evetpm unit tests. - Add unit tests in encryptdecrypt_test.go covering AES GCM and TPM encryption. - Update TPM test setup scripts (tests/tpm/*.sh) to provision required keys and certificates. - Allow overriding of TPM file paths in locationconsts.go for testing purposes. Signed-off-by: Shahriyar Jalayeri <shahriyar@posteo.de>
1 parent 0bfac29 commit a755a00

File tree

8 files changed

+575
-190
lines changed

8 files changed

+575
-190
lines changed

pkg/pillar/cmd/tpmmgr/tpmmgr.go

Lines changed: 1 addition & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,17 @@ package tpmmgr
66
import (
77
"bytes"
88
"crypto"
9-
"crypto/aes"
109
"crypto/ecdsa"
1110
"crypto/elliptic"
1211
"crypto/rand"
13-
"crypto/sha256"
1412
"crypto/x509"
1513
"crypto/x509/pkix"
1614
"encoding/asn1"
1715
"encoding/pem"
1816
"flag"
1917
"fmt"
20-
"io"
2118
"math/big"
2219
"os"
23-
"reflect"
2420
"time"
2521

2622
"github.com/google/go-tpm/legacy/tpm2"
@@ -373,119 +369,6 @@ func printPCRs() {
373369
}
374370
}
375371

376-
func testTpmEcdhSupport() error {
377-
rw, err := tpm2.OpenTPM(etpm.TpmDevicePath)
378-
if err != nil {
379-
log.Errorln(err)
380-
return err
381-
}
382-
defer rw.Close()
383-
384-
z, p, err := tpm2.ECDHKeyGen(rw, etpm.TpmDeviceKeyHdl)
385-
if err != nil {
386-
fmt.Printf("generating Shared Secret failed: %s", err)
387-
return err
388-
}
389-
tpmOwnerPasswd, err := etpm.ReadOwnerCrdl()
390-
if err != nil {
391-
log.Errorf("Reading owner credential failed: %s", err)
392-
return err
393-
}
394-
395-
z1, err := tpm2.ECDHZGen(rw, etpm.TpmDeviceKeyHdl, tpmOwnerPasswd, *p)
396-
if err != nil {
397-
fmt.Printf("recovering Shared Secret failed: %s", err)
398-
return err
399-
}
400-
fmt.Println(reflect.DeepEqual(z, z1))
401-
return nil
402-
}
403-
404-
// Test ECDH key exchange and a symmetric cipher based on ECDH
405-
func testEcdhAES() error {
406-
//Simulate Controller generating an ephemeral key
407-
privateA, publicAX, publicAY, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
408-
if err != nil {
409-
fmt.Printf("Failed to generate A private/public key pair: %s\n", err)
410-
}
411-
412-
//read public key from ecdh certificate
413-
certBytes, err := os.ReadFile(ecdhCertFile)
414-
if err != nil {
415-
fmt.Printf("error in reading ecdh cert file: %v", err)
416-
return err
417-
}
418-
block, _ := pem.Decode(certBytes)
419-
cert, err := x509.ParseCertificate(block.Bytes)
420-
if err != nil {
421-
fmt.Printf("error in parsing ecdh cert file: %v", err)
422-
return err
423-
}
424-
publicB := cert.PublicKey.(*ecdsa.PublicKey)
425-
426-
//multiply privateA with publicB (Controller Part)
427-
X, Y := elliptic.P256().Params().ScalarMult(publicB.X, publicB.Y, privateA)
428-
429-
fmt.Printf("publicAX, publicAY, X/Y = %v, %v, %v, %v\n", publicAX, publicAY, X, Y)
430-
encryptKey, err := etpm.Sha256FromECPoint(X, Y, publicB)
431-
if err != nil {
432-
fmt.Printf("Sha256FromECPoint failed with error: %v", err)
433-
return err
434-
}
435-
iv := make([]byte, aes.BlockSize)
436-
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
437-
fmt.Printf("Unable to generate Initial Value %v\n", err)
438-
}
439-
440-
msg := []byte("this is the secret")
441-
ciphertext := make([]byte, len(msg))
442-
etpm.AESEncrypt(ciphertext, msg, encryptKey[:], iv)
443-
444-
recoveredMsg := make([]byte, len(ciphertext))
445-
certHash, err := getCertHash(certBytes, types.CertHashTypeSha256First16)
446-
if err != nil {
447-
fmt.Printf("getCertHash failed with error: %v", err)
448-
return err
449-
}
450-
451-
isTpm := true
452-
if !etpm.IsTpmEnabled() || fileutils.FileExists(log, etpm.EcdhKeyFile) {
453-
isTpm = false
454-
}
455-
456-
ecdhCert := &types.EdgeNodeCert{
457-
HashAlgo: types.CertHashTypeSha256First16,
458-
CertID: certHash,
459-
CertType: types.CertTypeEcdhXchange,
460-
Cert: certBytes,
461-
IsTpm: isTpm,
462-
}
463-
err = etpm.DecryptSecretWithEcdhKey(log, publicAX, publicAY, ecdhCert, iv, ciphertext, recoveredMsg)
464-
if err != nil {
465-
fmt.Printf("Decryption failed with error %v\n", err)
466-
return err
467-
}
468-
if reflect.DeepEqual(msg, recoveredMsg) == true {
469-
return nil
470-
} else {
471-
return fmt.Errorf("want %v, but got %v", msg, recoveredMsg)
472-
}
473-
}
474-
475-
func testEncryptDecrypt() error {
476-
plaintext := []byte("This is the Secret Key")
477-
ciphertext, err := etpm.EncryptDecryptUsingTpm(plaintext, types.Unespecified, true)
478-
if err != nil {
479-
return err
480-
}
481-
decryptedtext, err := etpm.EncryptDecryptUsingTpm(ciphertext, types.Unespecified, false)
482-
if reflect.DeepEqual(plaintext, decryptedtext) == true {
483-
return nil
484-
} else {
485-
return fmt.Errorf("want %v, but got %v", plaintext, decryptedtext)
486-
}
487-
}
488-
489372
func createQuoteCert() error {
490373
// certificate is already created
491374
if fileutils.FileExists(log, quoteCertFile) {
@@ -1147,16 +1030,6 @@ func readEdgeNodeCert(certPath string) ([]byte, error) {
11471030
return certBytes, nil
11481031
}
11491032

1150-
func getCertHash(cert []byte, hashAlgo types.CertHashType) ([]byte, error) {
1151-
certHash := sha256.Sum256(cert)
1152-
switch hashAlgo {
1153-
case types.CertHashTypeSha256First16:
1154-
return certHash[:16], nil
1155-
default:
1156-
return []byte{}, fmt.Errorf("Unsupported cert hash type: %d\n", hashAlgo)
1157-
}
1158-
}
1159-
11601033
func publishEdgeNodeCertToController(ctx *tpmMgrContext, certFile string, certType types.CertType, isTpm bool, metaDataItems []types.CertMetaData) {
11611034
log.Functionf("publishEdgeNodeCertToController started")
11621035
if !fileutils.FileExists(log, certFile) {
@@ -1169,7 +1042,7 @@ func publishEdgeNodeCertToController(ctx *tpmMgrContext, certFile string, certTy
11691042
log.Error(errStr)
11701043
return
11711044
}
1172-
certHash, err := getCertHash(certBytes, types.CertHashTypeSha256First16)
1045+
certHash, err := etpm.GetCertHash(certBytes, types.CertHashTypeSha256First16)
11731046
if err != nil {
11741047
errStr := fmt.Sprintf("publishEdgeNodeCertToController failed: %v", err)
11751048
log.Error(errStr)
@@ -1512,24 +1385,6 @@ func runCommand(command string, args []string) int {
15121385
printCapability()
15131386
case "printPCRs":
15141387
printPCRs()
1515-
case "testTpmEcdhSupport":
1516-
if err := testTpmEcdhSupport(); err != nil {
1517-
fmt.Printf("failed with error %v", err)
1518-
} else {
1519-
fmt.Print("test passed")
1520-
}
1521-
case "testEcdhAES":
1522-
if err := testEcdhAES(); err != nil {
1523-
fmt.Printf("failed with error %v", err)
1524-
} else {
1525-
fmt.Print("test passed")
1526-
}
1527-
case "testEncryptDecrypt":
1528-
if err := testEncryptDecrypt(); err != nil {
1529-
fmt.Printf("failed with error %v", err)
1530-
} else {
1531-
fmt.Print("test passed")
1532-
}
15331388
case "createCerts":
15341389
// Create required directories if not present
15351390
initializeDirs()

pkg/pillar/cmd/tpmmgr/tpmmgr_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,6 @@ func TestSoftEcdh(t *testing.T) {
122122
t.Errorf("Failed to create test key file: %v", err)
123123
}
124124
defer os.Remove(ecdhKeyFile)
125-
126-
if err = testEcdhAES(); err != nil {
127-
t.Errorf("%v", err)
128-
}
129125
}
130126

131127
// Test ECDH key exchange and a symmetric cipher based on ECDH, with software based keys

0 commit comments

Comments
 (0)