Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 "Rewrap_fp.h" |
| 10 | #include "Object_spt_fp.h" |
| 11 | // |
| 12 | // |
| 13 | // Error Returns Meaning |
| 14 | // |
| 15 | // TPM_RC_ATTRIBUTES newParent is not a decryption key |
| 16 | // TPM_RC_HANDLE oldParent does not consistent with inSymSeed |
| 17 | // TPM_RC_INTEGRITY the integrity check of inDuplicate failed |
| 18 | // TPM_RC_KEY for an ECC key, the public key is not on the curve of the curve ID |
| 19 | // TPM_RC_KEY_SIZE the decrypted input symmetric key size does not matches the |
| 20 | // symmetric algorithm key size of oldParent |
| 21 | // TPM_RC_TYPE oldParent is not a storage key, or 'newParent is not a storage key |
| 22 | // TPM_RC_VALUE for an 'oldParent; RSA key, the data to be decrypted is greater than |
| 23 | // the public exponent |
| 24 | // Unmarshal errors errors during unmarshaling the input encrypted buffer to a ECC public |
| 25 | // key, or unmarshal the private buffer to sensitive |
| 26 | // |
| 27 | TPM_RC |
| 28 | TPM2_Rewrap( |
| 29 | Rewrap_In *in, // IN: input parameter list |
| 30 | Rewrap_Out *out // OUT: output parameter list |
| 31 | ) |
| 32 | { |
| 33 | TPM_RC result = TPM_RC_SUCCESS; |
| 34 | OBJECT *oldParent; |
| 35 | TPM2B_DATA data; // symmetric key |
| 36 | UINT16 hashSize = 0; |
| 37 | TPM2B_PRIVATE privateBlob; // A temporary private blob |
| 38 | // to transit between old |
| 39 | // and new wrappers |
| 40 | |
| 41 | // Input Validation |
| 42 | |
| 43 | if((in->inSymSeed.t.size == 0 && in->oldParent != TPM_RH_NULL) |
| 44 | || (in->inSymSeed.t.size != 0 && in->oldParent == TPM_RH_NULL)) |
| 45 | return TPM_RC_HANDLE + RC_Rewrap_oldParent; |
| 46 | |
| 47 | if(in->oldParent != TPM_RH_NULL) |
| 48 | { |
| 49 | // Get old parent pointer |
| 50 | oldParent = ObjectGet(in->oldParent); |
| 51 | |
| 52 | // old parent key must be a storage object |
| 53 | if(!ObjectIsStorage(in->oldParent)) |
| 54 | return TPM_RC_TYPE + RC_Rewrap_oldParent; |
| 55 | |
| 56 | // Decrypt input secret data via asymmetric decryption. A |
| 57 | // TPM_RC_VALUE, TPM_RC_KEY or unmarshal errors may be returned at this |
| 58 | // point |
| 59 | result = CryptSecretDecrypt(in->oldParent, NULL, |
| 60 | "DUPLICATE", &in->inSymSeed, &data); |
| 61 | if(result != TPM_RC_SUCCESS) |
| 62 | return TPM_RC_VALUE + RC_Rewrap_inSymSeed; |
| 63 | |
| 64 | // Unwrap Outer |
| 65 | result = UnwrapOuter(in->oldParent, &in->name, |
| 66 | oldParent->publicArea.nameAlg, (TPM2B_SEED *) &data, |
| 67 | FALSE, |
| 68 | in->inDuplicate.t.size, in->inDuplicate.t.buffer); |
| 69 | if(result != TPM_RC_SUCCESS) |
| 70 | return RcSafeAddToResult(result, RC_Rewrap_inDuplicate); |
| 71 | |
| 72 | // Copy unwrapped data to temporary variable, remove the integrity field |
| 73 | hashSize = sizeof(UINT16) + |
| 74 | CryptGetHashDigestSize(oldParent->publicArea.nameAlg); |
| 75 | privateBlob.t.size = in->inDuplicate.t.size - hashSize; |
| 76 | MemoryCopy(privateBlob.t.buffer, in->inDuplicate.t.buffer + hashSize, |
| 77 | privateBlob.t.size, sizeof(privateBlob.t.buffer)); |
| 78 | } |
| 79 | else |
| 80 | { |
| 81 | // No outer wrap from input blob. Direct copy. |
| 82 | privateBlob = in->inDuplicate; |
| 83 | } |
| 84 | |
| 85 | if(in->newParent != TPM_RH_NULL) |
| 86 | { |
| 87 | OBJECT *newParent; |
| 88 | newParent = ObjectGet(in->newParent); |
| 89 | |
| 90 | // New parent must be a storage object |
| 91 | if(!ObjectIsStorage(in->newParent)) |
| 92 | return TPM_RC_TYPE + RC_Rewrap_newParent; |
| 93 | |
| 94 | // Make new encrypt key and its associated secret structure. A |
| 95 | // TPM_RC_VALUE error may be returned at this point if RSA algorithm is |
| 96 | // enabled in TPM |
Vadim Bendebury | b209ce1 | 2015-06-01 17:47:52 -0700 | [diff] [blame] | 97 | out->outSymSeed.t.size = sizeof(out->outSymSeed.t.buffer); |
Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 98 | result = CryptSecretEncrypt(in->newParent, |
| 99 | "DUPLICATE", &data, &out->outSymSeed); |
| 100 | if(result != TPM_RC_SUCCESS) return result; |
| 101 | |
| 102 | // Command output |
| 103 | // Copy temporary variable to output, reserve the space for integrity |
| 104 | hashSize = sizeof(UINT16) + |
| 105 | CryptGetHashDigestSize(newParent->publicArea.nameAlg); |
| 106 | out->outDuplicate.t.size = privateBlob.t.size; |
| 107 | MemoryCopy(out->outDuplicate.t.buffer + hashSize, privateBlob.t.buffer, |
| 108 | privateBlob.t.size, sizeof(out->outDuplicate.t.buffer)); |
| 109 | |
| 110 | // Produce outer wrapper for output |
| 111 | out->outDuplicate.t.size = ProduceOuterWrap(in->newParent, &in->name, |
| 112 | newParent->publicArea.nameAlg, |
| 113 | (TPM2B_SEED *) &data, |
| 114 | FALSE, |
| 115 | out->outDuplicate.t.size, |
| 116 | out->outDuplicate.t.buffer); |
| 117 | |
| 118 | } |
| 119 | else // New parent is a null key so there is no seed |
| 120 | { |
| 121 | out->outSymSeed.t.size = 0; |
| 122 | |
| 123 | // Copy privateBlob directly |
| 124 | out->outDuplicate = privateBlob; |
| 125 | } |
| 126 | |
| 127 | return TPM_RC_SUCCESS; |
| 128 | } |