Beispiel #1
0
int digsig_init_pkey(const char read_par, unsigned char *raw_public_key, int mpi_size)
{
	int nread;

	switch (read_par) {

	case 'n':
		DSM_PRINT(DEBUG_SIGN, "Reading raw_public_key_n!\n");
		nread = mpi_size;
		digsig_public_key[0] =
			mpi_read_from_buffer(raw_public_key, &nread, 0);
		break;
	case 'e':
		DSM_PRINT(DEBUG_SIGN, "Reading raw_public_key_e!\n");
		nread = mpi_size;
		digsig_public_key[1] =
			mpi_read_from_buffer(raw_public_key, &nread, 0);
		break;
	}

	return 0;
}
Beispiel #2
0
int rsa_verify_sig(char *sig, int sig_size, u8 *sha1)
{
	MPI public_key[2];
	MPI hash;
	MPI data;
	int nread;
	int nframe;

	if (!rsa_key) {
		return -EINVAL;
	}

	/* initialize our keys */
	nread = rsa_key->n_size;
	public_key[0] = mpi_read_from_buffer((byte *)rsa_key->n, &nread, 0);
	if (!public_key[0]) {
		return -EINVAL;
	}

	nread = rsa_key->e_size;
	public_key[1] = mpi_read_from_buffer((byte *)rsa_key->e, &nread, 0);
	if (!public_key[1]) {
		return -EINVAL;
	}

	/* set up the MPI for the sig */
	data = mpi_read_from_buffer(sig, &sig_size, 0);
	if (!data) {
		return -EINVAL;
	}

	/* set up the MPI for the result */
	nframe = mpi_get_nbits(public_key[0]);
	hash = do_encode_md(sha1, nframe);

	/* verify the sig */
	return rsa_verify(hash, &data, public_key);
}
Beispiel #3
0
void digsig_init_pkey_internal(void)
{
	int buf_size;

	printk(KERN_DEBUG "digsig.keys_valid 0x%08x\n\n", digsig_keys.valid);
	dump_key("n_key", digsig_keys.n_key, 130);
	dump_key("e_key", digsig_keys.e_key, 5);

	if (digsig_keys.valid != 1) {
		printk(KERN_NOTICE "DIGSIG: no valid key, digsig security disabled\n");
		return;
	}

	DSM_PRINT(DEBUG_SIGN, "Reading raw_public_key_n!\n");
	/* 
	 * key size in bits encoded in first two bytes, big endian.
         * round key size up and convert to bytes.
	 * add two bytes for the size field
	 */
	buf_size = digsig_keys.n_key[0] << 8 | digsig_keys.n_key[1];
	buf_size = (buf_size + 7)/8;
	buf_size += 2;	
	printk(KERN_INFO "%s: n_key size %d\n", __FUNCTION__, buf_size);
	digsig_public_key[0] =
		mpi_read_from_buffer(digsig_keys.n_key, &buf_size, 0);

	DSM_PRINT(DEBUG_SIGN, "Reading raw_public_key_e!\n");
	buf_size = digsig_keys.e_key[0] << 8 | digsig_keys.e_key[1];
	buf_size = (buf_size + 7)/8;
	buf_size += 2;	
	printk(KERN_INFO "%s: e_key size %d\n", __FUNCTION__, buf_size);
	digsig_public_key[1] =
		mpi_read_from_buffer(digsig_keys.e_key, &buf_size, 0);

	g_init = 1;
	printk(KERN_NOTICE "DIGSIG: digsig security enabled\n");
}
Beispiel #4
0
int digsig_rsa_bsign_verify(unsigned char *hash_format, int length,
			 unsigned char *signed_hash)
{
	int rc = 0, cmp;
	MPI hash, data;
	unsigned nread = DIGSIG_ELF_SIG_SIZE;
	int nframe;
	unsigned char sig_class;
	unsigned char sig_timestamp[SIZEOF_UNSIGNED_INT];
	int i;
	SIGCTX *ctx = NULL;
	unsigned char *new_sig;

	new_sig = kmalloc(gDigestLength[HASH_SHA1], DIGSIG_SAFE_ALLOC);
	if (!new_sig) {
		DSM_ERROR ("kmalloc failed in %s for new_sig\n", __FUNCTION__);
		return -ENOMEM;
	}

	/* Get MPI of signed data from .sig file/section */
	nread = DIGSIG_ELF_SIG_SIZE;

	data = mpi_read_from_buffer(signed_hash + DIGSIG_RSA_DATA_OFFSET, 
				    &nread, 0);
	if (!data) {
		kfree(new_sig);
		return -EINVAL;
	}

	/* Get MPI for hash */
	/* bsign modif - file hash - gpg modif */
	/* bsign modif: add bsign greet at beginning */
	/* gpg modif:   add class and timestamp at end */

	ctx = kmalloc(sizeof(SIGCTX), GFP_KERNEL);
	if (!ctx) {
		DSM_ERROR("Cannot allocate ctx\n");
		mpi_free (data);
		kfree (new_sig);
		return -ENOMEM;
	}

	ctx->tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
	if (!ctx->tvmem) {
		kfree (ctx);
		mpi_free(data);
		kfree (new_sig);
		DSM_ERROR("Cannot allocate plaintext buffer\n");
		return -ENOMEM;
	}

	digsig_sha1_init(ctx);

	sig_class = signed_hash[DIGSIG_RSA_CLASS_OFFSET];
	sig_class &= 0xff;

	for (i = 0; i < SIZEOF_UNSIGNED_INT; i++) {
		sig_timestamp[i] =
		    signed_hash[DIGSIG_RSA_TIMESTAMP_OFFSET + i] & 0xff;
	}

	digsig_sha1_update(ctx, DIGSIG_BSIGN_STRING, DIGSIG_BSIGN_GREET_SIZE);
	digsig_sha1_update(ctx, hash_format, SHA1_DIGEST_LENGTH);
	digsig_sha1_update(ctx, &sig_class, 1);
	digsig_sha1_update(ctx, sig_timestamp, SIZEOF_UNSIGNED_INT);

	if ((rc = digsig_sha1_final(ctx, new_sig)) < 0) {
		DSM_ERROR
		    ("internal_rsa_verify_final Cannot finalize hash algorithm\n");
		mpi_free(data);
		kfree(ctx->tvmem);
		kfree(ctx);
		return rc;
	}

	nframe = mpi_get_nbits(digsig_public_key[0]);
	hash = do_encode_md(new_sig, nframe);

	if (hash == MPI_NULL) {
		DSM_PRINT(DEBUG_SIGN, "mpi creation failed\\n");
	}

	/* Do RSA verification */
	cmp = rsa_verify(hash, &data, digsig_public_key);
	rc = cmp ? -EPERM : 0;

	mpi_free(hash);
	mpi_free(data);
	kfree(ctx->tvmem);
	kfree(ctx);
	kfree (new_sig);
	return rc;
}
Beispiel #5
0
/* Convert the external representation of an integer stored in BUFFER
   with a length of BUFLEN into a newly create MPI returned in
   RET_MPI.  If NBYTES is not NULL, it will receive the number of
   bytes actually scanned after a successful operation.  */
gcry_error_t
gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
               const void *buffer_arg, size_t buflen, size_t *nscanned)
{
  const unsigned char *buffer = (const unsigned char*)buffer_arg;
  struct gcry_mpi *a = NULL;
  unsigned int len;
  int secure = (buffer && gcry_is_secure (buffer));

  if (format == GCRYMPI_FMT_SSH)
    len = 0;
  else
    len = buflen;

  if (format == GCRYMPI_FMT_STD)
    {
      const unsigned char *s = buffer;

      a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
      if (len)
        {
          a->sign = !!(*s & 0x80);
          if (a->sign)
            {
              /* FIXME: we have to convert from 2compl to magnitude format */
              mpi_free (a);
              return gcry_error (GPG_ERR_INTERNAL);
	    }
          else
            _gcry_mpi_set_buffer (a, s, len, 0);
	}
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_USG)
    {
      a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);

      if (len)
        _gcry_mpi_set_buffer (a, buffer, len, 0);
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_PGP)
    {
      a = mpi_read_from_buffer (buffer, &len, secure);
      if (nscanned)
        *nscanned = len;
      if (ret_mpi && a)
        {
          mpi_normalize (a);
          *ret_mpi = a;
	}
      else if (a)
        {
          mpi_free(a);
          a = NULL;
        }
      return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
    }
  else if (format == GCRYMPI_FMT_SSH)
    {
      const unsigned char *s = buffer;
      size_t n;

      /* This test is not strictly necessary and an assert (!len)
         would be sufficient.  We keep this test in case we later
         allow the BUFLEN argument to act as a sanitiy check.  Same
         below. */
      if (len && len < 4)
        return gcry_error (GPG_ERR_TOO_SHORT);

      n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
      s += 4;
      if (len)
        len -= 4;
      if (len && n > len)
        return gcry_error (GPG_ERR_TOO_LARGE);

      a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
                                    /BYTES_PER_MPI_LIMB)
                : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
      if (n)
        {
          a->sign = !!(*s & 0x80);
          if (a->sign)
            {
              /* FIXME: we have to convert from 2compl to magnitude format */
              mpi_free(a);
              return gcry_error (GPG_ERR_INTERNAL);
	    }
          else
            _gcry_mpi_set_buffer( a, s, n, 0 );
	}
      if (nscanned)
        *nscanned = n+4;
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
        }
      else
        mpi_free(a);
      return 0;
    }
  else if (format == GCRYMPI_FMT_HEX)
    {
      /* We can only handle C strings for now.  */
      if (buflen)
        return gcry_error (GPG_ERR_INV_ARG);

      a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
      if (mpi_fromstr (a, (const char *)buffer))
        {
          mpi_free (a);
          return gcry_error (GPG_ERR_INV_OBJ);
        }
      if (ret_mpi)
        {
          mpi_normalize ( a );
          *ret_mpi = a;
	}
      else
        mpi_free(a);
      return 0;
    }
  else
    return gcry_error (GPG_ERR_INV_ARG);
}