security: implement RSA private key ops (for PC only)

definitely not fast, but we're ok with it - it will be only used
rarely to sign things
tested:

gcc -o test main.c -O2 -DRSA_SUPPORT_PRIV_OP_LOWRAM -I.&& ./test

main.c:

//no leading zeroes please. full 32-bit multiples please
static const char *k_mod = "dee5437c422df7afd324a5df1337b0059f88e10bc92b83746d1de004e41f494516c233ed1f9996d96ee517814888e6d85e4d3cb65b091ac59afcd8d395b33cc8af98e50cb7a46c8af93edbb9d319a0d82ab0782c2145797924b3e93ba80a9a8849661f928a384268c5f2e8362ba17bf9c8219846cd0e92147fa4f799bc8b1bc201c265eef74424a8b35fcab91250a9a7fbdf81ad0e1253d183a315b184ec0f6c3f6230ecfe3cf04bed12f7dc6b94a9f0844f952c3e5da4a861de3242b8ea3ff8fbbaaf9e117c7283eb31b03a77384fec0b700e0811015b836e5ae93be527173d940f43337f77dd1382a871b710721b550d72f2a92ab3a975350a50d0542bed67";
static const char *k_priv = "a4ee646757d907c434aa938a637ffb61cdd0cd25996ff74f794677f36691b7f7c5856242fdf4fa685de46ae621341c0cd28ab877ff18d7948cc0b7f8a876fe6d49720b5ac3b08918b4a1cc98ce19d2a8e1bdbece78b81dd0845614292e88da1c2aa3c48cfc75f0bdf26b71645418a3d20a42c198f236ebe4fb26a8883bb97b894b94ed8c75102e64f2848f0f7df70aee19f46aec5b7df18342827d83245b9d3681c4dd0452f9e74329b38078e345b73fae03c0ebd56e8f5e990c2e86ebdc10f59df926cd137ec1b9941937134e9190902ea00faab8f2f8be0913dce418240bdca32f1b861f6562982a13196c5512b84ec52a5d5b8139f5e6c5018cf10d344cf1";

static bool readkey(uint32_t *to, const char *k)
{
    const char *end = k + strlen(k);
    uint32_t i, t;

    if (end - k != RSA_BYTES * 2)
        return false;

    while (end != k) {
        t = 0;
        end -= 8;
        for (i = 0; i < 8; i++) {
            char ch = end[i];
            t <<= 4;
            if (ch >= '0' && ch <= '9')
                t += ch - '0';
            else if (ch >= 'a' && ch <= 'f')
                t += ch + 10 - 'a';
            else if (ch >= 'A' && ch <= 'F')
                t += ch + 10 - 'A';
            else
                return false;
        }
        *to++ = t;
    }
    return true;
}

static void printnum(const char *nm, uint32_t *num, uint32_t len)
{
    int32_t i;

    printf("%s = 0x", nm);
    for (i = RSA_LIMBS - 1; i >= 0; i--)
         printf("_%08lx", (unsigned long)(i < len ? num[i] : 0));
    printf("\n");
}

int main(int argc, char** argv)
{
    struct RsaState s;

    //real test
    {
        uint32_t priv[RSA_LIMBS], mod[RSA_LIMBS], msg[RSA_LIMBS] = {0}, encr[RSA_LIMBS], decr[RSA_LIMBS];
        memcpy(msg, &main, RSA_BYTES - 1); //code fo this func is as good a test as any last byte zeroes to make sure we're smaller than modulus

        if (!readkey(priv, k_priv))
            return -1;
        if (!readkey(mod, k_mod))
            return -1;

        printnum("priv", priv, RSA_LIMBS);
        printnum("mod ", mod, RSA_LIMBS);
        printnum("msg ", msg, RSA_LIMBS);
        memcpy(encr, rsaPubOp(&s, msg, mod), RSA_BYTES);
        memcpy(decr, rsaPrivOp(&s, encr, priv, mod), RSA_BYTES);
        printnum("encr", encr, RSA_LIMBS);
        printnum("decr", decr, RSA_LIMBS);
    }

    return 0;
}

Change-Id: I473a80253f1d6b8047ff1c25c632820f425cfc8f
2 files changed
tree: 5b31c1569c526922ef3e03ef3b8c2bee3e7a036e
  1. firmware/
  2. util/
  3. .gitignore
  4. Android.mk