Index: srtp/crypto/ae_xfm/xfm.c |
diff --git a/srtp/crypto/ae_xfm/xfm.c b/srtp/crypto/ae_xfm/xfm.c |
deleted file mode 100644 |
index c3c08d9c7be4b781b56e4b1a647a768e5c0aef4b..0000000000000000000000000000000000000000 |
--- a/srtp/crypto/ae_xfm/xfm.c |
+++ /dev/null |
@@ -1,605 +0,0 @@ |
-/* |
- * xfm.c |
- * |
- * Crypto transform implementation |
- * |
- * David A. McGrew |
- * Cisco Systems, Inc. |
- */ |
-/* |
- * |
- * Copyright (c) 2001-2006, Cisco Systems, Inc. |
- * All rights reserved. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * |
- * Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * |
- * Redistributions in binary form must reproduce the above |
- * copyright notice, this list of conditions and the following |
- * disclaimer in the documentation and/or other materials provided |
- * with the distribution. |
- * |
- * Neither the name of the Cisco Systems, Inc. nor the names of its |
- * contributors may be used to endorse or promote products derived |
- * from this software without specific prior written permission. |
- * |
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
- * OF THE POSSIBILITY OF SUCH DAMAGE. |
- * |
- */ |
- |
-#include "cryptoalg.h" |
-#include "aes_cbc.h" |
-#include "hmac.h" |
-#include "crypto_kernel.h" /* for crypto_get_random() */ |
- |
-#define KEY_LEN 16 |
-#define ENC_KEY_LEN 16 |
-#define MAC_KEY_LEN 16 |
-#define IV_LEN 16 |
-#define TAG_LEN 12 |
-#define MAX_EXPAND 27 |
- |
-err_status_t |
-aes_128_cbc_hmac_sha1_96_func(void *key, |
- void *clear, |
- unsigned clear_len, |
- void *iv, |
- void *opaque, |
- unsigned *opaque_len, |
- void *auth_tag) { |
- aes_cbc_ctx_t aes_ctx; |
- hmac_ctx_t hmac_ctx; |
- unsigned char enc_key[ENC_KEY_LEN]; |
- unsigned char mac_key[MAC_KEY_LEN]; |
- err_status_t status; |
- |
- /* check if we're doing authentication only */ |
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { |
- |
- /* perform authentication only */ |
- |
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { |
- |
- /* |
- * bad parameter - we expect either all three pointers to be NULL, |
- * or none of those pointers to be NULL |
- */ |
- return err_status_fail; |
- |
- } else { |
- |
- /* derive encryption and authentication keys from the input key */ |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); |
- if (status) return status; |
- |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); |
- if (status) return status; |
- |
- |
- /* perform encryption and authentication */ |
- |
- /* set aes key */ |
- status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt); |
- if (status) return status; |
- |
- /* set iv */ |
- status = crypto_get_random(iv, IV_LEN); |
- if (status) return status; |
- status = aes_cbc_set_iv(&aes_ctx, iv); |
- |
- /* encrypt the opaque data */ |
- status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); |
- if (status) return status; |
- |
- /* authenticate clear and opaque data */ |
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); |
- if (status) return status; |
- |
- status = hmac_start(&hmac_ctx); |
- if (status) return status; |
- |
- status = hmac_update(&hmac_ctx, clear, clear_len); |
- if (status) return status; |
- |
- status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); |
- if (status) return status; |
- |
- } |
- |
- return err_status_ok; |
-} |
- |
-err_status_t |
-aes_128_cbc_hmac_sha1_96_inv(void *key, |
- void *clear, |
- unsigned clear_len, |
- void *iv, |
- void *opaque, |
- unsigned *opaque_len, |
- void *auth_tag) { |
- aes_cbc_ctx_t aes_ctx; |
- hmac_ctx_t hmac_ctx; |
- unsigned char enc_key[ENC_KEY_LEN]; |
- unsigned char mac_key[MAC_KEY_LEN]; |
- unsigned char tmp_tag[TAG_LEN]; |
- unsigned char *tag = auth_tag; |
- err_status_t status; |
- int i; |
- |
- /* check if we're doing authentication only */ |
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { |
- |
- /* perform authentication only */ |
- |
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { |
- |
- /* |
- * bad parameter - we expect either all three pointers to be NULL, |
- * or none of those pointers to be NULL |
- */ |
- return err_status_fail; |
- |
- } else { |
- |
- /* derive encryption and authentication keys from the input key */ |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); |
- if (status) return status; |
- |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); |
- if (status) return status; |
- |
- /* perform encryption and authentication */ |
- |
- /* set aes key */ |
- status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt); |
- if (status) return status; |
- |
- /* set iv */ |
- status = rand_source_get_octet_string(iv, IV_LEN); |
- if (status) return status; |
- status = aes_cbc_set_iv(&aes_ctx, iv); |
- |
- /* encrypt the opaque data */ |
- status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len); |
- if (status) return status; |
- |
- /* authenticate clear and opaque data */ |
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); |
- if (status) return status; |
- |
- status = hmac_start(&hmac_ctx); |
- if (status) return status; |
- |
- status = hmac_update(&hmac_ctx, clear, clear_len); |
- if (status) return status; |
- |
- status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag); |
- if (status) return status; |
- |
- /* compare the computed tag with the one provided as input */ |
- for (i=0; i < TAG_LEN; i++) |
- if (tmp_tag[i] != tag[i]) |
- return err_status_auth_fail; |
- |
- } |
- |
- return err_status_ok; |
-} |
- |
- |
-#define ENC 1 |
- |
-#define DEBUG 0 |
- |
-err_status_t |
-aes_128_cbc_hmac_sha1_96_enc(void *key, |
- const void *clear, |
- unsigned clear_len, |
- void *iv, |
- void *opaque, |
- unsigned *opaque_len) { |
- aes_cbc_ctx_t aes_ctx; |
- hmac_ctx_t hmac_ctx; |
- unsigned char enc_key[ENC_KEY_LEN]; |
- unsigned char mac_key[MAC_KEY_LEN]; |
- unsigned char *auth_tag; |
- err_status_t status; |
- |
- /* check if we're doing authentication only */ |
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { |
- |
- /* perform authentication only */ |
- |
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { |
- |
- /* |
- * bad parameter - we expect either all three pointers to be NULL, |
- * or none of those pointers to be NULL |
- */ |
- return err_status_fail; |
- |
- } else { |
- |
-#if DEBUG |
- printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); |
-#endif |
- |
- /* derive encryption and authentication keys from the input key */ |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); |
- if (status) return status; |
- |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); |
- if (status) return status; |
- |
- |
- /* perform encryption and authentication */ |
- |
- /* set aes key */ |
- status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt); |
- if (status) return status; |
- |
- /* set iv */ |
- status = rand_source_get_octet_string(iv, IV_LEN); |
- if (status) return status; |
- status = aes_cbc_set_iv(&aes_ctx, iv); |
- if (status) return status; |
- |
-#if DEBUG |
- printf("plaintext len: %d\n", *opaque_len); |
- printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); |
- printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- |
-#if ENC |
- /* encrypt the opaque data */ |
- status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); |
- if (status) return status; |
-#endif |
- |
-#if DEBUG |
- printf("ciphertext len: %d\n", *opaque_len); |
- printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- |
- /* |
- * authenticate clear and opaque data, then write the |
- * authentication tag to the location immediately following the |
- * ciphertext |
- */ |
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); |
- if (status) return status; |
- |
- status = hmac_start(&hmac_ctx); |
- if (status) return status; |
- |
- status = hmac_update(&hmac_ctx, clear, clear_len); |
- if (status) return status; |
-#if DEBUG |
- printf("hmac input: %s\n", |
- octet_string_hex_string(clear, clear_len)); |
-#endif |
- auth_tag = (unsigned char *)opaque; |
- auth_tag += *opaque_len; |
- status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); |
- if (status) return status; |
-#if DEBUG |
- printf("hmac input: %s\n", |
- octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- /* bump up the opaque_len to reflect the authentication tag */ |
- *opaque_len += TAG_LEN; |
- |
-#if DEBUG |
- printf("prot data len: %d\n", *opaque_len); |
- printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- } |
- |
- return err_status_ok; |
-} |
- |
-err_status_t |
-aes_128_cbc_hmac_sha1_96_dec(void *key, |
- const void *clear, |
- unsigned clear_len, |
- void *iv, |
- void *opaque, |
- unsigned *opaque_len) { |
- aes_cbc_ctx_t aes_ctx; |
- hmac_ctx_t hmac_ctx; |
- unsigned char enc_key[ENC_KEY_LEN]; |
- unsigned char mac_key[MAC_KEY_LEN]; |
- unsigned char tmp_tag[TAG_LEN]; |
- unsigned char *auth_tag; |
- unsigned ciphertext_len; |
- err_status_t status; |
- int i; |
- |
- /* check if we're doing authentication only */ |
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { |
- |
- /* perform authentication only */ |
- |
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { |
- |
- /* |
- * bad parameter - we expect either all three pointers to be NULL, |
- * or none of those pointers to be NULL |
- */ |
- return err_status_fail; |
- |
- } else { |
-#if DEBUG |
- printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); |
-#endif |
- |
- /* derive encryption and authentication keys from the input key */ |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); |
- if (status) return status; |
- |
- status = hmac_init(&hmac_ctx, key, KEY_LEN); |
- if (status) return status; |
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); |
- if (status) return status; |
- |
-#if DEBUG |
- printf("prot data len: %d\n", *opaque_len); |
- printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- |
- /* |
- * set the protected data length to that of the ciphertext, by |
- * subtracting out the length of the authentication tag |
- */ |
- ciphertext_len = *opaque_len - TAG_LEN; |
- |
-#if DEBUG |
- printf("ciphertext len: %d\n", ciphertext_len); |
-#endif |
- /* verify the authentication tag */ |
- |
- /* |
- * compute the authentication tag for the clear and opaque data, |
- * and write it to a temporary location |
- */ |
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); |
- if (status) return status; |
- |
- status = hmac_start(&hmac_ctx); |
- if (status) return status; |
- |
- status = hmac_update(&hmac_ctx, clear, clear_len); |
- if (status) return status; |
- |
-#if DEBUG |
- printf("hmac input: %s\n", |
- octet_string_hex_string(clear, clear_len)); |
-#endif |
- |
- status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag); |
- if (status) return status; |
- |
-#if DEBUG |
- printf("hmac input: %s\n", |
- octet_string_hex_string(opaque, ciphertext_len)); |
-#endif |
- |
- /* |
- * compare the computed tag with the one provided as input (which |
- * immediately follows the ciphertext) |
- */ |
- auth_tag = (unsigned char *)opaque; |
- auth_tag += ciphertext_len; |
-#if DEBUG |
- printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN)); |
- printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN)); |
-#endif |
- for (i=0; i < TAG_LEN; i++) { |
- if (tmp_tag[i] != auth_tag[i]) |
- return err_status_auth_fail; |
- } |
- |
- /* bump down the opaque_len to reflect the authentication tag */ |
- *opaque_len -= TAG_LEN; |
- |
- /* decrypt the confidential data */ |
- status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt); |
- if (status) return status; |
- status = aes_cbc_set_iv(&aes_ctx, iv); |
- if (status) return status; |
- |
-#if DEBUG |
- printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); |
- printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); |
-#endif |
- |
-#if ENC |
- status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len); |
- if (status) return status; |
-#endif |
- |
-#if DEBUG |
- printf("plaintext len: %d\n", ciphertext_len); |
- printf("plaintext: %s\n", |
- octet_string_hex_string(opaque, ciphertext_len)); |
-#endif |
- |
- /* indicate the length of the plaintext */ |
- *opaque_len = ciphertext_len; |
- } |
- |
- return err_status_ok; |
-} |
- |
-cryptoalg_ctx_t cryptoalg_ctx = { |
- aes_128_cbc_hmac_sha1_96_enc, |
- aes_128_cbc_hmac_sha1_96_dec, |
- KEY_LEN, |
- IV_LEN, |
- TAG_LEN, |
- MAX_EXPAND, |
-}; |
- |
-cryptoalg_t cryptoalg = &cryptoalg_ctx; |
- |
-#define NULL_TAG_LEN 12 |
- |
-err_status_t |
-null_enc(void *key, |
- const void *clear, |
- unsigned clear_len, |
- void *iv, |
- void *opaque, |
- unsigned *opaque_len) { |
- int i; |
- unsigned char *auth_tag; |
- unsigned char *init_vec = iv; |
- |
- /* check if we're doing authentication only */ |
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { |
- |
- /* perform authentication only */ |
- |
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { |
- |
- /* |
- * bad parameter - we expect either all three pointers to be NULL, |
- * or none of those pointers to be NULL |
- */ |
- return err_status_fail; |
- |
- } else { |
- |
-#if DEBUG |
- printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); |
- printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN); |
- printf("plaintext len: %d\n", *opaque_len); |
-#endif |
- for (i=0; i < IV_LEN; i++) |
- init_vec[i] = i + (i * 16); |
-#if DEBUG |
- printf("iv: %s\n", |
- octet_string_hex_string(iv, IV_LEN)); |
- printf("plaintext: %s\n", |
- octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- auth_tag = opaque; |
- auth_tag += *opaque_len; |
- for (i=0; i < NULL_TAG_LEN; i++) |
- auth_tag[i] = i + (i * 16); |
- *opaque_len += NULL_TAG_LEN; |
-#if DEBUG |
- printf("protected data len: %d\n", *opaque_len); |
- printf("protected data: %s\n", |
- octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- |
- } |
- |
- return err_status_ok; |
-} |
- |
-err_status_t |
-null_dec(void *key, |
- const void *clear, |
- unsigned clear_len, |
- void *iv, |
- void *opaque, |
- unsigned *opaque_len) { |
- unsigned char *auth_tag; |
- |
- /* check if we're doing authentication only */ |
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { |
- |
- /* perform authentication only */ |
- |
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { |
- |
- /* |
- * bad parameter - we expect either all three pointers to be NULL, |
- * or none of those pointers to be NULL |
- */ |
- return err_status_fail; |
- |
- } else { |
- |
-#if DEBUG |
- printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); |
- |
- printf("protected data len: %d\n", *opaque_len); |
- printf("protected data: %s\n", |
- octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- auth_tag = opaque; |
- auth_tag += (*opaque_len - NULL_TAG_LEN); |
-#if DEBUG |
- printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); |
-#endif |
- *opaque_len -= NULL_TAG_LEN; |
-#if DEBUG |
- printf("plaintext len: %d\n", *opaque_len); |
- printf("plaintext: %s\n", |
- octet_string_hex_string(opaque, *opaque_len)); |
-#endif |
- } |
- |
- return err_status_ok; |
-} |
- |
-cryptoalg_ctx_t null_cryptoalg_ctx = { |
- null_enc, |
- null_dec, |
- KEY_LEN, |
- IV_LEN, |
- NULL_TAG_LEN, |
- MAX_EXPAND, |
-}; |
- |
-cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx; |
- |
-int |
-cryptoalg_get_id(cryptoalg_t c) { |
- if (c == cryptoalg) |
- return 1; |
- return 0; |
-} |
- |
-cryptoalg_t |
-cryptoalg_find_by_id(int id) { |
- switch(id) { |
- case 1: |
- return cryptoalg; |
- default: |
- break; |
- } |
- return 0; |
-} |