Dmitry Eremin-Solenikov(lumag) replied on github web page:

platform/linux-generic/odp_crypto.c
line 152
@@ -308,6 +319,142 @@ void packet_hmac(odp_packet_t pkt,
        HMAC_Final(ctx, hash, NULL);
 }
 
+static void do_pad_xor(uint8_t *out, const uint8_t *in, int len) {
+       int pos=0;
+       for (pos=1; pos <= 16; pos++, in++, out++) {
+               if (pos <= len)
+                       *out ^= *in;
+               if (pos > len) {
+                       *out ^= 0x80;
+                       break;
+               }
+       }
+}
+static void xor_block(aes_block res, const aes_block op) {
+       res[0] ^= op[0];
+       res[1] ^= op[1];
+       res[2] ^= op[2];
+       res[3] ^= op[3];
+}
+
+static
+odp_crypto_alg_err_t aesxcbc_gen(odp_packet_t pkt,
+                             const odp_crypto_packet_op_param_t *param,
+                             odp_crypto_generic_session_t *session)
+{
+       aes_block e = {0, 0, 0, 0};
+       uint8_t *data  = odp_packet_data(pkt);
+       uint8_t *icv   = data;
+       uint32_t len = param->auth_range.length;
+       uint8_t  hash_out[16];
+       EVP_CIPHER_CTX *ctx;
+       int dummy_len = 0;
+       /* Adjust pointer for beginning of area to auth */
+       data += param->auth_range.offset;
+       icv  += param->hash_result_offset;
+
+       ctx = EVP_CIPHER_CTX_new();
+       EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, session->auth.key, 
NULL);
+       for (; len > AES_BLOCK_SIZE ; len -= AES_BLOCK_SIZE) {
+               xor_block(e, (const uint32_t*) data);
+               EVP_EncryptUpdate(ctx, (uint8_t *)e, &dummy_len, (uint8_t *)e, 
sizeof(e));
+               data += AES_BLOCK_SIZE;
+       }
+       do_pad_xor((uint8_t *)e, data, len);
+       if (len == AES_BLOCK_SIZE) {
+               xor_block(e, (const uint32_t*) (session->auth.key + 16));
+       }
+       else
+       {
+               xor_block(e, (const uint32_t*) (session->auth.key + 16*2));
+       }
+       EVP_EncryptUpdate(ctx, hash_out, &dummy_len, (uint8_t *)e, sizeof(e));
+       EVP_CIPHER_CTX_free(ctx);       
+       memcpy (icv, hash_out, 12);
+       
+       return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+odp_crypto_alg_err_t aesxcbc_check(odp_packet_t pkt,
+                             const odp_crypto_packet_op_param_t *param,
+                             odp_crypto_generic_session_t *session)
+{
+       aes_block e = {0, 0, 0, 0};
+       uint8_t *data  = odp_packet_data(pkt);
+       uint8_t *icv   = data;
+       uint32_t len = param->auth_range.length;
+       uint8_t  hash_in[12];
+       uint8_t  hash_out[12];
+       EVP_CIPHER_CTX *ctx;
+       int dummy_len = 0;
+       
+       /* Adjust pointer for beginning of area to auth */
+       data += param->auth_range.offset;
+       icv  += param->hash_result_offset;
+       
+       /* Copy current value out and clear it before authentication */
+       memset(hash_in, 0, sizeof(hash_in));
+       memcpy(hash_in, icv, 12);
+       memset(hash_out, 0, sizeof(hash_out));
+
+       ctx = EVP_CIPHER_CTX_new();
+       EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, session->auth.key, 
NULL);
+
+       for (; len > AES_BLOCK_SIZE ; len -= AES_BLOCK_SIZE) {
+               xor_block(e, (const uint32_t*) data);
+               EVP_EncryptUpdate(ctx, (uint8_t *)e, &dummy_len, (uint8_t *)e, 
sizeof(e));
+               data += AES_BLOCK_SIZE;
+       }
+       do_pad_xor((uint8_t *)e, data, len);
+       if (len == AES_BLOCK_SIZE) {
+               xor_block(e, (const uint32_t*) (session->auth.key + 16));
+       }
+       else
+       {
+               xor_block(e, (const uint32_t*) (session->auth.key + 16*2));
+       }
+       EVP_EncryptUpdate(ctx, hash_out, &dummy_len, (uint8_t *)e, sizeof(e));
+       EVP_CIPHER_CTX_free(ctx);       
+       /* Verify match */
+       if (0 != memcmp(hash_in, hash_out, 12))
+               return ODP_CRYPTO_ALG_ERR_ICV_CHECK;
+
+       /* Matched */
+       return ODP_CRYPTO_ALG_ERR_NONE;
+}      
+
+static int process_aesxcbc_param(odp_crypto_generic_session_t *session)
+{
+       aes_block kn[3] = {
+               { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
+               { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
+               { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
+       };
+       EVP_CIPHER_CTX *ctx;
+       int dummy_len = 0;
+       
+       /* Set function */
+       if (ODP_CRYPTO_OP_ENCODE == session->p.op)
+               session->auth.func = aesxcbc_gen;
+       else
+               session->auth.func = aesxcbc_check;


Comment:
You also need to set auth.init func here. For now you can use nullinit function

> Dmitry Eremin-Solenikov(lumag) wrote:
> XCBC-MAC computation should be extracted to a separate function.


>> Dmitry Eremin-Solenikov(lumag) wrote:
>> This will not work with segmented packets.


>>> Dmitry Eremin-Solenikov(lumag) wrote:
>>> Please use `uint32_t*` instead of adding new type.


https://github.com/Linaro/odp/pull/470#discussion_r167567113
updated_at 2018-02-12 14:34:03

Reply via email to