15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 3: Commands
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h"
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "RSA_Decrypt_fp.h"
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_RSA
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Error Returns                     Meaning
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15cc08a97054435c8da283dffc0bf089b56862dc18Scott//     TPM_RC_ATTRIBUTES                 If the key is restricted or the key is not a decryption key
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_BINDING                    The public an private parts of the key are not properly bound
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_KEY                        keyHandle does not reference an unrestricted decrypt key
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SCHEME                     incorrect input scheme, or the chosen scheme is not a valid RSA
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       decrypt scheme
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SIZE                       cipherText is not the size of the modulus of key referenced by
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       keyHandle
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_VALUE                      label is not a null terminated string or the value of cipherText is
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       greater that the modulus of keyHandle
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
265679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM2_RSA_Decrypt(
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_Decrypt_In        *in,                   // IN: input parameter list
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   RSA_Decrypt_Out       *out                   // OUT: output parameter list
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                             result;
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   OBJECT                            *rsaKey;
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMT_RSA_DECRYPT                  *scheme;
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   char                              *label = NULL;
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Input Validation
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   rsaKey = ObjectGet(in->keyHandle);
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The selected key must be an RSA key
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(rsaKey->publicArea.type != TPM_ALG_RSA)
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_KEY + RC_RSA_Decrypt_keyHandle;
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The selected key must be an unrestricted decryption key
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(   rsaKey->publicArea.objectAttributes.restricted == SET
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      || rsaKey->publicArea.objectAttributes.decrypt == CLEAR)
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_ATTRIBUTES + RC_RSA_Decrypt_keyHandle;
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   NOTE: Proper operation of this command requires that the sensitive area
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   of the key is loaded. This is assured because authorization is required
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   to use the sensitive area of the key. In order to check the authorization,
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //   the sensitive area has to be loaded, even if authorization is with policy.
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If label is present, make sure that it is a NULL-terminated string
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(in->label.t.size > 0)
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Present, so make sure that it is NULL-terminated
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(in->label.t.buffer[in->label.t.size - 1] != 0)
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_VALUE + RC_RSA_Decrypt_label;
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       label = (char *)in->label.t.buffer;
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Command Output
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Select a scheme for decrypt.
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   scheme = CryptSelectRSAScheme(in->keyHandle, &in->inScheme);
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  if(scheme == NULL)
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      return TPM_RC_SCHEME + RC_RSA_Decrypt_inScheme;
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Decryption. TPM_RC_VALUE, TPM_RC_SIZE, and TPM_RC_KEY error may be
715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // returned by CryptDecryptRSA.
725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // NOTE: CryptDecryptRSA can also return TPM_RC_ATTRIBUTES or TPM_RC_BINDING
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // when the key is not a decryption key but that was checked above.
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  out->message.t.size = sizeof(out->message.t.buffer);
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  result = CryptDecryptRSA(&out->message.t.size, out->message.t.buffer, rsaKey,
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           scheme, in->cipherText.t.size,
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           in->cipherText.t.buffer,
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           label);
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return result;
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif
83