Ejemplo n.º 1
0
/* out must have enough space for sch->len bytes */
int schema_run(const struct schema *sch, uint8_t *out) {
  int status;
  struct rand_source src;

  if(rand_source_init(&src, sch->key, schema_keylen(sch),
                      schema_update, sch->cb_ms_ivl,
                      (void *) sch) != 0)
    return -1;

#define SCHEMA_RUN_CASE(schema_id, name) \
  case schema_id: \
    status = schema_##name##_run(sch, &src, out); \
    break

  switch(sch->id) {
  SCHEMA_RUN_CASE(SCHEMA_ID_HEX, hex);
  SCHEMA_RUN_CASE(SCHEMA_ID_PW0, pw0);
  default:
    status = -1;
  }

  rand_source_free(&src);
  return status;
}
Ejemplo n.º 2
0
err_status_t
crypto_kernel_init() {
  err_status_t status;  

  /* check the security state */
  if (crypto_kernel.state == crypto_kernel_state_secure) {
    
    /*
     * we're already in the secure state, but we've been asked to
     * re-initialize, so we just re-run the self-tests and then return
     */
    return crypto_kernel_status(); 
  }

  /* initialize error reporting system */
  status = err_reporting_init("crypto");
  if (status)
    return status;

  /* load debug modules */
  status = crypto_kernel_load_debug_module(&mod_crypto_kernel);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_auth);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_cipher);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_stat);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_alloc);
  if (status)
    return status;
  
  /* initialize random number generator */
  status = rand_source_init();
  if (status)
    return status;

  /* run FIPS-140 statistical tests on rand_source */  
  status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
  if (status)
    return status;

  /* initialize pseudorandom number generator */
  status = ctr_prng_init(rand_source_get_octet_string);
  if (status)
    return status;

  /* run FIPS-140 statistical tests on ctr_prng */  
  status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS);
  if (status)
    return status;
 
  /* load cipher types */
  status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
  if (status) 
    return status;
  status = crypto_kernel_load_cipher_type(&aes_icm, AES_128_ICM);
  if (status) 
    return status;
  status = crypto_kernel_load_cipher_type(&aes_cbc_cipher, AES_128_CBC);
  if (status) 
    return status;

  /* load auth func types */
  status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
  if (status)
    return status;
  status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);
  if (status)
    return status;

  /* change state to secure */
  crypto_kernel.state = crypto_kernel_state_secure;

  return err_status_ok;
}
Ejemplo n.º 3
0
err_status_t
crypto_kernel_init() {
  err_status_t status;  

  /* initialize error reporting system */
  status = err_reporting_init("crypto");
  if (status)
    return status;

  /* load debug modules */
  status = crypto_kernel_load_debug_module(&mod_crypto_kernel);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_auth);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_cipher);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_stat);
  if (status)
    return status;
  status = crypto_kernel_load_debug_module(&mod_alloc);
  if (status)
    return status;
  
  /* initialize random number generator */
  status = rand_source_init();
  if (status)
    return status;

  /* run FIPS-140 statistical tests on rand_source */  
  status = stat_test_rand_source(rand_source_get_octet_string);
  if (status)
    return status;

  /* initialize pseudorandom number generator */
  status = ctr_prng_init(rand_source_get_octet_string);
  if (status)
    return status;

  /* run FIPS-140 statistical tests on ctr_prng */  
  status = stat_test_rand_source(ctr_prng_get_octet_string);
  if (status)
    return status;
 
  /* load cipher types */
  status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
  if (status) 
    return status;
  status = crypto_kernel_load_cipher_type(&aes_icm, AES_128_ICM);
  if (status) 
    return status;
  status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_CBC);
  if (status) 
    return status;

  /* load auth func types */
  status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
  if (status)
    return status;
  status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);
  if (status)
    return status;

  /* change state to secure */
  crypto_kernel.state = crypto_kernel_state_secure;

  return err_status_ok;
}
Ejemplo n.º 4
0
err_status_t
cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
  const cipher_test_case_t *test_case = test_data;
  cipher_t *c;
  err_status_t status;
  uint8_t buffer[SELF_TEST_BUF_OCTETS];
  uint8_t buffer2[SELF_TEST_BUF_OCTETS];
  unsigned int len;
  int i, j, case_num = 0;

  debug_print(mod_cipher, "running self-test for cipher %s", 
	      ct->description);
  
  /*
   * check to make sure that we have at least one test case, and
   * return an error if we don't - we need to be paranoid here
   */
  if (test_case == NULL)
    return err_status_cant_check;

  /*
   * loop over all test cases, perform known-answer tests of both the
   * encryption and decryption functions
   */  
  while (test_case != NULL) {

    /* allocate cipher */
    status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
    if (status)
      return status;
    
    /*
     * test the encrypt function 
     */
    debug_print(mod_cipher, "testing encryption", NULL);    
    
    /* initialize cipher */
    status = cipher_init(c, test_case->key, direction_encrypt);
    if (status) {
      cipher_dealloc(c);
      return status;
    }
    
    /* copy plaintext into test buffer */
    if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
      cipher_dealloc(c);    
      return err_status_bad_param;
    }
    for (i=0; i < test_case->plaintext_length_octets; i++)
      buffer[i] = test_case->plaintext[i];

    debug_print(mod_cipher, "plaintext:    %s",
	     octet_string_hex_string(buffer,
				     test_case->plaintext_length_octets));

    /* set the initialization vector */
    status = cipher_set_iv(c, test_case->idx);
    if (status) {
      cipher_dealloc(c);
      return status;
    } 
    
    /* encrypt */
    len = test_case->plaintext_length_octets;
    status = cipher_encrypt(c, buffer, &len);
    if (status) {
      cipher_dealloc(c);
      return status;
    }
    
    debug_print(mod_cipher, "ciphertext:   %s",
	     octet_string_hex_string(buffer,
				     test_case->ciphertext_length_octets));

    /* compare the resulting ciphertext with that in the test case */
    if (len != (unsigned int)test_case->ciphertext_length_octets)
      return err_status_algo_fail;
    status = err_status_ok;
    for (i=0; i < test_case->ciphertext_length_octets; i++)
      if (buffer[i] != test_case->ciphertext[i]) {
	status = err_status_algo_fail;
	debug_print(mod_cipher, "test case %d failed", case_num);
	debug_print(mod_cipher, "(failure at byte %d)", i);
	break;
      }
    if (status) {

      debug_print(mod_cipher, "c computed: %s",
	     octet_string_hex_string(buffer,
		  2*test_case->plaintext_length_octets));
      debug_print(mod_cipher, "c expected: %s",
		  octet_string_hex_string(test_case->ciphertext,
			  2*test_case->plaintext_length_octets));

      cipher_dealloc(c);
      return err_status_algo_fail;
    }

    /*
     * test the decrypt function
     */
    debug_print(mod_cipher, "testing decryption", NULL);    

    /* re-initialize cipher for decryption */
    status = cipher_init(c, test_case->key, direction_decrypt);
    if (status) {
      cipher_dealloc(c);
      return status;
    }

    /* copy ciphertext into test buffer */
    if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
      cipher_dealloc(c);    
      return err_status_bad_param;
    }
    for (i=0; i < test_case->ciphertext_length_octets; i++)
      buffer[i] = test_case->ciphertext[i];

    debug_print(mod_cipher, "ciphertext:    %s",
		octet_string_hex_string(buffer,
					test_case->plaintext_length_octets));

    /* set the initialization vector */
    status = cipher_set_iv(c, test_case->idx);
    if (status) {
      cipher_dealloc(c);
      return status;
    } 
    
    /* decrypt */
    len = test_case->ciphertext_length_octets;
    status = cipher_decrypt(c, buffer, &len);
    if (status) {
      cipher_dealloc(c);
      return status;
    }
    
    debug_print(mod_cipher, "plaintext:   %s",
	     octet_string_hex_string(buffer,
				     test_case->plaintext_length_octets));

    /* compare the resulting plaintext with that in the test case */
    if (len != (unsigned int)test_case->plaintext_length_octets)
      return err_status_algo_fail;
    status = err_status_ok;
    for (i=0; i < test_case->plaintext_length_octets; i++)
      if (buffer[i] != test_case->plaintext[i]) {
	status = err_status_algo_fail;
	debug_print(mod_cipher, "test case %d failed", case_num);
	debug_print(mod_cipher, "(failure at byte %d)", i);
      }
    if (status) {

      debug_print(mod_cipher, "p computed: %s",
	     octet_string_hex_string(buffer,
		  2*test_case->plaintext_length_octets));
      debug_print(mod_cipher, "p expected: %s",
		  octet_string_hex_string(test_case->plaintext,
			  2*test_case->plaintext_length_octets));

      cipher_dealloc(c);
      return err_status_algo_fail;
    }

    /* deallocate the cipher */
    status = cipher_dealloc(c);
    if (status)
      return status;
    
    /* 
     * the cipher passed the test case, so move on to the next test
     * case in the list; if NULL, we'l proceed to the next test
     */   
    test_case = test_case->next_test_case;
    ++case_num;
  }
  
  /* now run some random invertibility tests */

  /* allocate cipher, using paramaters from the first test case */
  test_case = test_data;
  status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
  if (status)
      return status;
  
  rand_source_init();
  
  for (j=0; j < NUM_RAND_TESTS; j++) {
    unsigned length;
    int plaintext_len;
    uint8_t key[MAX_KEY_LEN];
    uint8_t  iv[MAX_KEY_LEN];

    /* choose a length at random (leaving room for IV and padding) */
    length = rand() % (SELF_TEST_BUF_OCTETS - 64);
    debug_print(mod_cipher, "random plaintext length %d\n", length);
    status = rand_source_get_octet_string(buffer, length);
    if (status) return status;

    debug_print(mod_cipher, "plaintext:    %s",
		octet_string_hex_string(buffer, length));

    /* copy plaintext into second buffer */
    for (i=0; (unsigned int)i < length; i++)
      buffer2[i] = buffer[i];
    
    /* choose a key at random */
    if (test_case->key_length_octets > MAX_KEY_LEN)
      return err_status_cant_check;
    status = rand_source_get_octet_string(key, test_case->key_length_octets);
    if (status) return status;

   /* chose a random initialization vector */
    status = rand_source_get_octet_string(iv, MAX_KEY_LEN);
    if (status) return status;
        
    /* initialize cipher */
    status = cipher_init(c, key, direction_encrypt);
    if (status) {
      cipher_dealloc(c);
      return status;
    }

    /* set initialization vector */
    status = cipher_set_iv(c, test_case->idx);
    if (status) {
      cipher_dealloc(c);
      return status;
    } 

    /* encrypt buffer with cipher */
    plaintext_len = length;
    status = cipher_encrypt(c, buffer, &length);
    if (status) {
      cipher_dealloc(c);
      return status;
    }
    debug_print(mod_cipher, "ciphertext:   %s",
		octet_string_hex_string(buffer, length));

    /* 
     * re-initialize cipher for decryption, re-set the iv, then
     * decrypt the ciphertext
     */
    status = cipher_init(c, key, direction_decrypt);
    if (status) {
      cipher_dealloc(c);
      return status;
    }
    status = cipher_set_iv(c, test_case->idx);
    if (status) {
      cipher_dealloc(c);
      return status;
    } 
    status = cipher_decrypt(c, buffer, &length);
    if (status) {
      cipher_dealloc(c);
      return status;
    }    

    debug_print(mod_cipher, "plaintext[2]: %s",
		octet_string_hex_string(buffer, length));    

    /* compare the resulting plaintext with the original one */
    if (length != (unsigned int)plaintext_len)
      return err_status_algo_fail;
    status = err_status_ok;
    for (i=0; i < plaintext_len; i++)
      if (buffer[i] != buffer2[i]) {
	status = err_status_algo_fail;
	debug_print(mod_cipher, "random test case %d failed", case_num);
	debug_print(mod_cipher, "(failure at byte %d)", i);
      }
    if (status) {
      cipher_dealloc(c);
      return err_status_algo_fail;
    }
        
  }

  status = cipher_dealloc(c);
  if (status)
    return status;

  return err_status_ok;
}