From 9449b168e067934c54cd846f61791cc8e52cea22 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Sat, 27 Apr 2013 00:05:57 -0700 Subject: [PATCH] keystore: don't use binder input buffers for rsa sign/verify directly 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 --- libkeymaster/keymaster_mobicore.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libkeymaster/keymaster_mobicore.cpp b/libkeymaster/keymaster_mobicore.cpp index 1cfcc50..f2d5d55 100644 --- a/libkeymaster/keymaster_mobicore.cpp +++ b/libkeymaster/keymaster_mobicore.cpp @@ -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; -- 2.20.1