Implement new credential activation scheme for windows (#33)

* Implement new credential activation scheme for windows
This commit is contained in:
Tom D 2019-05-16 15:51:01 -07:00 committed by GitHub
parent 70c839779d
commit 5b7e00554a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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: