mirror of
https://github.com/google/go-attestation.git
synced 2025-01-02 19:26:49 +00:00
Implement new credential activation scheme for windows (#33)
* Implement new credential activation scheme for windows
This commit is contained in:
parent
70c839779d
commit
5b7e00554a
@ -183,89 +183,42 @@ func (k *Key) Marshal() ([]byte, error) {
|
|||||||
return json.Marshal(k)
|
return json.Marshal(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeTrousersCredential(secretKey, blob []byte) ([]byte, error) {
|
func decryptCredential(secretKey, blob []byte) ([]byte, error) {
|
||||||
var header struct {
|
var scheme uint32
|
||||||
Credsize uint32
|
|
||||||
AlgID uint32
|
|
||||||
EncScheme uint16
|
|
||||||
SigScheme uint16
|
|
||||||
Parmsize uint32
|
|
||||||
}
|
|
||||||
symbuf := bytes.NewReader(blob)
|
symbuf := bytes.NewReader(blob)
|
||||||
if err := binary.Read(symbuf, binary.BigEndian, &header); err != nil {
|
if err := binary.Read(symbuf, binary.BigEndian, &scheme); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("reading scheme: %v", err)
|
||||||
}
|
}
|
||||||
// Unload the symmetric key parameters.
|
if scheme != 0x00000002 {
|
||||||
parms := make([]byte, header.Parmsize)
|
return nil, fmt.Errorf("can only handle CBC schemes")
|
||||||
if err := binary.Read(symbuf, binary.BigEndian, parms); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Unpack the symmetrically encrypted secret.
|
|
||||||
cred := make([]byte, header.Credsize)
|
|
||||||
if err := binary.Read(symbuf, binary.BigEndian, cred); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A TPM representation of a symmetric key, which is the
|
iv := make([]byte, 16)
|
||||||
// format of the blob returned from TPM_ActivateIdentity.
|
if err := binary.Read(symbuf, binary.BigEndian, &iv); err != nil {
|
||||||
var k struct {
|
|
||||||
AlgID uint32
|
|
||||||
EncScheme uint16
|
|
||||||
Key []byte
|
|
||||||
}
|
|
||||||
in := bytes.NewReader(secretKey)
|
|
||||||
if err := binary.Read(in, binary.BigEndian, &k.AlgID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := binary.Read(in, binary.BigEndian, &k.EncScheme); err != nil {
|
cipherText := make([]byte, len(blob)-20)
|
||||||
return nil, err
|
if err := binary.Read(symbuf, binary.BigEndian, &cipherText); err != nil {
|
||||||
|
return nil, fmt.Errorf("reading ciphertext: %v", err)
|
||||||
}
|
}
|
||||||
var size uint16
|
|
||||||
if err := binary.Read(in, binary.BigEndian, &size); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
key := make([]byte, size)
|
|
||||||
if err := binary.Read(in, binary.BigEndian, &key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
k.Key = key
|
|
||||||
|
|
||||||
// Decrypt the credential.
|
// Decrypt the credential.
|
||||||
var (
|
var (
|
||||||
block cipher.Block
|
block cipher.Block
|
||||||
iv []byte
|
secret []byte
|
||||||
ciphertxt []byte
|
err error
|
||||||
secret []byte
|
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
switch id := k.AlgID; id {
|
block, err = aes.NewCipher(secretKey)
|
||||||
case 6: // algAES128
|
if err != nil {
|
||||||
block, err = aes.NewCipher(k.Key)
|
return nil, fmt.Errorf("aes.NewCipher failed: %v", err)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("aes.NewCipher failed: %v", err)
|
|
||||||
}
|
|
||||||
iv = cred[:aes.BlockSize]
|
|
||||||
ciphertxt = cred[aes.BlockSize:]
|
|
||||||
secret = ciphertxt
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("%v is not a supported session key algorithm", id)
|
|
||||||
}
|
|
||||||
switch es := k.EncScheme; es {
|
|
||||||
case 4: // esSymCTR
|
|
||||||
stream := cipher.NewCTR(block, iv)
|
|
||||||
stream.XORKeyStream(secret, ciphertxt)
|
|
||||||
case 5: // esSymOFB
|
|
||||||
stream := cipher.NewOFB(block, iv)
|
|
||||||
stream.XORKeyStream(secret, ciphertxt)
|
|
||||||
case 0xff: // esSymCBCPKCS5 - tcsd specific
|
|
||||||
mode := cipher.NewCBCDecrypter(block, iv)
|
|
||||||
mode.CryptBlocks(secret, ciphertxt)
|
|
||||||
// Remove PKCS5 padding.
|
|
||||||
padlen := int(secret[len(secret)-1])
|
|
||||||
secret = secret[:len(secret)-padlen]
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("%v is not a supported encryption scheme", es)
|
|
||||||
}
|
}
|
||||||
|
secret = cipherText
|
||||||
|
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
mode.CryptBlocks(secret, cipherText)
|
||||||
|
// Remove PKCS5 padding.
|
||||||
|
padlen := int(secret[len(secret)-1])
|
||||||
|
secret = secret[:len(secret)-padlen]
|
||||||
return secret, nil
|
return secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +236,7 @@ func (k *Key) ActivateCredential(tpm *TPM, in EncryptedCredential) ([]byte, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return decodeTrousersCredential(secretKey, in.Secret)
|
return decryptCredential(secretKey, in.Secret)
|
||||||
case TPMVersion20:
|
case TPMVersion20:
|
||||||
return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
|
return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user