Logo Search packages:      
Sourcecode: blender version File versions  Download package

v_encryption.c

/*
 * Verse encryption routines. Implements RSA encryption/decryption plus fast XORx.
*/

#if !defined(V_GENERATE_FUNC_MODE)

#include <ctype.h>
#include <stdio.h>
#include <string.h>

#include "verse.h"
#include "v_pack.h"
#include "v_bignum.h"
#include "v_encryption.h"

#define     BITS  V_ENCRYPTION_LOGIN_KEY_BITS   /* Save some typing. */

extern void v_prime_set_random(VBigDig *x);
extern void v_prime_set_table(VBigDig *x, int i);

const uint8 * v_e_data_create_key(void) /* possibly the worst key gen ever */
{
      static unsigned int counter = 0;
      static uint8      buffer[V_ENCRYPTION_DATA_KEY_SIZE];
      unsigned int      i, temp;

      for(i = 0; i < V_ENCRYPTION_DATA_KEY_SIZE; i++) 
      {
            counter++;
            temp = (counter << 13) ^ counter;
            temp = (temp * (temp * temp * 15731 + 789221) + 1376312589) & 0x7fffffff;
            buffer[i] = temp;
      }
      /* FIXME: This really isn't very pretty. */
      buffer[0] &= 0x3f;      /* Make sure top word is... Low. For RSA compatibility. */

/*    memset(buffer, 0, sizeof buffer);
      fprintf(stderr, "**WARNING: XOR data encryption disabled\n");
*/
      return buffer;
}

void v_e_data_encrypt_command(uint8 *packet, size_t packet_size, const uint8 *command, size_t command_size, const uint8 *key)
{
      uint32      pos, i;

      vnp_raw_unpack_uint32(packet, &pos);
/*    printf("encrypting packet %u", pos);*/
      pos = key[pos % V_ENCRYPTION_DATA_KEY_SIZE] + packet_size;
/*    printf(" -> pos=%u (size %u)", pos, packet_size);
      printf(", key begins: [");
      for(i = 0; i < 16; i++)
            printf(" %02X", key[(pos + i) % V_ENCRYPTION_DATA_KEY_SIZE]);
      printf(" ]\n");
*/
      for(i = 0; i < command_size; i++)
            packet[packet_size + i] = command[i] ^ key[(i + pos) % V_ENCRYPTION_DATA_KEY_SIZE];
}

void v_e_data_decrypt_packet(uint8 *to, const uint8 *from, size_t size, const uint8 *key)
{
      uint32      pos, i;

      vnp_raw_unpack_uint32(from, &pos);
/*    printf("decrypting packet %u", pos);*/
      pos = key[pos % V_ENCRYPTION_DATA_KEY_SIZE];
/*    printf(" -> pos=%u", pos);
      printf(", key begins: [");
      for(i = 0; i < 16; i++)
            printf(" %02X", key[(i + pos) % V_ENCRYPTION_DATA_KEY_SIZE]);
      printf(" ]\n");
*/    for(i = 0; i < 4; i++)
            to[i] = from[i];
      for(i = 4; i < size; i++)
            to[i] = from[i] ^ key[(i + pos) % V_ENCRYPTION_DATA_KEY_SIZE];
}

#endif

/* From Knuth. Computes multiplicative inverse of u, modulo v. */
void v_e_math_inv(VBigDig *inv, const VBigDig *u, const VBigDig *v)
{
      VBigDig     VBIGNUM(u1, 2*BITS), VBIGNUM(u3, 2*BITS), VBIGNUM(v1, 2*BITS), VBIGNUM(v3, 2 *BITS),
            VBIGNUM(t1, 2*BITS), VBIGNUM(t3, 2*BITS), VBIGNUM(q, 2*BITS),  VBIGNUM(w, 2*BITS);
      int   iter = 1;

      v_bignum_set_one(u1);
      v_bignum_set_bignum(u3, u);
      v_bignum_set_zero(v1);
      v_bignum_set_bignum(v3, v);

      while(!v_bignum_eq_zero(v3))
      {
            v_bignum_set_bignum(q, u3);
            v_bignum_div(q, v3, t3);
            v_bignum_set_bignum(w, q);
            v_bignum_mul(w, v1);
            v_bignum_set_bignum(t1, u1);
            v_bignum_add(t1, w);

            v_bignum_set_bignum(u1, v1);
            v_bignum_set_bignum(v1, t1);
            v_bignum_set_bignum(u3, v3);
            v_bignum_set_bignum(v3, t3);
            iter = -iter;
      }
      if(iter < 0)
      {
            v_bignum_set_bignum(inv, v);
            v_bignum_sub(inv, u1);
      }
      else
            v_bignum_set_bignum(inv, u1);
}

void v_e_connect_create_key(uint8 *private_key, uint8 *public_key, uint8 *n)
{
      VBigDig     VBIGNUM(p, BITS / 2), VBIGNUM(q, BITS / 2), VBIGNUM(qmo, BITS / 2), VBIGNUM(phi, BITS),
            VBIGNUM(pub, BITS), VBIGNUM(priv, BITS), VBIGNUM(mod, BITS);

#if !defined _WIN32
      /* FIXME: This is a security backdoor. Intent is simply to save time during testing. */
      if(getenv("VERSE_NORSA") != NULL)
      {
            printf("VERSE: Found the NORSA envvar, using constant keys\n");
            v_prime_set_table(p, 0);
            v_prime_set_table(q, 1);
            goto compute_phi;
      }
#endif
/*    printf("find prime p\n");*/
      v_prime_set_random(p);
/*    printf("find prime q\n");*/
      v_prime_set_random(q);
compute_phi:
/*    printf("done, computing key\n");*/
/*    printf("p=");
      v_bignum_print_hex_lf(p);
      printf("q=");
      v_bignum_print_hex_lf(q);
*/    v_bignum_set_bignum(phi, p);
      v_bignum_sub_digit(phi, 1);
      v_bignum_set_bignum(qmo, q);
      v_bignum_sub_digit(qmo, 1);
      v_bignum_mul(phi, qmo);
/*    printf("phi=");
      v_bignum_print_hex_lf(phi);
*/    v_bignum_set_string_hex(pub, "0x10001");
      v_e_math_inv(priv, pub, phi);
/*    printf(" pub=");
      v_bignum_print_hex_lf(pub);
      printf("priv=");
      v_bignum_print_hex_lf(priv);
*/
      v_bignum_set_bignum(mod, p);
      v_bignum_mul(mod, q);
/*    printf(" mod=");
      v_bignum_print_hex_lf(mod);
      printf("key-creation finished\n");
*/    /* Write out the keys. */
      v_bignum_raw_export(pub, public_key);
      v_bignum_raw_export(priv, private_key);
      v_bignum_raw_export(mod, n);
}

void v_e_connect_encrypt(uint8 *output, const uint8 *data, const uint8 *key, const uint8 *key_n)
{
      VBigDig     VBIGNUM(packet, BITS), VBIGNUM(expo, BITS), VBIGNUM(mod, BITS);

      v_bignum_raw_import(packet, data);
      v_bignum_raw_import(expo, key);
      v_bignum_raw_import(mod, key_n);

      /* Verify that data is less than the modulo, this is a prerequisite for encryption. */
      if(!v_bignum_gte(mod, packet))
      {
            printf("*** WARNING. Data is not less than modulo, as it should be--encryption will break!\n");
            printf(" RSA modulo: ");
            v_bignum_print_hex_lf(mod);
            printf("   RSA data: ");
            v_bignum_print_hex_lf(packet);
      }
/*    printf("RSA key: ");
      v_bignum_print_hex_lf(expo);
      printf("RSA mod: ");
      v_bignum_print_hex_lf(mod);
      printf("RSA in:  ");
      v_bignum_print_hex_lf(packet);
      printf("bits in packet: %d, ", v_bignum_bit_msb(packet) + 1);
      printf("bits in modulo: %d\n", v_bignum_bit_msb(mod) + 1);
*/    v_bignum_pow_mod(packet, expo, mod);      /* Blam. */
/*    printf("RSA out: ");
      v_bignum_print_hex_lf(packet);
*/    v_bignum_raw_export(packet, output);
}

#if defined CRYPTALONE
void v_encrypt_test(void)
{
      uint8 k_priv[BITS / 8], k_pub[BITS / 8], k_n[BITS / 8], cipher[BITS / 8], plain[BITS / 8], decode[BITS / 8], i;

      printf("testing RSA-crypto\n");
      v_e_connect_create_key(k_pub, k_priv, k_n);
/*    exit(0);*/
      printf("key pair generated, encrypting something\n");
      memset(plain, 0, sizeof plain);
      strcpy(plain, "This is some text to encrypt, to give it something to chew on.");
      printf("plain: %02X (%u)\n", plain[0], strlen(plain));
      v_e_connect_encrypt(cipher, plain, k_pub, k_n);
      printf("plain: %02X, cipher: %02X\n", plain[0], cipher[0]);
      v_e_connect_encrypt(decode, cipher, k_priv, k_n);
      printf("decoded: %02X: '", decode[0]);
      for(i = 0; decode[i] != 0; i++)
            putchar(decode[i]);
      printf("'\n");
/*    printf("\npublic key: ");
      v_bignum_print_hex_lf(k_public);
      printf("private key: ");
      v_bignum_print_hex_lf(k_private);
      v_bignum_set_string(msg, "123");
      gettimeofday(&t1, NULL);
      v_bignum_pow_mod(msg, k_private, k_n);
      gettimeofday(&t2, NULL);
      printf("encrypted: ");
      v_bignum_print_hex_lf(msg);
      printf("encrypted %u bits in %g s\n", BITS, t2.tv_sec - t1.tv_sec + 1.0E-6 * (t2.tv_usec - t1.tv_usec));

      gettimeofday(&t1, NULL);
      v_bignum_pow_mod(msg, k_public, k_n);
      gettimeofday(&t2, NULL);
      printf("decrypted: ");
      v_bignum_print_hex_lf(msg);
      printf("decrypted %u bits in %g s\n", BITS, t2.tv_sec - t1.tv_sec + 1.0E-6 * (t2.tv_usec - t1.tv_usec));
      exit(0);
*//*  v_e_encrypt(cipher, plain, &k_private, &k_n);
      printf("encrypted data: ");
      for(i = 0; i < sizeof cipher; i++)
            printf("%c", isalnum(cipher[i]) ? cipher[i] : '?');
      printf("\n\n");
      printf("decrypting\n");
      v_e_encrypt(decode, cipher, &k_public, &k_n);
      printf("decrypted data: ");
      for(i = 0; i < sizeof cipher; i++)
            printf("%c", isalnum(decode[i]) ? decode[i] : '?');
      printf("\n\n");
*/
}

int main(void)
{
      v_encrypt_test();

      return 0;
}
#endif

Generated by  Doxygen 1.6.0   Back to index