@@ -652,11 +652,23 @@ public void sendOutgoing(APDU apdu, KMAttestationCert cert, short certStart, sho
652652 // reclaim the unused memory in the certificate.
653653 repository .reclaimMemory ((short ) (bufferStart - certStart ));
654654 }
655+ // Reserve space of MAX_KEY_CHARS_SIZE to encode KeyCharacteristics
656+ short prevReclaimIndex = repository .getHeapReclaimIndex ();
657+ short keyCharsIndex = repository .allocReclaimableMemory (MAX_KEY_CHARS_SIZE );
658+
659+ // Encode keyblob at the end of the buffer before KEY_CHARACTERISTICS
660+ short keyBlobLen = encodeKeyBlob (keyblob );
661+ short keyBlobStart = repository .getHeapReclaimIndex ();
655662
656663 // Encode KeyCharacteristics at the end of heap just before data[CERTIFICATE]
657- encodeKeyCharacteristics (keyChars );
658- // and encode it to the end of the buffer before KEY_CHARACTERISTICS
659- encodeKeyBlob (keyblob );
664+ // in the reserved space of MAX_KEY_CHARS_SIZE
665+ short keyCharsLen = encodeKeyCharacteristics (keyCharsIndex , prevReclaimIndex , keyChars );
666+
667+ // Adjust the keyblob buffer before KeyChars and reclaim the memory
668+ short newKeyBlobStart = (short ) (keyBlobStart + (MAX_KEY_CHARS_SIZE - keyCharsLen ));
669+ Util .arrayCopyNonAtomic (buffer , keyBlobStart , buffer , newKeyBlobStart , keyBlobLen );
670+ repository .reclaimMemory ((short ) (newKeyBlobStart - keyBlobStart ));
671+
660672 // Write Array header and ErrorCode before data[KEY_BLOB]
661673 short bufferStartOffset = repository .allocReclaimableMemory ((short ) 2 );
662674 Util .setShort (buffer , bufferStartOffset , (short ) 0x8400 );
@@ -3048,11 +3060,6 @@ private void importKey(APDU apdu, short keyFmt, byte[] scratchPad) {
30483060 makeKeyCharacteristics ( scratchPad );
30493061 KMAttestationCert cert = generateAttestation (data [ATTEST_KEY_BLOB ], data [ATTEST_KEY_PARAMS ],scratchPad );
30503062 createEncryptedKeyBlob (scratchPad );
3051- // Remove custom tags from key characteristics
3052- short teeParams = KMKeyCharacteristics .cast (data [KEY_CHARACTERISTICS ]).getTeeEnforced ();
3053- if (teeParams != KMType .INVALID_VALUE ) {
3054- KMKeyParameters .cast (teeParams ).deleteCustomTags ();
3055- }
30563063 sendOutgoing (apdu , cert , data [CERTIFICATE ], data [KEY_BLOB ], data [KEY_CHARACTERISTICS ]);
30573064 }
30583065
@@ -3496,11 +3503,6 @@ private void processGenerateKey(APDU apdu) {
34963503 // construct the certificate and place the encoded data in data[CERTIFICATE]
34973504 KMAttestationCert cert = generateAttestation (data [ATTEST_KEY_BLOB ], data [ATTEST_KEY_PARAMS ], scratchPad );
34983505 createEncryptedKeyBlob (scratchPad );
3499- // Remove custom tags from key characteristics
3500- short teeParams = KMKeyCharacteristics .cast (data [KEY_CHARACTERISTICS ]).getTeeEnforced ();
3501- if (teeParams != KMType .INVALID_VALUE ) {
3502- KMKeyParameters .cast (teeParams ).deleteCustomTags ();
3503- }
35043506 sendOutgoing (apdu , cert , data [CERTIFICATE ], data [KEY_BLOB ], data [KEY_CHARACTERISTICS ]);
35053507 }
35063508
@@ -3841,34 +3843,39 @@ private static void createEncryptedKeyBlob(byte[] scratchPad) {
38413843 }
38423844
38433845 // Encodes KeyCharacteristics at the end of the heap
3844- private void encodeKeyCharacteristics (short keyChars ) {
3846+ // and return the length of encoded KeyChars.
3847+ private short encodeKeyCharacteristics (short startOffset , short prevReclaimIndex , short keyChars ) {
3848+ // Remove custom tags from key characteristics
3849+ short teeParams = KMKeyCharacteristics .cast (data [KEY_CHARACTERISTICS ]).getTeeEnforced ();
3850+ if (teeParams != KMType .INVALID_VALUE ) {
3851+ KMKeyParameters .cast (teeParams ).deleteCustomTags ();
3852+ }
38453853 byte [] buffer = repository .getHeap ();
3846- short prevReclaimIndex = repository .getHeapReclaimIndex ();
3847- short ptr = repository .allocReclaimableMemory (MAX_KEY_CHARS_SIZE );
3848- short len = encoder .encode (keyChars , buffer , ptr , prevReclaimIndex , MAX_KEY_CHARS_SIZE );
3854+ short len = encoder .encode (keyChars , buffer , startOffset , prevReclaimIndex , MAX_KEY_CHARS_SIZE );
38493855 // shift the encoded KeyCharacteristics data towards the right till the data[CERTIFICATE] offset.
3850- Util .arrayCopyNonAtomic (buffer , ptr , buffer , (short ) (ptr + (MAX_KEY_CHARS_SIZE - len )), len );
3851- // Reclaim the unused memory.
3852- repository .reclaimMemory ((short ) (MAX_KEY_CHARS_SIZE - len ));
3856+ Util .arrayCopyNonAtomic (buffer , startOffset , buffer , (short ) (startOffset + (MAX_KEY_CHARS_SIZE - len )), len );
3857+ return len ;
38533858 }
38543859
38553860 // Encodes KeyBlob at the end of the heap
3856- private void encodeKeyBlob (short keyBlobPtr ) {
3861+ // and returns the length of the encoded keyblob
3862+ private short encodeKeyBlob (short keyBlobPtr ) {
38573863 // allocate reclaimable memory.
38583864 byte [] buffer = repository .getHeap ();
38593865 short prevReclaimIndex = repository .getHeapReclaimIndex ();
38603866 short top = repository .allocReclaimableMemory (MAX_KEYBLOB_SIZE );
3861- short keyBlob = encoder .encode (keyBlobPtr , buffer , top , prevReclaimIndex , MAX_KEYBLOB_SIZE );
3867+ short keyBlobLen = encoder .encode (keyBlobPtr , buffer , top , prevReclaimIndex , MAX_KEYBLOB_SIZE );
38623868 Util .arrayCopyNonAtomic (repository .getHeap (), top , repository .getHeap (),
3863- (short ) (top + MAX_KEYBLOB_SIZE - keyBlob ), keyBlob );
3864- short newTop = (short ) (top + MAX_KEYBLOB_SIZE - keyBlob );
3865- // Encode the KeyBlob array inside a ByteString . Get the length of
3866- // the ByteString header.
3867- short encodedBytesLength = encoder .getEncodedBytesLength (keyBlob );
3869+ (short ) (top + MAX_KEYBLOB_SIZE - keyBlobLen ), keyBlobLen );
3870+ short newTop = (short ) (top + MAX_KEYBLOB_SIZE - keyBlobLen );
3871+ // Encode the KeyBlob array inside a ByteBlob . Get the length of
3872+ // the ByteBlob header.
3873+ short encodedBytesLength = encoder .getEncodedBytesLength (keyBlobLen );
38683874 newTop -= encodedBytesLength ;
3869- encoder .encodeByteBlobHeader (keyBlob , buffer , newTop , encodedBytesLength );
3875+ encoder .encodeByteBlobHeader (keyBlobLen , buffer , newTop , encodedBytesLength );
38703876 // Reclaim unused memory.
38713877 repository .reclaimMemory ((short ) (newTop - top ));
3878+ return (short ) (keyBlobLen + encodedBytesLength );
38723879 }
38733880
38743881 private short readKeyBlobVersion (short keyBlob ) {
0 commit comments