Coverage Report

Created: 2025-09-05 06:38

/src/tpm2/Sign.c
Line
Count
Source (jump to first uncovered line)
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 "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
//
23
TPM_RC
24
TPM2_Sign(
25
   Sign_In          *in,                   // IN: input parameter list
26
   Sign_Out         *out                   // OUT: output parameter list
27
   )
28
0
{
29
0
   TPM_RC                     result;
30
0
   TPMT_TK_HASHCHECK          ticket;
31
0
   OBJECT                    *signKey;
32
33
// Input Validation
34
   // Get sign key pointer
35
0
   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
0
   result = CryptSelectSignScheme(in->keyHandle, &in->inScheme);
40
0
   if(result != TPM_RC_SUCCESS)
41
0
   {
42
0
       if(result == TPM_RC_KEY)
43
0
           return TPM_RC_KEY + RC_Sign_keyHandle;
44
0
       else
45
0
           return RcSafeAddToResult(result, RC_Sign_inScheme);
46
0
   }
47
48
   // If validation is provided, or the key is restricted, check the ticket
49
0
   if(   in->validation.digest.t.size != 0
50
0
      || signKey->publicArea.objectAttributes.restricted == SET)
51
0
   {
52
       // Compute and compare ticket
53
0
       TicketComputeHashCheck(in->validation.hierarchy,
54
0
                              in->inScheme.details.any.hashAlg,
55
0
                              &in->digest, &ticket);
56
57
0
       if(!Memory2BEqual(&in->validation.digest.b, &ticket.digest.b))
58
0
           return TPM_RC_TICKET + RC_Sign_validation;
59
0
   }
60
0
   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
0
   {
66
0
       if(
67
0
#if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES
68
0
           in->inScheme.details.any.hashAlg != TPM_ALG_NULL &&
69
0
#endif
70
0
           in->digest.t.size
71
0
             != CryptGetHashDigestSize(in->inScheme.details.any.hashAlg))
72
0
             return TPM_RC_SIZE + RC_Sign_digest;
73
0
   }
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
0
   result = CryptSign(in->keyHandle, &in->inScheme, &in->digest, &out->signature);
79
80
0
   return result;
81
0
}