blob: 10b673b546b1369e2814079d3242f46c6a3c2d12 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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 "Sign_fp.h"
10#include "Attest_spt_fp.h"
11//
12//
13// Error Returns Meaning
14//
15// TPM_RC_BINDING The public and private portions of the key are not properly bound.
16// TPM_RC_KEY signHandle does not reference a signing key;
17// TPM_RC_SCHEME the scheme is not compatible with sign key type, or input scheme is
18// not compatible with default scheme, or the chosen scheme is not a
19// valid sign scheme
20// TPM_RC_TICKET validation is not a valid ticket
21// TPM_RC_VALUE the value to sign is larger than allowed for the type of keyHandle
22//
23TPM_RC
24TPM2_Sign(
25 Sign_In *in, // IN: input parameter list
26 Sign_Out *out // OUT: output parameter list
27 )
28{
29 TPM_RC result;
30 TPMT_TK_HASHCHECK ticket;
31 OBJECT *signKey;
32
33// Input Validation
34 // Get sign key pointer
35 signKey = ObjectGet(in->keyHandle);
36
37 // pick a scheme for sign. If the input sign scheme is not compatible with
38 // the default scheme, return an error.
39 result = CryptSelectSignScheme(in->keyHandle, &in->inScheme);
40 if(result != TPM_RC_SUCCESS)
41 {
42 if(result == TPM_RC_KEY)
43 return TPM_RC_KEY + RC_Sign_keyHandle;
44 else
45 return RcSafeAddToResult(result, RC_Sign_inScheme);
46 }
47
48 // If validation is provided, or the key is restricted, check the ticket
49 if( in->validation.digest.t.size != 0
50 || signKey->publicArea.objectAttributes.restricted == SET)
51 {
52 // Compute and compare ticket
53 TicketComputeHashCheck(in->validation.hierarchy,
54 in->inScheme.details.any.hashAlg,
55 &in->digest, &ticket);
56
57 if(!Memory2BEqual(&in->validation.digest.b, &ticket.digest.b))
58 return TPM_RC_TICKET + RC_Sign_validation;
59 }
60 else
61 // If we don't have a ticket, at least verify that the provided 'digest'
62 // is the size of the scheme hashAlg digest.
63 // NOTE: this does not guarantee that the 'digest' is actually produced using
64 // the indicated hash algorithm, but at least it might be.
65 {
Andrey Pronin569c3c52016-12-15 14:19:49 -080066 if(
67#if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES
68 in->inScheme.details.any.hashAlg != TPM_ALG_NULL &&
69#endif
70 in->digest.t.size
Vadim Bendebury56797522015-05-20 10:32:25 -070071 != CryptGetHashDigestSize(in->inScheme.details.any.hashAlg))
Vadim Bendebury065e0d72015-10-16 09:35:42 -070072 return TPM_RC_SIZE + RC_Sign_digest;
Vadim Bendebury56797522015-05-20 10:32:25 -070073 }
74
75// Command Output
76 // Sign the hash. A TPM_RC_VALUE or TPM_RC_SCHEME
77 // error may be returned at this point
78 result = CryptSign(in->keyHandle, &in->inScheme, &in->digest, &out->signature);
79
80 return result;
81}