Re: Subject Key Attestation Evidence "light" - Invention Disclosure

"Timothy J. Miller" <tmiller@mitre.org> Fri, 19 September 2008 16:32 UTC

Return-Path: <owner-ietf-smime@mail.imc.org>
X-Original-To: ietfarch-smime-archive@core3.amsl.com
Delivered-To: ietfarch-smime-archive@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 3315A3A6987 for <ietfarch-smime-archive@core3.amsl.com>; Fri, 19 Sep 2008 09:32:49 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -5.399
X-Spam-Level:
X-Spam-Status: No, score=-5.399 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, J_CHICKENPOX_26=0.6, J_CHICKENPOX_46=0.6, RCVD_IN_DNSWL_MED=-4]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id N-JBGa9KMSlH for <ietfarch-smime-archive@core3.amsl.com>; Fri, 19 Sep 2008 09:32:47 -0700 (PDT)
Received: from balder-227.proper.com (properopus-pt.tunnel.tserv3.fmt2.ipv6.he.net [IPv6:2001:470:1f04:392::2]) by core3.amsl.com (Postfix) with ESMTP id 43D393A68FE for <smime-archive@ietf.org>; Fri, 19 Sep 2008 09:32:46 -0700 (PDT)
Received: from balder-227.proper.com (localhost [127.0.0.1]) by balder-227.proper.com (8.14.2/8.14.2) with ESMTP id m8JGF6LO066060 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 19 Sep 2008 09:15:06 -0700 (MST) (envelope-from owner-ietf-smime@mail.imc.org)
Received: (from majordom@localhost) by balder-227.proper.com (8.14.2/8.13.5/Submit) id m8JGF6oj066059; Fri, 19 Sep 2008 09:15:06 -0700 (MST) (envelope-from owner-ietf-smime@mail.imc.org)
X-Authentication-Warning: balder-227.proper.com: majordom set sender to owner-ietf-smime@mail.imc.org using -f
Received: from smtp-bedford.mitre.org (smtp-bedford.mitre.org [129.83.20.191]) by balder-227.proper.com (8.14.2/8.14.2) with ESMTP id m8JGF4kr066052 for <ietf-smime@imc.org>; Fri, 19 Sep 2008 09:15:05 -0700 (MST) (envelope-from tmiller@mitre.org)
Received: from smtp-bedford.mitre.org (localhost.localdomain [127.0.0.1]) by smtp-bedford.mitre.org (8.13.1/8.13.1) with ESMTP id m8JGF42U026537 for <ietf-smime@imc.org>; Fri, 19 Sep 2008 12:15:04 -0400
Received: from imchub1.MITRE.ORG (imchub1.mitre.org [129.83.29.73]) by smtp-bedford.mitre.org (8.13.1/8.13.1) with ESMTP id m8JGF4QY026533; Fri, 19 Sep 2008 12:15:04 -0400
Received: from [129.83.200.30] (129.83.200.30) by imchub1.MITRE.ORG (129.83.29.73) with Microsoft SMTP Server (TLS) id 8.1.278.0; Fri, 19 Sep 2008 12:15:04 -0400
Message-ID: <48D3D002.7030108@mitre.org>
Date: Fri, 19 Sep 2008 11:14:58 -0500
From: "Timothy J. Miller" <tmiller@mitre.org>
User-Agent: Thunderbird 2.0.0.16 (Windows/20080708)
MIME-Version: 1.0
To: Anders Rundgren <anders.rundgren@telia.com>
CC: ietf-smime@imc.org, Russ Housley <housley@vigilsec.com>
Subject: Re: Subject Key Attestation Evidence "light" - Invention Disclosure
References: <00e101c91a2b$e2481320$82c5a8c0@arport2v> <48B6B19801185BEB@pne-smtpin1-sn2.hy.skanova.net> (added by postmaster@pne.skanova.net) <024501c91a6b$fd73d720$82c5a8c0@arport2v>
In-Reply-To: <024501c91a6b$fd73d720$82c5a8c0@arport2v>
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha1"; boundary="------------ms040700020709040103040109"
Sender: owner-ietf-smime@mail.imc.org
Precedence: bulk
List-Archive: <http://www.imc.org/ietf-smime/mail-archive/>
List-ID: <ietf-smime.imc.org>
List-Unsubscribe: <mailto:ietf-smime-request@imc.org?body=unsubscribe>

I'm curious--don't most token management systems tackle the same issue 
by establishing a secure channel with the token (using the token key 
encryption key, provisioned at manufacture)?

-- Tim

Anders Rundgren wrote:
> Well, maybe I formulated the message bad but I don't
> claim any IPR and the idea was that nobody else should
> be able to do it either since patents in large-scale Open Source
> projects don't work well.  My (maybe naive) hope was that
> a public disclosure in "authoritative places" would put the
> idea in the public domain.  I'm not aware of that this
> concept is featured in any RFC or work-in-progress
> except for in KeyGen2 (which is not going to be RFCed
> until it is/becomes firmly established).
> 
> Regards
> Anders
> 
> ----- Original Message ----- 
> From: "Russ Housley" <housley@vigilsec.com>
> To: "Anders Rundgren" <anders.rundgren@telia.com>; <ietf-smime@imc.org>
> Sent: Friday, September 19, 2008 16:25
> Subject: Re: Subject Key Attestation Evidence "light" - Invention Disclosure
> 
> 
> Please file a formal IPR statement on the IETF web site, especially
> if you believe that this invention is related to any RFC or
> Internet-Draft.  The URL for IPR statements is:
> https://datatracker.ietf.org/ipr/about/
> 
> Thanks,
>    Russ
> 
> At 03:46 AM 9/19/2008, Anders Rundgren wrote:
> 
>> The following may be prior art, or be common knowledge. It may
>> even be a bad idea.  However, the publishing was only done
>> in order to thwart possible future IPR claims.  If the principle
>> is already patented, I would appreciate more information
>> if possible.  The concept described is primarily intended for usage
>> with mobile phones having embedded crypto hardware which should
>> be the majority within 5-10 years from now, since crypto hardware is
>> close to a requirement for making secure operating systems.
>> In case you find the mail version hard to read, there is a PDF with
>> the same content available:
>> http://webpki.org/papers/keygen2/SubjectKeyAttestationEvidence-light__InventionDisclosure.pdf
>>
>> The decribed scheme is an intrinsic part of the KeyGen2 universal
>> key-provisioning protocol:
>> http://webpki.org/papers/keygen2/keygen2-key-attestation-1.pdf
>>
>> SKAE "light" - Invention Disclosure
>> ------------------------------------
>>
>> Background
>> =========
>>
>> In some cryptographic systems, asymmetric key-pairs may be
>> internally generated in Security Elements (SEs), like Smart Cards.
>> For on-line (remote) provisioning of keys to SEs, there is a whish
>> by CAs to be able to securely verify that the public key part
>> they receive for inclusion in a certificate, indeed was (together
>> with its private counterpart), generated inside of a "genuine" SE.
>>
>> To support this requirement the TrustedComputingGroup's (TCG's)
>> Trusted Platform Module (TPM) V1.2 specification features a
>> mechanism known as Subject Key Attestation Evidence (SKAE).
>>
>> Prerequisite: The SE contains an embedded private key and a
>> matching public key certificate identifying the SE in some way that
>> makes sense for CAs.  The private key is used for signing evidence
>> attestations regarding generated key-pairs.
>>
>> Problem: If the embedded private key of the SE is also to be usable
>> for other cryptographic operations, a "hacked" software environment
>> could exploit this by creating unprotected key-pairs externally and
>> still be able providing CAs with genuine-looking attestation
>> evidences.  TCG's solution to this problem is based on the use
>> of dedicated key attest keys, specific X.509 certificate extensions,
>> and potentially also relying on multiple CA roots.  Although
>> working, this scheme appears unnecessary complex for supporting
>> a single-purpose key.
>>
>> Solution
>> ======
>>
>> The following steps describe how a simpler form of SKAE,
>> purely based on cryptography, could be implemented in an SE.
>>
>> First you need to restrict the SE key-certifying private key from being
>> able to perform unformatted ("blank") RSA decryption
>> operations through direct API calls to the SE.
>>
>> You MAY still allow the key-certifying key creating standard
>> PKCS #1 signatures which are useful for many purposes including
>> authentication and message integrity.  Encryption operations using
>> the public key MAY also be supported.
>>
>> To support SKAE, the proposal is to create a unique variant of PKCS #1
>> signatures that must only be generated during key-generation.
>> Such a signature MAY also be created if the SE is explicitly invoked with
>> a previously generated public key, unless that would lead
>> to key-reuse vulnerabilities.
>>
>> A unique variant of PKCS #1 could in its simplest form be implemented
>> through the use of a non-standard padding pattern.  The hash
>> algorithms to use would still be the existing SHA-1 etc.  A verifier
>> should then be able to securely distinguish between standard
>> signatures and SKAE signatures.  A nonce option would also be
>> suitable for inclusion in the signature packet.   On the next pages,
>> there is a sample program in Java implementing the proposed
>> SKAE scheme.
>>
>> Although this scheme only describes PKCS #1 (RSA) keys, the
>> principles are presumable applicable to other asymmetric key types as
>> well including ECDSA.
>>
>> One might consider the proposed solution as a standards-defying
>> "kludge", but the fact is that all current SKAE schemes rely on very
>> specific generation and validation code.
>>
>> The primary target for this invention are mobile phones which are
>> likely to be fitted with secure hardware fairly soon, since this
>> is more or less a requirement for other purposes as well, most
>> notably for Operating System integrity protection.
>>
>> Side Effect: PoP Becomes Redundant
>> ==========================
>>
>> It seems that a properly designed SKAE scheme makes
>> Proof of Possession (PoP) signatures like in CRMF (RFC 4211)
>> redundant which is an advantage because combining PoP
>> signatures with PIN-code provisioning introduces fairly
>> awkward state-handling in SEs since the generated private
>> key typically must be used before it is fully provisioned.
>>
>> Anders Rundgren, WebPKI.org, September 15, 2008
>>
>> Author's address:
>> Storbolsäng 50
>> 740 10 Almunge
>> Sweden
>>
>> Email: anders.rundgren@telia.com
>>
>> ---------------------------------------------------------------------
>>
>>
>> import javax.crypto.Cipher;
>>
>> import java.security.GeneralSecurityException;
>> import java.security.MessageDigest;
>> import java.security.PublicKey;
>> import java.security.PrivateKey;
>> import java.security.KeyPair;
>> import java.security.KeyPairGenerator;
>>
>> import java.security.interfaces.RSAKey;
>>
>> /**
>>  * SKAE (Subject Key Attestation Evidence).  The following J2SE
>> compatible code is meant illustrate
>>  * the use of SKAE signatures.
>>  */
>> public class skae
>>   {
>>     static final String SHA_1            = "SHA-1";
>>
>>     static final String UNFORMATTED_RSA  = "RSA/ECB/NoPadding";
>>
>>     static final byte[] PS_END_SEQUENCE  = new byte[] {(byte)0x00,
>> (byte)'S',  (byte)'K',  (byte)'A',  (byte)'E'};
>>
>>     static final byte[] DIGEST_INFO_SHA1 = new byte[] {(byte)0x30,
>> (byte)0x21, (byte)0x30, (byte)0x09, (byte)0x06,
>>                                                        (byte)0x05,
>> (byte)0x2b, (byte)0x0e, (byte)0x03, (byte)0x02,
>>                                                        (byte)0x1a,
>> (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x14};
>>
>>
>>     /**
>>      * Create an SKAE package for signing or verification
>>      * @param rsa_key The certifying (attesting) private or public key.
>>      * @param certified_public_key The certified (attested) key.
>>      * @param optional_nonce An optional "nonce" element.
>>      * @return The SKAE package.
>>      */
>>     public static byte[] createSKAEPackage (RSAKey rsa_key,
>>                                             PublicKey certified_public_key,
>>                                             byte[] optional_nonce)
>>     throws GeneralSecurityException
>>       {
>>
>> ////////////////////////////////////////////////////////////////////////////////////////
>>         // To make it feasible securely distinguishing standard
>> RSASSA-PKCS1.5 signatures     //
>>         // from SKAE signatures the latter are packaged in a
>> different way which should       //
>>         // create errors if processed by a crypto library that does
>> not support SKAE.         //
>>         // The following shows the packaging differences in
>> detail.                           //
>>         //
>>                            //
>>         // EMSA-PKCS1-v1_5: EM = 0x00 || 0x01 || PS || 0x00 ||
>> T                              //
>>         //
>>                            //
>>         // EM-PKCS1-SKAE:   EM = 0x00 || 0x01 || PS || 0x00 || 'S'
>> || 'K' || 'A' || 'E' || T  //
>>
>> ////////////////////////////////////////////////////////////////////////////////////////
>>         byte[] modulus = rsa_key.getModulus ().toByteArray ();
>>         int k = modulus.length;
>>         if (modulus[0] == 0) k--;
>>         byte[] encoded_message = new byte [k];
>>         encoded_message[0] = (byte)0;
>>         encoded_message[1] = (byte)1;
>>         MessageDigest md = MessageDigest.getInstance (SHA_1);
>>         if (optional_nonce != null)
>>           {
>>             md.update (optional_nonce);
>>           }
>>         byte[] hash = md.digest (certified_public_key.getEncoded ());
>>         int i = k - 2 - PS_END_SEQUENCE.length - hash.length -
>> DIGEST_INFO_SHA1.length;
>>         int j = 2;
>>         while (i-- > 0)
>>           {
>>             encoded_message[j++] = (byte)0xff;
>>           }
>>         i = 0;
>>         while (i < PS_END_SEQUENCE.length)
>>           {
>>             encoded_message[j++] = PS_END_SEQUENCE[i++];
>>           }
>>         System.arraycopy (DIGEST_INFO_SHA1, 0, encoded_message, j,
>> DIGEST_INFO_SHA1.length);
>>         System.arraycopy (hash, 0, encoded_message, j +
>> DIGEST_INFO_SHA1.length, hash.length);
>>         return encoded_message;
>>       }
>>
>>
>>
>>    /**
>>      * Verify an SKAE signature
>>      * @param skae_signature The signature to be verified.
>>      * @param certifying_public_key The certifying (attesting) public key.
>>      * @param certified_public_key The certified (attested) key.
>>      * @param optional_nonce An optional "nonce" element.
>>      * @throws GeneralSecurityException if the signature is invalid
>> or indata is incorrect.
>>      */
>>     public static void verifySKAESignature (byte[] skae_signature,
>>                                             PublicKey certifying_public_key,
>>                                             PublicKey certified_public_key,
>>                                             byte[] optional_nonce)
>>     throws GeneralSecurityException
>>       {
>>         Cipher cipher = Cipher.getInstance (UNFORMATTED_RSA);
>>         cipher.init (Cipher.ENCRYPT_MODE, certifying_public_key);
>>         byte[] received_signature_package = cipher.doFinal (skae_signature);
>>         byte[] reference_signature_package = createSKAEPackage
>> ((RSAKey)certifying_public_key,
>>
>> certified_public_key,
>>
>> optional_nonce);
>>         if (reference_signature_package.length !=
>> received_signature_package.length)
>>           {
>>             throw new GeneralSecurityException ("Signature package
>> length error");
>>           }
>>         for (int i = 0; i < received_signature_package.length ; i++)
>>           {
>>             if (received_signature_package[i] !=
>> reference_signature_package[i])
>>               {
>>                 // A more comprehensive diagnostic would be preferable...
>>                 throw new GeneralSecurityException ("Signature
>> package content error");
>>               }
>>           }
>>       }
>>
>>
>>     public static class GeneratedKey
>>       {
>>         PublicKey certified_public_key;
>>         PublicKey certifying_public_key;
>>         byte[] skae_signature;
>>       }
>>
>>
>>     public static class SecurityElement
>>       {
>>         PublicKey certifying_public_key;
>>
>>         private PrivateKey certifying_private_key;
>>
>>         public SecurityElement () throws GeneralSecurityException
>>           {
>>             /////////////////////////////////////////////////////////////////
>>             // Key-certifying keys are typically created once during       //
>>             // device manufacturing. The public key part is also most      //
>>             // likely distributed in an X.509 certificate issued by a CA   //
>>             // setup specifically for certifying crypto hardware.          //
>>             // That is, the following lines are just for showing the       //
>>             // cryptography, without any infrastructural considerations.   //
>>             /////////////////////////////////////////////////////////////////
>>             KeyPairGenerator certifier =
>> KeyPairGenerator.getInstance ("RSA");
>>             certifier.initialize (2048);
>>             KeyPair certifying_key_pair = certifier.generateKeyPair ();
>>             certifying_public_key = certifying_key_pair.getPublic ();
>>             certifying_private_key = certifying_key_pair.getPrivate ();
>>           }
>>
>>
>>         /**
>>          * Create a certified key-pair.
>>          * @param size The size of the RSA key.
>>          * @param optional_nonce An optional "nonce" element.
>>          * @return A container with a generated public key and
>> attesting signature.
>>          */
>>         public GeneratedKey generateCertifiedKeyPair (int size,
>> byte[] optional_nonce)
>>         throws GeneralSecurityException
>>           {
>>             /////////////////////////////////////////////////////////////////
>>             // Generate a new key-pair in the Security Element.  The       //
>>             // private key is presumably stored securely in hardware and   //
>>             // never leave its container, unless "sealed" by the latter.   //
>>             /////////////////////////////////////////////////////////////////
>>             KeyPairGenerator kpg = KeyPairGenerator.getInstance ("RSA");
>>             kpg.initialize (size);
>>             KeyPair new_key_pair = kpg.generateKeyPair ();
>>
>>             /////////////////////////////////////////////////////////////////
>>             // Now let the Security Element attest that the new key-pair   //
>>             // actually was created inside of the Security Element.        //
>>             //                                                             //
>>             // NOTE 1: The Security Element MUST NOT expose an API that    //
>>             // allows unformatted RSA decryptions like used below to be    //
>>             // performed with the key-certifying key, otherwise "malware"  //
>>             // could easily create fake attestations for any externally    //
>>             // supplied key-pair!                                          //
>>             //                                                             //
>>             // NOTE 2: Due to the fact that SKAE signatures are only to    //
>>             // be created for generated keys, the key-certifying key MAY   //
>>             // also be used for creating ordinary PKCS1.5 signatures for   //
>>             // things like authentications and securing message integrity  //
>>             /////////////////////////////////////////////////////////////////
>>             GeneratedKey gk = new GeneratedKey ();
>>             gk.certified_public_key = new_key_pair.getPublic ();
>>             Cipher cipher = Cipher.getInstance (UNFORMATTED_RSA);
>>             cipher.init (Cipher.DECRYPT_MODE, certifying_private_key);
>>             gk.skae_signature = cipher.doFinal (createSKAEPackage
>> ((RSAKey)certifying_private_key,
>>
>> gk.certified_public_key,
>>
>> optional_nonce));
>>             gk.certifying_public_key = certifying_public_key;
>>             return gk;
>>           }
>>       }
>>
>>
>>     public static void main (String[] args) throws Exception
>>       {
>>
>>         /////////////////////////////////////////////////////////////////
>>         //                                                             //
>>         //                     CLIENT Operations                       //
>>         //                                                             //
>>         // It is assumed that the critical operations are performed    //
>>         // inside of the Security Element, otherwise attestations      //
>>         // would not be more trustworthy than the environment where    //
>>         // the Security Element is actually running in!                //
>>         /////////////////////////////////////////////////////////////////
>>         SecurityElement se = new SecurityElement ();
>>
>>         /////////////////////////////////////////////////////////////////
>>         // Generate a new key-pair in the Security Element.  The       //
>>         // private key is presumably stored securely in hardware and   //
>>         // never leave its container, unless "sealed" by the latter.   //
>>         /////////////////////////////////////////////////////////////////
>>         byte[] nonce = null; // Didn't use a nonce in the sample run
>>         GeneratedKey gk = se.generateCertifiedKeyPair (1024, nonce);
>>
>>         /////////////////////////////////////////////////////////////////
>>         //                                                             //
>>         //                     VERIFIER Operations                     //
>>         //                                                             //
>>         // The certifying public key is supposed to be transferred to  //
>>         // the verifier by some kind of protocol, together with the    //
>>         // SKAE-signature, certified public key, and the optional      //
>>         // nonce.  A nonce (if used) would preferably be created by    //
>>         // the verifier during an earlier (not shown) protocol phase.  //
>>         /////////////////////////////////////////////////////////////////
>>         verifySKAESignature (gk.skae_signature,
>>                              gk.certifying_public_key,
>>                              gk.certified_public_key,
>>                              nonce);
>>
>>         System.out.println ("The SKAE signature appears to be valid!");
>>       }
>>
>>   }
>