Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 3: Commands
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "InternalRoutines.h"
      9 #include "RSA_Decrypt_fp.h"
     10 #ifdef TPM_ALG_RSA
     11 //
     12 //
     13 //     Error Returns                     Meaning
     14 //
     15 //     TPM_RC_ATTRIBUTES                 If the key is restricted or the key is not a decryption key
     16 //     TPM_RC_BINDING                    The public an private parts of the key are not properly bound
     17 //     TPM_RC_KEY                        keyHandle does not reference an unrestricted decrypt key
     18 //     TPM_RC_SCHEME                     incorrect input scheme, or the chosen scheme is not a valid RSA
     19 //                                       decrypt scheme
     20 //     TPM_RC_SIZE                       cipherText is not the size of the modulus of key referenced by
     21 //                                       keyHandle
     22 //     TPM_RC_VALUE                      label is not a null terminated string or the value of cipherText is
     23 //                                       greater that the modulus of keyHandle
     24 //
     25 TPM_RC
     26 TPM2_RSA_Decrypt(
     27    RSA_Decrypt_In        *in,                   // IN: input parameter list
     28    RSA_Decrypt_Out       *out                   // OUT: output parameter list
     29    )
     30 {
     31    TPM_RC                             result;
     32    OBJECT                            *rsaKey;
     33    TPMT_RSA_DECRYPT                  *scheme;
     34    char                              *label = NULL;
     35 
     36 // Input Validation
     37 
     38    rsaKey = ObjectGet(in->keyHandle);
     39 
     40    // The selected key must be an RSA key
     41    if(rsaKey->publicArea.type != TPM_ALG_RSA)
     42        return TPM_RC_KEY + RC_RSA_Decrypt_keyHandle;
     43 
     44    // The selected key must be an unrestricted decryption key
     45    if(   rsaKey->publicArea.objectAttributes.restricted == SET
     46       || rsaKey->publicArea.objectAttributes.decrypt == CLEAR)
     47        return TPM_RC_ATTRIBUTES + RC_RSA_Decrypt_keyHandle;
     48 
     49    //   NOTE: Proper operation of this command requires that the sensitive area
     50    //   of the key is loaded. This is assured because authorization is required
     51    //   to use the sensitive area of the key. In order to check the authorization,
     52    //   the sensitive area has to be loaded, even if authorization is with policy.
     53 
     54    // If label is present, make sure that it is a NULL-terminated string
     55    if(in->label.t.size > 0)
     56    {
     57        // Present, so make sure that it is NULL-terminated
     58        if(in->label.t.buffer[in->label.t.size - 1] != 0)
     59            return TPM_RC_VALUE + RC_RSA_Decrypt_label;
     60        label = (char *)in->label.t.buffer;
     61    }
     62 
     63 // Command Output
     64 
     65    // Select a scheme for decrypt.
     66    scheme = CryptSelectRSAScheme(in->keyHandle, &in->inScheme);
     67   if(scheme == NULL)
     68       return TPM_RC_SCHEME + RC_RSA_Decrypt_inScheme;
     69 
     70   // Decryption. TPM_RC_VALUE, TPM_RC_SIZE, and TPM_RC_KEY error may be
     71   // returned by CryptDecryptRSA.
     72   // NOTE: CryptDecryptRSA can also return TPM_RC_ATTRIBUTES or TPM_RC_BINDING
     73   // when the key is not a decryption key but that was checked above.
     74   out->message.t.size = sizeof(out->message.t.buffer);
     75   result = CryptDecryptRSA(&out->message.t.size, out->message.t.buffer, rsaKey,
     76                            scheme, in->cipherText.t.size,
     77                            in->cipherText.t.buffer,
     78                            label);
     79 
     80    return result;
     81 }
     82 #endif
     83