keystore: don't use binder input buffers for rsa sign/verify directly
authorDima Zavin <dima@android.com>
Sat, 27 Apr 2013 07:05:57 +0000 (00:05 -0700)
committerDima Zavin <dima@android.com>
Sat, 27 Apr 2013 07:31:20 +0000 (00:31 -0700)
The input buffers for RSA sign/verify are passed over the binder, which
maps it into this process as read-only. When this buffer is passed
to mobicore, it tries to pin the page with __get_user_pages with
PROT_WRITE, which fails. Since the mobicore transport code doesn't
know if the APIs are producers or consumers, it "rightfully" assumes
all buffers are read/write. The interface to trustzone currently
doesn't support specifying read/write access bits, so instead
we create a copy of the input data in a locally allocated
malloc buffer and use that instead.

Bug: 8019596
Change-Id: I3c77c893f674ec73196a8a2ea3e5a24fb9e3b860
Signed-off-by: Dima Zavin <dima@android.com>
libkeymaster/keymaster_mobicore.cpp

index 1cfcc508b26e0a0765da3a638e4793affcd09b9f..f2d5d554f8f66c6b7cffb0c729f5d4c5b827191d 100644 (file)
@@ -360,8 +360,12 @@ static int exynos_km_sign_data(const keymaster_device_t* dev,
 
     *signedDataLength = RSA_KEY_MAX_SIZE;
 
-    ret = TEE_RSASign(keyBlob, keyBlobLength, data, dataLength, signedDataPtr.get(),
+    /* binder gives us read-only mappings we can't use with mobicore */
+    void *tmpData = malloc(dataLength);
+    memcpy(tmpData, data, dataLength);
+    ret = TEE_RSASign(keyBlob, keyBlobLength, (const uint8_t *)tmpData, dataLength, signedDataPtr.get(),
                        signedDataLength, TEE_RSA_NODIGEST_NOPADDING);
+    free(tmpData);
     if (ret != TEE_ERR_NONE) {
         ALOGE("TEE_RSASign() is failed: %d", ret);
         return -1;
@@ -397,8 +401,14 @@ static int exynos_km_verify_data(const keymaster_device_t* dev,
         return -1;
     }
 
-    ret = TEE_RSAVerify(keyBlob, keyBlobLength, signedData, signedDataLength, signature,
+    void *tmpSignedData = malloc(signedDataLength);
+    memcpy(tmpSignedData, signedData, signedDataLength);
+    void *tmpSig = malloc(signatureLength);
+    memcpy(tmpSig, signature, signatureLength);
+    ret = TEE_RSAVerify(keyBlob, keyBlobLength, (const uint8_t*)tmpSignedData, signedDataLength, (const uint8_t *)tmpSig,
                        signatureLength, TEE_RSA_NODIGEST_NOPADDING, &result);
+    free(tmpSignedData);
+    free(tmpSig);
     if (ret != TEE_ERR_NONE) {
         ALOGE("TEE_RSAVerify() is failed: %d", ret);
         return -1;