Example #1
0
 public static byte[] Encrypt(SymDefObject symDef, byte[] key, byte[] iv, byte[] dataToEncrypt)
 {
     using (SymmCipher cipher = Create(symDef, key, iv))
     {
         return(cipher.CFBEncrypt(dataToEncrypt));
     }
 }
Example #2
0
        internal byte[] ParmEncrypt(byte[] parm, Direction inOrOut)
        {
            if (Symmetric == null)
            {
                throw new Exception("parameter encryption cipher not defined");
            }
            if (Symmetric.Algorithm == TpmAlgId.Null)
            {
                return(parm);
            }

            byte[] nonceNewer, nonceOlder;
            if (inOrOut == Direction.Command)
            {
                nonceNewer = NonceCaller;
                nonceOlder = NonceTpm;
            }
            else
            {
                nonceNewer = NonceTpm;
                nonceOlder = NonceCaller;
            }

            byte[] encKey = (AuthHandle != null && AuthHandle.Auth != null) ?
                            SessionKey.Concat(AuthHandle.Auth).ToArray() : SessionKey;

            if (Symmetric.Algorithm == TpmAlgId.Xor)
            {
                return(CryptoLib.KdfThenXor(AuthHash, encKey, nonceNewer, nonceOlder, parm));
            }

            int keySize       = (Symmetric.KeyBits + 7) / 8,
                blockSize     = SymmCipher.GetBlockSize(Symmetric),
                bytesRequired = keySize + blockSize;

            byte[] keyInfo = KDF.KDFa(AuthHash, encKey, "CFB", nonceNewer, nonceOlder, (uint)(bytesRequired * 8));

            var key = new byte[keySize];

            Array.Copy(keyInfo, 0, key, 0, keySize);

            var iv = new byte[blockSize];

            Array.Copy(keyInfo, keySize, iv, 0, blockSize);

            // Make a new SymmCipher from the key and IV and do the encryption.
            using (SymmCipher s = SymmCipher.Create(Symmetric, key, iv))
            {
                return(inOrOut == Direction.Command ? s.CFBEncrypt(parm) : s.CFBDecrypt(parm));
            }
        }
Example #3
0
        /// <summary>
        /// Creates a duplication blob for the current key that can be Imported as a child
        /// of newParent. Three forms are possible. GetPlaintextDuplicationBlob() allows
        /// plaintext-import. This function enables duplication with and without an
        /// inner wrapper (depending on whether innerWrapper is null)
        /// </summary>
        /// <param name="newParent"></param>
        /// <param name="innerWrapper"></param>
        /// <param name="encryptedWrappingKey"></param>
        /// <returns></returns>
        public TpmPrivate GetDuplicationBlob(
            TpmPublic newParent,
            SymmCipher innerWrapper,
            out byte[] encryptedWrappingKey)
        {
            byte[] encSensitive;
            if (innerWrapper == null)
            {
                // No inner wrapper
                encSensitive = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation());
                Transform(encSensitive);
            }
            else
            {
                byte[] sens = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation());
                byte[] toHash = Globs.Concatenate(sens, GetName());
                Transform(toHash);
                byte[] innerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(publicPart.nameAlg, toHash));
                byte[] innerData = Globs.Concatenate(innerIntegrity, sens);
                Transform(innerData);
                encSensitive = innerWrapper.CFBEncrypt(innerData);
                Transform(encSensitive);
            }

            byte[] seed, encSecret;
            SymDefObject symDef = GetSymDef(newParent);

            using (AsymCryptoSystem newParentPubKey = AsymCryptoSystem.CreateFrom(newParent))
            {
                switch (newParent.type)
                {
                    case TpmAlgId.Rsa:
                        // The seed should be the same size as the symmKey
                        seed = Globs.GetRandomBytes((symDef.KeyBits + 7) / 8);
                        encSecret = newParentPubKey.EncryptOaep(seed, DuplicateEncodingParms);
                        break;
                    case TpmAlgId.Ecc:
                        EccPoint pubEphem;
                        seed = newParentPubKey.EcdhGetKeyExchangeKey(DuplicateEncodingParms,
                                                                     newParent.nameAlg,
                                                                     out pubEphem);
                        encSecret = Marshaller.GetTpmRepresentation(pubEphem);
                        break;
                    default:
                        throw new NotImplementedException("activate crypto scheme not implemented");
                }
            }
            Transform(seed);
            Transform(encSecret);

            encryptedWrappingKey = encSecret;

            byte[] symKey = KDF.KDFa(newParent.nameAlg, seed, "STORAGE", publicPart.GetName(), new byte[0], symDef.KeyBits);
            Transform(symKey);

            byte[] dupSensitive;
            using (SymmCipher enc2 = SymmCipher.Create(symDef, symKey))
            {
                dupSensitive = enc2.CFBEncrypt(encSensitive);
            }
            Transform(dupSensitive);

            int npNameNumBits = CryptoLib.DigestSize(newParent.nameAlg) * 8;
            byte[] hmacKey = KDF.KDFa(newParent.nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], (uint)npNameNumBits);

            byte[] outerDataToHmac = Globs.Concatenate(dupSensitive, publicPart.GetName());
            Transform(outerDataToHmac);

            byte[] outerHmac = Marshaller.ToTpm2B(CryptoLib.HmacData(newParent.nameAlg, hmacKey, outerDataToHmac));
            Transform(outerHmac);

            byte[] dupBlob = Globs.Concatenate(outerHmac, dupSensitive);
            Transform(dupBlob);

            return new TpmPrivate(dupBlob);
        }
Example #4
0
        /// <summary>
        /// Creates a duplication blob for the current key that can be Imported as a child
        /// of newParent. Three forms are possible. GetPlaintextDuplicationBlob() allows
        /// plaintext-import. This function enables duplication with and without an
        /// inner wrapper (depending on whether innerWrapper is null)
        /// </summary>
        /// <param name="newParent"></param>
        /// <param name="innerWrapper"></param>
        /// <param name="encryptedWrappingKey"></param>
        /// <returns></returns>
        public TpmPrivate GetDuplicationBlob(
            TpmPublic newParent,
            SymmCipher innerWrapper,
            out byte[] encryptedWrappingKey)
        {
            byte[] encSensitive;
            if (innerWrapper == null)
            {
                // No inner wrapper
                encSensitive = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation());
                Transform(encSensitive);
            }
            else
            {
                byte[] sens   = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation());
                byte[] toHash = Globs.Concatenate(sens, GetName());
                Transform(toHash);
                byte[] innerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(publicPart.nameAlg, toHash));
                byte[] innerData      = Globs.Concatenate(innerIntegrity, sens);
                Transform(innerData);
                encSensitive = innerWrapper.CFBEncrypt(innerData);
                Transform(encSensitive);
            }

            byte[]       seed, encSecret;
            SymDefObject symDef = GetSymDef(newParent);

            using (AsymCryptoSystem newParentPubKey = AsymCryptoSystem.CreateFrom(newParent))
            {
                switch (newParent.type)
                {
                case TpmAlgId.Rsa:
                    // The seed should be the same size as the symmKey
                    seed      = Globs.GetRandomBytes((symDef.KeyBits + 7) / 8);
                    encSecret = newParentPubKey.EncryptOaep(seed, DuplicateEncodingParms);
                    break;

                case TpmAlgId.Ecc:
                    EccPoint pubEphem;
                    seed = newParentPubKey.EcdhGetKeyExchangeKey(DuplicateEncodingParms,
                                                                 newParent.nameAlg,
                                                                 out pubEphem);
                    encSecret = Marshaller.GetTpmRepresentation(pubEphem);
                    break;

                default:
                    throw new NotImplementedException("activate crypto scheme not implemented");
                }
            }
            Transform(seed);
            Transform(encSecret);

            encryptedWrappingKey = encSecret;

            byte[] symKey = KDF.KDFa(newParent.nameAlg, seed, "STORAGE", publicPart.GetName(), new byte[0], symDef.KeyBits);
            Transform(symKey);

            byte[] dupSensitive;
            using (SymmCipher enc2 = SymmCipher.Create(symDef, symKey))
            {
                dupSensitive = enc2.CFBEncrypt(encSensitive);
            }
            Transform(dupSensitive);

            int npNameNumBits = CryptoLib.DigestSize(newParent.nameAlg) * 8;

            byte[] hmacKey = KDF.KDFa(newParent.nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], (uint)npNameNumBits);

            byte[] outerDataToHmac = Globs.Concatenate(dupSensitive, publicPart.GetName());
            Transform(outerDataToHmac);

            byte[] outerHmac = Marshaller.ToTpm2B(CryptoLib.HmacData(newParent.nameAlg, hmacKey, outerDataToHmac));
            Transform(outerHmac);

            byte[] dupBlob = Globs.Concatenate(outerHmac, dupSensitive);
            Transform(dupBlob);

            return(new TpmPrivate(dupBlob));
        }
Example #5
0
        /// <summary>
        /// Create activation blobs that can be passed to ActivateCredential.  Two blobs are returned -
        /// (a) - encryptedSecret - is the symmetric key cfb-symmetrically encrypted with an enveloping key
        /// (b) credentialBlob (the return value of this function) - is the enveloping key OEAP (RSA) encrypted
        ///         by the public part of this key.
        /// </summary>
        /// <param name="secret"></param>
        /// <param name="nameAlgId"></param>
        /// <param name="nameOfKeyToBeActivated"></param>
        /// <param name="encryptedSecret"></param>
        /// <returns>CredentialBlob (</returns>
        public byte[] CreateActivationCredentials(
            byte[] secret,
            TpmAlgId nameAlgId,
            byte[] nameOfKeyToBeActivated,
            out byte[] encryptedSecret)
        {
            byte[] seed, encSecret;

            switch (type)
            {
            case TpmAlgId.Rsa:
                // The seed should be the same size as the symmKey
                seed      = Globs.GetRandomBytes((CryptoLib.DigestSize(nameAlg) + 7) / 8);
                encSecret = EncryptOaep(seed, ActivateEncodingParms);
                break;

            case TpmAlgId.Ecc:
                EccPoint pubEphem;
                seed      = EcdhGetKeyExchangeKey(ActivateEncodingParms, nameAlg, out pubEphem);
                encSecret = Marshaller.GetTpmRepresentation(pubEphem);
                break;

            default:
                throw new NotImplementedException("activate crypto scheme not implemented");
            }

            Transform(seed);
            Transform(encSecret);

            var cvx = new Tpm2bDigest(secret);

            byte[] cvTpm2B = Marshaller.GetTpmRepresentation(cvx);
            Transform(cvTpm2B);

            SymDefObject symDef = TssObject.GetSymDef(this);

            byte[] symKey = KDF.KDFa(nameAlg, seed, "STORAGE", nameOfKeyToBeActivated, new byte[0], symDef.KeyBits);
            Transform(symKey);

            byte[] encIdentity;
            using (SymmCipher symm2 = SymmCipher.Create(symDef, symKey))
            {
                encIdentity = symm2.CFBEncrypt(cvTpm2B);
            }
            Transform(encIdentity);

            var hmacKeyBits = (uint)CryptoLib.DigestSize(nameAlg);

            byte[] hmacKey = KDF.KDFa(nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], hmacKeyBits * 8);
            Transform(hmacKey);
            byte[] outerHmac = CryptoLib.HmacData(nameAlg,
                                                  hmacKey,
                                                  Globs.Concatenate(encIdentity, nameOfKeyToBeActivated));
            Transform(outerHmac);

            byte[] activationBlob = Globs.Concatenate(
                Marshaller.ToTpm2B(outerHmac),
                encIdentity);

            Transform(activationBlob);

            encryptedSecret = encSecret;

            return(activationBlob);
        }