int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad,
                      size_t len)
{
    u64 i, all_num_blocks;
    size_t num_blocks, last_len;
    OCB_BLOCK tmp1;
    OCB_BLOCK tmp2;

    /* Calculate the number of blocks of AAD provided now, and so far */
    num_blocks = len / 16;
    all_num_blocks = num_blocks + ctx->blocks_hashed;

    /* Loop through all full blocks of AAD */
    for (i = ctx->blocks_hashed + 1; i <= all_num_blocks; i++) {
        OCB_BLOCK *lookup;
        OCB_BLOCK *aad_block;

        /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
        lookup = ocb_lookup_l(ctx, ocb_ntz(i));
        if (lookup == NULL)
            return 0;
        ocb_block16_xor(&ctx->offset_aad, lookup, &ctx->offset_aad);

        /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
        aad_block = (OCB_BLOCK *)(aad + ((i - ctx->blocks_hashed - 1) * 16));
        ocb_block16_xor_misaligned(&ctx->offset_aad, aad_block, &tmp1);
        ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc);
        ocb_block16_xor(&ctx->sum, &tmp2, &ctx->sum);
    }

    /*
     * Check if we have any partial blocks left over. This is only valid in the
     * last call to this function
     */
    last_len = len % 16;

    if (last_len > 0) {
        /* Offset_* = Offset_m xor L_* */
        ocb_block16_xor(&ctx->offset_aad, &ctx->l_star, &ctx->offset_aad);

        /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
        memset(&tmp1, 0, 16);
        memcpy(&tmp1, aad + (num_blocks * 16), last_len);
        ((unsigned char *)&tmp1)[last_len] = 0x80;
        ocb_block16_xor(&ctx->offset_aad, &tmp1, &tmp2);

        /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
        ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc);
        ocb_block16_xor(&ctx->sum, &tmp1, &ctx->sum);
    }

    ctx->blocks_hashed = all_num_blocks;

    return 1;
}