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_Encrypt_fp.h"
10#ifdef TPM_ALG_RSA
11//
12//
13//     Error Returns                     Meaning
14//
15//     TPM_RC_ATTRIBUTES                 decrypt attribute is not SET in key referenced by keyHandle
16//     TPM_RC_KEY                        keyHandle does not reference an RSA key
17//     TPM_RC_SCHEME                     incorrect input scheme, or the chosen scheme is not a valid RSA
18//                                       decrypt scheme
19//     TPM_RC_VALUE                      the numeric value of message is greater than the public modulus of
20//                                       the key referenced by keyHandle, or label is not a null-terminated
21//                                       string
22//
23TPM_RC
24TPM2_RSA_Encrypt(
25   RSA_Encrypt_In        *in,                 // IN: input parameter list
26   RSA_Encrypt_Out       *out                 // OUT: output parameter list
27   )
28{
29   TPM_RC                    result;
30   OBJECT                    *rsaKey;
31   TPMT_RSA_DECRYPT          *scheme;
32   char                      *label = NULL;
33
34// Input Validation
35
36   rsaKey = ObjectGet(in->keyHandle);
37
38   // selected key must be an RSA key
39   if(rsaKey->publicArea.type != TPM_ALG_RSA)
40       return TPM_RC_KEY + RC_RSA_Encrypt_keyHandle;
41
42   // selected key must have the decryption attribute
43   if(rsaKey->publicArea.objectAttributes.decrypt != SET)
44       return TPM_RC_ATTRIBUTES + RC_RSA_Encrypt_keyHandle;
45
46   // Is there a label?
47   if(in->label.t.size > 0)
48   {
49       // label is present, so make sure that is it NULL-terminated
50       if(in->label.t.buffer[in->label.t.size - 1] != 0)
51           return TPM_RC_VALUE + RC_RSA_Encrypt_label;
52       label = (char *)in->label.t.buffer;
53   }
54
55// Command Output
56
57   // Select a scheme for encryption
58   scheme = CryptSelectRSAScheme(in->keyHandle, &in->inScheme);
59   if(scheme == NULL)
60       return TPM_RC_SCHEME + RC_RSA_Encrypt_inScheme;
61
62   // Encryption. TPM_RC_VALUE, or TPM_RC_SCHEME errors my be returned buy
63   // CryptEncyptRSA. Note: It can also return TPM_RC_ATTRIBUTES if the key does
64   // not have the decrypt attribute but that was checked above.
65   out->outData.t.size = sizeof(out->outData.t.buffer);
66   result = CryptEncryptRSA(&out->outData.t.size, out->outData.t.buffer, rsaKey,
67                          scheme, in->message.t.size, in->message.t.buffer,
68                          label);
69   return result;
70}
71#endif
72