示例#1
0
err_status_t
aes_icm_context_init(aes_icm_ctx_t *c, const octet_t *key) {
    v128_t tmp_key;

    /* set counter and initial values to 'offset' value */
    /* FIX!!! this assumes the salt is at key + 16, and thus that the */
    /* FIX!!! cipher key length is 16!  Also note this copies past the
              end of the 'key' array by 2 bytes! */
    v128_copy_octet_string(&c->counter, key + 16);
    v128_copy_octet_string(&c->offset, key + 16);

    /* force last two octets of the offset to zero (for srtp compatibility) */
    c->offset.octet[14] = c->offset.octet[15] = 0;
    c->counter.octet[14] = c->counter.octet[15] = 0;

    /* set tmp_key (for alignment) */
    v128_copy_octet_string(&tmp_key, key);

    debug_print(mod_aes_icm,
                "key:  %s", v128_hex_string(&tmp_key));
    debug_print(mod_aes_icm,
                "offset: %s", v128_hex_string(&c->offset));

    /* expand key */
    aes_expand_encryption_key(tmp_key, c->expanded_key);

    /* indicate that the keystream_buffer is empty */
    c->bytes_in_buffer = 0;

    return err_status_ok;
}
示例#2
0
inline void
aes_icm_advance(aes_icm_ctx_t *c) {

#if GENERIC_AESICM
    uint32_t temp;
#endif

    /* fill buffer with new keystream */
    v128_copy(&c->keystream_buffer, &c->counter);
    aes_encrypt(&c->keystream_buffer, c->expanded_key);
    c->bytes_in_buffer = 16;

    debug_print(mod_aes_icm, "counter:    %s",
                v128_hex_string(&c->counter));
    debug_print(mod_aes_icm, "ciphertext: %s",
                v128_hex_string(&c->keystream_buffer));

    /* clock counter forward */

#if GENERIC_AESICM
    //alex's clock counter forward
    temp = ntohl(c->counter.v32[3]);
    c->counter.v32[3] = htonl(++temp);
#else
    if (!++(c->counter.octet[15]))
        ++(c->counter.octet[14]);
#endif
}
示例#3
0
/*
 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
 * the offset
 */
err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir)
{
    const EVP_CIPHER *evp;
    v128_t *nonce = (v128_t*)iv;

    debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(nonce));

    v128_xor(&c->counter, &c->offset, nonce);

    debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter));

    switch (c->key_size) {
    case AES_256_KEYSIZE:
        evp = EVP_aes_256_ctr();
        break;
    case AES_192_KEYSIZE:
        evp = EVP_aes_192_ctr();
        break;
    case AES_128_KEYSIZE:
        evp = EVP_aes_128_ctr();
        break;
    default:
        return err_status_bad_param;
        break;
    }

    if (!EVP_EncryptInit_ex(&c->ctx, evp,
                            NULL, c->key.v8, c->counter.v8)) {
        return err_status_fail;
    } else {
        return err_status_ok;
    }
}
示例#4
0
/*
 * aes_icm_openssl_context_init(...) initializes the aes_icm_context
 * using the value in key[].
 *
 * the key is the secret key
 *
 * the salt is unpredictable (but not necessarily secret) data which
 * randomizes the starting point in the keystream
 */
err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key)
{
    /* set counter and initial values to 'offset' value */
    /* FIX!!! this assumes the salt is at key + 16, and thus that the */
    /* FIX!!! cipher key length is 16!  Also note this copies past the
              end of the 'key' array by 2 bytes! */
    v128_copy_octet_string(&c->counter, key + c->key_size);
    v128_copy_octet_string(&c->offset, key + c->key_size);

    /* force last two octets of the offset to zero (for srtp compatibility) */
    c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0;
    c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0;

    /* copy key to be used later when CiscoSSL crypto context is created */
    v128_copy_octet_string((v128_t*)&c->key, key);

    /* if the key is greater than 16 bytes, copy the second
     * half.  Note, we treat AES-192 and AES-256 the same here
     * for simplicity.  The storage location receiving the
     * key is statically allocated to handle a full 32 byte key
     * regardless of the cipher in use.
     */
    if (c->key_size == AES_256_KEYSIZE || c->key_size == AES_192_KEYSIZE) {
        debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s",
                    v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
        v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE);
    }

    debug_print(mod_aes_icm, "key:  %s", v128_hex_string((v128_t*)&c->key));
    debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));

    EVP_CIPHER_CTX_cleanup(&c->ctx);

    return err_status_ok;
}
示例#5
0
/*
 * aes_icm_advance(...) refills the keystream_buffer and
 * advances the block index of the sicm_context forward by one
 *
 * this is an internal, hopefully inlined function
 */
static void srtp_aes_icm_advance_ismacryp (srtp_aes_icm_ctx_t *c, uint8_t forIsmacryp)
{
    /* fill buffer with new keystream */
    v128_copy(&c->keystream_buffer, &c->counter);
    srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
    c->bytes_in_buffer = sizeof(v128_t);

    debug_print(srtp_mod_aes_icm, "counter:    %s",
                v128_hex_string(&c->counter));
    debug_print(srtp_mod_aes_icm, "ciphertext: %s",
                v128_hex_string(&c->keystream_buffer));

    /* clock counter forward */

    if (forIsmacryp) {
        uint32_t temp;
        //alex's clock counter forward
        temp = ntohl(c->counter.v32[3]);
	++temp;
        c->counter.v32[3] = htonl(temp);
    } else {
        if (!++(c->counter.v8[15])) {
            ++(c->counter.v8[14]);
        }
    }
}
// int main(int argc, char *argv[]) {
int aes_calc(char *key8, char *phrase8, char *cipher8) {
    v128_t data, key;
    aes_expanded_key_t exp_key;
    int len;
    int verbose = 0;

    /* read in key, checking length */
    if (strlen(key8) > AES_KEY_LEN * 2) {
        fprintf(stderr, "error: too many digits in key "
            "(should be %d hexadecimal digits, found %u)\n", AES_KEY_LEN * 2,
                (unsigned) strlen(key8));
        return(1);
    }
    len = hex_string_to_octet_string((char *) &key, key8, AES_KEY_LEN*2);
    /* check that hex string is the right length */
    if (len < AES_KEY_LEN * 2) {
        fprintf(stderr, "error: too few digits in key "
            "(should be %d hexadecimal digits, found %d)\n", AES_KEY_LEN * 2,
                len);
        return(1);
    }

    /* read in plaintext, checking length */
    if (strlen(phrase8) > 16 * 2) {
        fprintf(stderr, "error: too many digits in plaintext "
            "(should be %d hexadecimal digits, found %u)\n", 16 * 2,
                (unsigned) strlen(phrase8));
        return(1);
    }
    len = hex_string_to_octet_string((char *) (&data), phrase8, 16 * 2);
    /* check that hex string is the right length */
    if (len < 16 * 2) {
        fprintf(stderr, "error: too few digits in plaintext "
            "(should be %d hexadecimal digits, found %d)\n", 16 * 2, len);
        return(1);
    }

    if (verbose) {
        /* print out plaintext */
        printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *) &data,
                16));
    }

    /* encrypt plaintext */
    aes_expand_encryption_key(&key, exp_key);

    aes_encrypt(&data, exp_key);

    /* write ciphertext to output */
    if (verbose) {
        printf("key:\t\t%s\n", v128_hex_string(&key));
        printf("ciphertext:\t");
    }
    printf("%s\n", v128_hex_string(&data));

    return strcmp(v128_hex_string(&data), cipher8);
}
err_status_t
aes_cbc_encrypt(aes_cbc_ctx_t *c,
                unsigned char *data,
                unsigned int *bytes_in_data) {
    int i;
    unsigned char *input  = data;   /* pointer to data being read    */
    unsigned char *output = data;   /* pointer to data being written */
    int bytes_to_encr = *bytes_in_data;

    /*
     * verify that we're 16-octet aligned
     */
    if (*bytes_in_data & 0xf)
        return err_status_bad_param;

    /*
     * note that we assume that the initialization vector has already
     * been set, e.g. by calling aes_cbc_set_iv()
     */
    debug_print(mod_aes_cbc, "iv: %s",
                v128_hex_string(&c->state));

    /*
     * loop over plaintext blocks, exoring state into plaintext then
     * encrypting and writing to output
     */
    while (bytes_to_encr > 0) {

        /* exor plaintext into state */
        for (i=0; i < 16; i++)
            c->state.v8[i] ^= *input++;

        debug_print(mod_aes_cbc, "inblock:  %s",
                    v128_hex_string(&c->state));

        aes_encrypt(&c->state, &c->expanded_key);

        debug_print(mod_aes_cbc, "outblock: %s",
                    v128_hex_string(&c->state));

        /* copy ciphertext to output */
        for (i=0; i < 16; i++)
            *output++ = c->state.v8[i];

        bytes_to_encr -= 16;
    }

    return err_status_ok;
}
err_status_t
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv, int direction) {
    err_status_t status;
    int i;
    /*   v128_t *input = iv; */
    uint8_t *input = (uint8_t*) iv;

    /* set state and 'previous' block to iv */
    for (i=0; i < 16; i++)
        c->previous.v8[i] = c->state.v8[i] = input[i];

    debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state));

    /* expand key for the appropriate direction */
    switch (direction) {
    case (direction_encrypt):
        status = aes_expand_encryption_key(c->key, c->key_len, &c->expanded_key);
        memset(c->key, 0, 32);
        if (status)
            return status;
        break;
    case (direction_decrypt):
        status = aes_expand_decryption_key(c->key, c->key_len, &c->expanded_key);
        memset(c->key, 0, 32);
        if (status)
            return status;
        break;
    default:
        return err_status_bad_param;
    }

    return err_status_ok;
}
示例#9
0
/*
 * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with
 * the offset
 */
static srtp_err_status_t srtp_aes_gcm_openssl_set_iv(
    void *cv,
    uint8_t *iv,
    srtp_cipher_direction_t direction)
{
    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;

    if (direction != srtp_direction_encrypt &&
        direction != srtp_direction_decrypt) {
        return (srtp_err_status_bad_param);
    }
    c->dir = direction;

    debug_print(srtp_mod_aes_gcm, "setting iv: %s",
                v128_hex_string((v128_t *)iv));

    if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
        return (srtp_err_status_init_fail);
    }

    if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL, iv,
                           (c->dir == srtp_direction_encrypt ? 1 : 0))) {
        return (srtp_err_status_init_fail);
    }

    return (srtp_err_status_ok);
}
示例#10
0
err_status_t
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, 
		     cipher_direction_t dir) {
  v128_t tmp_key;

  /* set tmp_key (for alignment) */
  v128_copy_octet_string(&tmp_key, key);

  debug_print(mod_aes_cbc, 
	      "key:  %s", v128_hex_string(&tmp_key)); 

  /* expand key for the appropriate direction */
  switch (dir) {
  case (direction_encrypt):
    aes_expand_encryption_key(&tmp_key, c->expanded_key);
    break;
  case (direction_decrypt):
    aes_expand_decryption_key(&tmp_key, c->expanded_key);
    break;
  default:
    return err_status_bad_param;
  }


  return err_status_ok;
}
示例#11
0
err_status_t
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
    v128_t *nonce = iv;

    debug_print(mod_aes_icm,
                "setting iv: %s", v128_hex_string(nonce));

    v128_xor(&c->counter, &c->offset, nonce);

    debug_print(mod_aes_icm,
                "set_counter: %s", v128_hex_string(&c->counter));

    /* indicate that the keystream_buffer is empty */
    c->bytes_in_buffer = 0;

    return err_status_ok;
}
示例#12
0
/*
 * aes_icm_advance(...) refills the keystream_buffer and
 * advances the block index of the sicm_context forward by one
 *
 * this is an internal, hopefully inlined function
 */
static void srtp_aes_icm_advance (srtp_aes_icm_ctx_t *c)
{
    /* fill buffer with new keystream */
    v128_copy(&c->keystream_buffer, &c->counter);
    srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
    c->bytes_in_buffer = sizeof(v128_t);

    debug_print(srtp_mod_aes_icm, "counter:    %s",
                v128_hex_string(&c->counter));
    debug_print(srtp_mod_aes_icm, "ciphertext: %s",
                v128_hex_string(&c->keystream_buffer));

    /* clock counter forward */
    if (!++(c->counter.v8[15])) {
        ++(c->counter.v8[14]);
    }
}
示例#13
0
/*
 * aes_icm_openssl_context_init(...) initializes the aes_icm_context
 * using the value in key[].
 *
 * the key is the secret key
 *
 * the salt is unpredictable (but not necessarily secret) data which
 * randomizes the starting point in the keystream
 */
err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key, int len)
{
    /*
     * set counter and initial values to 'offset' value, being careful not to
     * go past the end of the key buffer
     */

    if (c->key_size + SALT_SIZE != len)
        return err_status_bad_param;

    v128_set_to_zero(&c->counter);
    v128_set_to_zero(&c->offset);
    memcpy(&c->counter, key + c->key_size, SALT_SIZE);
    memcpy(&c->offset, key + c->key_size, SALT_SIZE);

    /* force last two octets of the offset to zero (for srtp compatibility) */
    c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0;
    c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0;

    /* copy key to be used later when CiscoSSL crypto context is created */
    v128_copy_octet_string((v128_t*)&c->key, key);

    /* if the key is greater than 16 bytes, copy the second
     * half.  Note, we treat AES-192 and AES-256 the same here
     * for simplicity.  The storage location receiving the
     * key is statically allocated to handle a full 32 byte key
     * regardless of the cipher in use.
     */
    if (c->key_size == AES_256_KEYSIZE
#ifndef BORINGSSL
        || c->key_size == AES_192_KEYSIZE
#endif
       ) {
        debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s",
                    v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
        v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE);
    }

    debug_print(mod_aes_icm, "key:  %s", v128_hex_string((v128_t*)&c->key));
    debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));

    EVP_CIPHER_CTX_cleanup(&c->ctx);

    return err_status_ok;
}
/*
 * aes_gcm_openssl_context_init(...) initializes the aes_gcm_context
 * using the value in key[].
 *
 * the key is the secret key
 */
err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx_t *c, const uint8_t *key)
{
    c->dir = direction_any;

    /* copy key to be used later when CiscoSSL crypto context is created */
    v128_copy_octet_string((v128_t*)&c->key, key);

    if (c->key_size == AES_256_KEYSIZE) {
        debug_print(mod_aes_gcm, "Copying last 16 bytes of key: %s",
                    v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
        v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, 
		               key + AES_128_KEYSIZE);
    }

    debug_print(mod_aes_gcm, "key:  %s", v128_hex_string((v128_t*)&c->key));

    EVP_CIPHER_CTX_cleanup(&c->ctx);

    return (err_status_ok);
}
示例#15
0
static srtp_err_status_t srtp_aes_icm_set_iv (srtp_aes_icm_ctx_t *c, uint8_t *iv, int direction)
{
    v128_t nonce;

    /* set nonce (for alignment) */
    v128_copy_octet_string(&nonce, iv);

    debug_print(srtp_mod_aes_icm,
                "setting iv: %s", v128_hex_string(&nonce));

    v128_xor(&c->counter, &c->offset, &nonce);

    debug_print(srtp_mod_aes_icm,
                "set_counter: %s", v128_hex_string(&c->counter));

    /* indicate that the keystream_buffer is empty */
    c->bytes_in_buffer = 0;

    return srtp_err_status_ok;
}
示例#16
0
/*
 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
 * the offset
 */
static srtp_err_status_t srtp_aes_icm_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir)
{
    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    v128_t nonce;

    /* set nonce (for alignment) */
    v128_copy_octet_string(&nonce, iv);

    debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));

    v128_xor(&c->counter, &c->offset, &nonce);

    debug_print(srtp_mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter));

    if (!EVP_EncryptInit_ex(c->ctx, NULL,
                            NULL, NULL, c->counter.v8)) {
        return srtp_err_status_fail;
    } else {
        return srtp_err_status_ok;
    }
}
示例#17
0
void
byte_order(void) {
  int i;
  v128_t e;
#if 0
  v16_t b;
  v32_t c;
  v64_t d;

  for (i=0; i < sizeof(b); i++)
    b.octet[i] = i;
  for (i=0; i < sizeof(c); i++)
    c.octet[i] = i;
  for (i=0; i < sizeof(d); i++)
    d.octet[i] = i;
  
  printf("v128_t:\t%s\n", v128_hex_string(&e));
  printf("v64_t:\t%s\n", v64_hex_string(&d));
  printf("v32_t:\t%s\n", v32_hex_string(c));
  printf("v16_t:\t%s\n", v16_hex_string(b));

  c.value = 0x01020304;
  printf("v32_t:\t%s\n", v32_hex_string(c));
  b.value = 0x0102;
  printf("v16_t:\t%s\n", v16_hex_string(b));

  printf("uint16_t ordering:\n");

  c.value = 0x00010002;
  printf("v32_t:\t%x%x\n", c.v16[0], c.v16[1]);
#endif 

  printf("byte ordering of crypto/math datatypes:\n");
  for (i=0; i < sizeof(e); i++)
    e.v8[i] = i;
  printf("v128_t: %s\n", v128_hex_string(&e));
  
}
示例#18
0
/*
 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
 * the offset
 */
err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir)
{
    const EVP_CIPHER *evp;
    v128_t nonce;

    /* set nonce (for alignment) */
    v128_copy_octet_string(&nonce, iv);

    debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));

    v128_xor(&c->counter, &c->offset, &nonce);

    debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter));

    switch (c->key_size) {
    case AES_256_KEYSIZE:
        evp = EVP_aes_256_ctr();
        break;
#ifndef BORINGSSL
    case AES_192_KEYSIZE:
        evp = EVP_aes_192_ctr();
        break;
#endif
    case AES_128_KEYSIZE:
        evp = EVP_aes_128_ctr();
        break;
    default:
        return err_status_bad_param;
        break;
    }

    if (!EVP_EncryptInit_ex(&c->ctx, evp,
                            NULL, c->key.v8, c->counter.v8)) {
        return err_status_fail;
    } else {
        return err_status_ok;
    }
}
示例#19
0
err_status_t
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
  int i;
/*   v128_t *input = iv; */
  uint8_t *input = iv;
 
  /* set state and 'previous' block to iv */
  for (i=0; i < 16; i++) 
    c->previous.v8[i] = c->state.v8[i] = input[i];

  debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state)); 

  return err_status_ok;
}
示例#20
0
err_status_t
aes_icm_set_octet(aes_icm_ctx_t *c,
                  uint64_t octet_num) {

    int tail_num       = octet_num % 16;
    uint64_t block_num = octet_num / 16;


    /* set counter value */
    c->counter.v64[0] = c->offset.v64[0];
    c->counter.v64[0] = c->offset.v64[0] ^ block_num;

    debug_print(mod_aes_icm,
                "set_octet: %s", v128_hex_string(&c->counter));

    /* fill keystream buffer, if needed */
    if (tail_num) {
        v128_copy(&c->keystream_buffer, &c->counter);
        aes_encrypt(&c->keystream_buffer, c->expanded_key);
        c->bytes_in_buffer = 16;

        debug_print(mod_aes_icm, "counter:    %s",
                    v128_hex_string(&c->counter));
        debug_print(mod_aes_icm, "ciphertext: %s",
                    v128_hex_string(&c->keystream_buffer));

        /*  indicate number of bytes in keystream_buffer  */
        c->bytes_in_buffer = 16 - tail_num;

    } else {

        /* indicate that keystream_buffer is empty */
        c->bytes_in_buffer = 0;
    }

    return err_status_ok;
}
示例#21
0
static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key)
{
    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    srtp_err_status_t status;
    int base_key_len, copy_len;

    if (c->key_size > 16 && c->key_size < 30) { /* Ismacryp */
        base_key_len = 16;
    } else if (c->key_size == 30 || c->key_size == 38 || c->key_size == 46) {
        base_key_len = c->key_size - 14;
    } else{
        return srtp_err_status_bad_param;
    }

    /*
     * set counter and initial values to 'offset' value, being careful not to
     * go past the end of the key buffer
     */
    v128_set_to_zero(&c->counter);
    v128_set_to_zero(&c->offset);

    copy_len = c->key_size - base_key_len;
    /* force last two octets of the offset to be left zero (for srtp compatibility) */
    if (copy_len > 14) {
        copy_len = 14;
    }

    memcpy(&c->counter, key + base_key_len, copy_len);
    memcpy(&c->offset, key + base_key_len, copy_len);

    debug_print(srtp_mod_aes_icm,
                "key:  %s", srtp_octet_string_hex_string(key, base_key_len));
    debug_print(srtp_mod_aes_icm,
                "offset: %s", v128_hex_string(&c->offset));

    /* expand key */
    status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
    if (status) {
        v128_set_to_zero(&c->counter);
        v128_set_to_zero(&c->offset);
        return status;
    }

    /* indicate that the keystream_buffer is empty */
    c->bytes_in_buffer = 0;

    return srtp_err_status_ok;
}
示例#22
0
/*
 * aes_icm_openssl_context_init(...) initializes the aes_icm_context
 * using the value in key[].
 *
 * the key is the secret key
 *
 * the salt is unpredictable (but not necessarily secret) data which
 * randomizes the starting point in the keystream
 */
static srtp_err_status_t srtp_aes_icm_openssl_context_init (void* cv, const uint8_t *key)
{
    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    const EVP_CIPHER *evp;

    /*
     * set counter and initial values to 'offset' value, being careful not to
     * go past the end of the key buffer
     */
    v128_set_to_zero(&c->counter);
    v128_set_to_zero(&c->offset);
    memcpy(&c->counter, key + c->key_size, SRTP_SALT_SIZE);
    memcpy(&c->offset, key + c->key_size, SRTP_SALT_SIZE);

    /* force last two octets of the offset to zero (for srtp compatibility) */
    c->offset.v8[SRTP_SALT_SIZE] = c->offset.v8[SRTP_SALT_SIZE + 1] = 0;
    c->counter.v8[SRTP_SALT_SIZE] = c->counter.v8[SRTP_SALT_SIZE + 1] = 0;

    debug_print(srtp_mod_aes_icm, "key:  %s", srtp_octet_string_hex_string(key, c->key_size));
    debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));

    switch (c->key_size) {
    case SRTP_AES_256_KEYSIZE:
        evp = EVP_aes_256_ctr();
        break;
#ifndef SRTP_NO_AES192
    case SRTP_AES_192_KEYSIZE:
        evp = EVP_aes_192_ctr();
        break;
#endif
    case SRTP_AES_128_KEYSIZE:
        evp = EVP_aes_128_ctr();
        break;
    default:
        return srtp_err_status_bad_param;
        break;
    }

    if (!EVP_EncryptInit_ex(c->ctx, evp,
                            NULL, key, NULL)) {
        return srtp_err_status_fail;
    } else {
        return srtp_err_status_ok;
    }

    return srtp_err_status_ok;
}
示例#23
0
/*
 * This function encrypts a buffer using AES CTR mode
 *
 * Parameters:
 *	c	Crypto context
 *	buf	data to encrypt
 *	enc_len	length of encrypt buffer
 */
err_status_t aes_icm_openssl_encrypt (aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len)
{
    int len = 0;

    debug_print(mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));

    if (!EVP_EncryptUpdate(&c->ctx, buf, &len, buf, *enc_len)) {
        return err_status_cipher_fail;
    }
    *enc_len = len;

    if (!EVP_EncryptFinal_ex(&c->ctx, buf, (int*)&len)) {
        return err_status_cipher_fail;
    }
    *enc_len += len;

    return err_status_ok;
}
/*
 * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with
 * the offset
 */
err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv,
	                             int direction)
{
    const EVP_CIPHER *evp;
    v128_t *nonce = iv;

    if (direction != direction_encrypt && direction != direction_decrypt) {
        return (err_status_bad_param);
    }
    c->dir = direction;

    debug_print(mod_aes_gcm, "setting iv: %s", v128_hex_string(nonce));

    switch (c->key_size) {
    case AES_256_KEYSIZE:
        evp = EVP_aes_256_gcm();
        break;
    case AES_128_KEYSIZE:
        evp = EVP_aes_128_gcm();
        break;
    default:
        return (err_status_bad_param);
        break;
    }

    if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8,
                           NULL, (c->dir == direction_encrypt ? 1 : 0))) {
        return (err_status_init_fail);
    }

    /* set IV len  and the IV value, the followiong 3 calls are required */
    if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
        return (err_status_init_fail);
    }
    if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) {
        return (err_status_init_fail);
    }
    if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) {
        return (err_status_init_fail);
    }

    return (err_status_ok);
}
示例#25
0
/*
 * This function encrypts a buffer using AES CTR mode
 *
 * Parameters:
 *	c	Crypto context
 *	buf	data to encrypt
 *	enc_len	length of encrypt buffer
 */
static srtp_err_status_t srtp_aes_icm_openssl_encrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
{
    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    int len = 0;

    debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));

    if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) {
        return srtp_err_status_cipher_fail;
    }
    *enc_len = len;

    if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) {
        return srtp_err_status_cipher_fail;
    }
    *enc_len += len;

    return srtp_err_status_ok;
}
err_status_t
aes_cbc_decrypt(aes_cbc_ctx_t *c,
                unsigned char *data,
                unsigned int *bytes_in_data) {
    int i;
    v128_t state, previous;
    unsigned char *input  = data;   /* pointer to data being read    */
    unsigned char *output = data;   /* pointer to data being written */
    int bytes_to_encr = *bytes_in_data;
    uint8_t tmp;

    /*
     * verify that we're 16-octet aligned
     */
    if (*bytes_in_data & 0x0f)
        return err_status_bad_param;

    /* set 'previous' block to iv*/
    for (i=0; i < 16; i++) {
        previous.v8[i] = c->previous.v8[i];
    }

    debug_print(mod_aes_cbc, "iv: %s",
                v128_hex_string(&previous));

    /*
     * loop over ciphertext blocks, decrypting then exoring with state
     * then writing plaintext to output
     */
    while (bytes_to_encr > 0) {

        /* set state to ciphertext input block */
        for (i=0; i < 16; i++) {
            state.v8[i] = *input++;
        }

        debug_print(mod_aes_cbc, "inblock:  %s",
                    v128_hex_string(&state));

        /* decrypt state */
        aes_decrypt(&state, &c->expanded_key);

        debug_print(mod_aes_cbc, "outblock: %s",
                    v128_hex_string(&state));

        /*
         * exor previous ciphertext block out of plaintext, and write new
         * plaintext block to output, while copying old ciphertext block
         * to the 'previous' block
         */
        for (i=0; i < 16; i++) {
            tmp = *output;
            *output++ = state.v8[i] ^ previous.v8[i];
            previous.v8[i] = tmp;
        }

        bytes_to_encr -= 16;
    }

    return err_status_ok;
}