aboutsummaryrefslogtreecommitdiffstats
path: root/stubdom/vtpmmgr/tpmrsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'stubdom/vtpmmgr/tpmrsa.c')
-rw-r--r--stubdom/vtpmmgr/tpmrsa.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/stubdom/vtpmmgr/tpmrsa.c b/stubdom/vtpmmgr/tpmrsa.c
new file mode 100644
index 0000000000..56094e735f
--- /dev/null
+++ b/stubdom/vtpmmgr/tpmrsa.c
@@ -0,0 +1,175 @@
+/*
+ * The RSA public-key cryptosystem
+ *
+ * Copyright (C) 2006-2011, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
+ *
+ * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
+ */
+
+#include "tcg.h"
+#include "polarssl/sha1.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "tpmrsa.h"
+
+#define HASH_LEN 20
+
+void tpmrsa_set_pubkey(tpmrsa_context* ctx,
+ const unsigned char* key,
+ int keylen,
+ const unsigned char* exponent,
+ int explen) {
+
+ tpmrsa_free(ctx);
+
+ if(explen == 0) { //Default e= 2^16+1
+ mpi_lset(&ctx->E, 65537);
+ } else {
+ mpi_read_binary(&ctx->E, exponent, explen);
+ }
+ mpi_read_binary(&ctx->N, key, keylen);
+
+ ctx->len = ( mpi_msb(&ctx->N) + 7) >> 3;
+}
+
+static TPM_RESULT tpmrsa_public( tpmrsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret;
+ size_t olen;
+ mpi T;
+
+ mpi_init( &T );
+
+ MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+ if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+ {
+ mpi_free( &T );
+ return TPM_ENCRYPT_ERROR;
+ }
+
+ olen = ctx->len;
+ MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+ MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+ mpi_free( &T );
+
+ if( ret != 0 )
+ return TPM_ENCRYPT_ERROR;
+
+ return TPM_SUCCESS;
+}
+
+static void mgf_mask( unsigned char *dst, int dlen, unsigned char *src, int slen)
+{
+ unsigned char mask[HASH_LEN];
+ unsigned char counter[4] = {0, 0, 0, 0};
+ int i;
+ sha1_context mctx;
+
+ //We always hash the src with the counter, so save the partial hash
+ sha1_starts(&mctx);
+ sha1_update(&mctx, src, slen);
+
+ // Generate and apply dbMask
+ while(dlen > 0) {
+ //Copy the sha1 context
+ sha1_context ctx = mctx;
+
+ //compute hash for input || counter
+ sha1_update(&ctx, counter, sizeof(counter));
+ sha1_finish(&ctx, mask);
+
+ //Apply the mask
+ for(i = 0; i < (dlen < HASH_LEN ? dlen : HASH_LEN); ++i) {
+ *(dst++) ^= mask[i];
+ }
+
+ //Increment counter
+ ++counter[3];
+
+ dlen -= HASH_LEN;
+ }
+}
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret;
+ int olen;
+ unsigned char* seed = output + 1;
+ unsigned char* db = output + HASH_LEN +1;
+
+ olen = ctx->len-1;
+
+ if( f_rng == NULL )
+ return TPM_ENCRYPT_ERROR;
+
+ if( ilen > olen - 2 * HASH_LEN - 1)
+ return TPM_ENCRYPT_ERROR;
+
+ output[0] = 0;
+
+ //Encoding parameter p
+ sha1((unsigned char*)"TCPA", 4, db);
+
+ //PS
+ memset(db + HASH_LEN, 0,
+ olen - ilen - 2 * HASH_LEN - 1);
+
+ //constant 1 byte
+ db[olen - ilen - HASH_LEN -1] = 0x01;
+
+ //input string
+ memcpy(db + olen - ilen - HASH_LEN,
+ input, ilen);
+
+ //Generate random seed
+ if( ( ret = f_rng( p_rng, seed, HASH_LEN ) ) != 0 )
+ return TPM_ENCRYPT_ERROR;
+
+ // maskedDB: Apply dbMask to DB
+ mgf_mask( db, olen - HASH_LEN, seed, HASH_LEN);
+
+ // maskedSeed: Apply seedMask to seed
+ mgf_mask( seed, HASH_LEN, db, olen - HASH_LEN);
+
+ // Do the crypto op
+ return tpmrsa_public(ctx, output, output);
+}