Remove leading zero truncation in EC public key generation 45/311345/2
authorFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Fri, 17 May 2024 15:28:17 +0000 (17:28 +0200)
committerFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Mon, 20 May 2024 16:23:17 +0000 (18:23 +0200)
Change-Id: Ie8d212b3ff67db4ad7b9183efe1978a84aeca03c

ssflib/src/ssf_storage.cpp

index 9c0cabcad652f48ab1177a1ebc87077a1953f349..58c29ab8dd87d0f6e5a78eb37f6923f5533a7e3a 100644 (file)
@@ -1844,7 +1844,7 @@ TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
                        int nid = 0;
                        uint32_t curve = 0;
                        uint8_t *privKey = NULL, *pubX = NULL, *pubY = NULL;
-                       size_t privSize = 0, pubSize = 0, pubXSize = 0, pubYSize = 0;
+                       size_t privSize = 0, pubSize = 0, pubCoordSize = 0;
 
                        for (i = 0; i < paramCount; i++) {
                                if (params[i].attributeID == TEE_ATTR_ECC_CURVE) {
@@ -1941,21 +1941,35 @@ TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
                                TZ_ERROR("failed in EC_POINT_get_affine_coordinates(). line = %d,%s\n", __LINE__, __func__);
                                TEE_Panic(0);
                        }
-                       pubX = (uint8_t *) malloc(BN_num_bytes(x));
-                       pubY = (uint8_t *) malloc(BN_num_bytes(y));
-                       pubXSize = BN_bn2bin(x, pubX);
-                       pubYSize = BN_bn2bin(y, pubY);
-
-                       if (key_size < privSize || key_size < pubXSize || key_size < pubYSize) {
-                               TZ_ERROR("Too small key size. line = %d,%s. key_size=%d, privSize=%d, pubXSize=%d, pubYSize=%d\n",
-                                               __LINE__, __func__, key_size, privSize, pubXSize, pubYSize);
+
+                       // OpenSSL may truncate the leading zeros if the bignum is small enough
+                       // but we would like to have them back
+                       pubCoordSize = EC_GROUP_order_bits(ec_group) / 8;
+                       int xRawBytes = BN_num_bytes(x);
+                       int yRawBytes = BN_num_bytes(y);
+
+                       pubX = (uint8_t *) malloc(pubCoordSize * sizeof(uint8_t));
+                       pubY = (uint8_t *) malloc(pubCoordSize * sizeof(uint8_t));
+
+                       if (BN_bn2binpad(x, pubX, pubCoordSize) != xRawBytes) {
+                               TZ_ERROR("EC public key x component has incorrect size line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       if (BN_bn2binpad(y, pubY, pubCoordSize) != yRawBytes) {
+                               TZ_ERROR("EC public key y component has incorrect size line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+
+                       if (key_size < privSize || key_size < pubCoordSize) {
+                               TZ_ERROR("Too small key size. line = %d,%s. key_size=%d, privSize=%d, pubCoordSize=%d\n",
+                                               __LINE__, __func__, key_size, privSize, pubCoordSize);
                                TEE_Panic(0);
                        }
 
                        TEE_InitValueAttribute(&attrs[0], TEE_ATTR_ECC_CURVE, curve, 0);
                        TEE_InitRefAttribute(&attrs[1], TEE_ATTR_ECC_PRIVATE_VALUE, privKey, privSize);
-                       TEE_InitRefAttribute(&attrs[2], TEE_ATTR_ECC_PUBLIC_VALUE_X, pubX, pubXSize);
-                       TEE_InitRefAttribute(&attrs[3], TEE_ATTR_ECC_PUBLIC_VALUE_Y, pubY, pubYSize);
+                       TEE_InitRefAttribute(&attrs[2], TEE_ATTR_ECC_PUBLIC_VALUE_X, pubX, pubCoordSize);
+                       TEE_InitRefAttribute(&attrs[3], TEE_ATTR_ECC_PUBLIC_VALUE_Y, pubY, pubCoordSize);
                        TEE_PopulateTransientObject(object, attrs, 4);
 
                        EVP_PKEY_free(pkey);