crypto/modes/gcm128.c:1252: error: BUFFER_OVERRUN_L3
  Offset added: 16 Size: [0, +oo].
Showing all 3 steps of the trace


crypto/modes/gcm128.c:1216:1: <Length trace>
1214.   }
1215.   
1216. > int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
1217.                             const unsigned char *in, unsigned char *out,
1218.                             size_t len)

crypto/modes/gcm128.c:1216:1: Parameter `ctx->Xn[*]`
1214.   }
1215.   
1216. > int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
1217.                             const unsigned char *in, unsigned char *out,
1218.                             size_t len)

crypto/modes/gcm128.c:1252:9: Array access: Offset added: 16 Size: [0, +oo]
1250.               return 0;
1251.           }
1252.           memcpy(ctx->Xn, ctx->Xi.c, sizeof(ctx->Xi));
                ^
1253.           ctx->Xi.u[0] = 0;
1254.           ctx->Xi.u[1] = 0;

int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
                          const unsigned char *in, unsigned char *out,
                          size_t len)
{
    const union {
        long one;
        char little;
    } is_endian = { 1 };
    unsigned int n, ctr, mres;
    size_t i;
    u64 mlen = ctx->len.u[1];
    block128_f block = ctx->block;
    void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
                         const u8 *inp, size_t len) = ctx->ghash;
# endif
#endif
    mlen += len;
    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
        return -1;
    ctx->len.u[1] = mlen;
    mres = ctx->mres;
    if (ctx->ares) {
#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
        if (len == 0) {
            GCM_MUL(ctx);
            ctx->ares = 0;
            return 0;
        }
        memcpy(ctx->Xn, ctx->Xi.c, sizeof(ctx->Xi));
        ctx->Xi.u[0] = 0;
        ctx->Xi.u[1] = 0;
        mres = sizeof(ctx->Xi);
#else
        GCM_MUL(ctx);
#endif
        ctx->ares = 0;
    }
    if (is_endian.little)
#ifdef BSWAP4
        ctr = BSWAP4(ctx->Yi.d[3]);
#else
        ctr = GETU32(ctx->Yi.c + 12);
#endif
    else
        ctr = ctx->Yi.d[3];
    n = mres % 16;
#if !defined(OPENSSL_SMALL_FOOTPRINT)
    if (16 % sizeof(size_t) == 0) {
        do {
            if (n) {
# if defined(GHASH)
                while (n && len) {
                    *(out++) = (ctx->Xn[mres++] = *(in++)) ^ ctx->EKi.c[n];
                    --len;
                    n = (n + 1) % 16;
                }
                if (n == 0) {
                    GHASH(ctx, ctx->Xn, mres);
                    mres = 0;
                } else {
                    ctx->mres = mres;
                    return 0;
                }
# else
                while (n && len) {
                    u8 c = *(in++);
                    *(out++) = c ^ ctx->EKi.c[n];
                    ctx->Xi.c[n] ^= c;
                    --len;
                    n = (n + 1) % 16;
                }
                if (n == 0) {
                    GCM_MUL(ctx);
                    mres = 0;
                } else {
                    ctx->mres = n;
                    return 0;
                }
# endif
            }
# if defined(STRICT_ALIGNMENT)
            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
                break;
# endif
# if defined(GHASH)
            if (len >= 16 && mres) {
                GHASH(ctx, ctx->Xn, mres);
                mres = 0;
            }
#  if defined(GHASH_CHUNK)
            while (len >= GHASH_CHUNK) {
                size_t j = GHASH_CHUNK;
                GHASH(ctx, in, GHASH_CHUNK);
                while (j) {
                    size_t *out_t = (size_t *)out;
                    const size_t *in_t = (const size_t *)in;
                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
                    ++ctr;
                    if (is_endian.little)
#   ifdef BSWAP4
                        ctx->Yi.d[3] = BSWAP4(ctr);
#   else
                        PUTU32(ctx->Yi.c + 12, ctr);
#   endif
                    else
                        ctx->Yi.d[3] = ctr;
                    for (i = 0; i < 16 / sizeof(size_t); ++i)
                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
                    out += 16;
                    in += 16;
                    j -= 16;
                }
                len -= GHASH_CHUNK;
            }
#  endif
            if ((i = (len & (size_t)-16))) {
                GHASH(ctx, in, i);
                while (len >= 16) {
                    size_t *out_t = (size_t *)out;
                    const size_t *in_t = (const size_t *)in;
                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
                    ++ctr;
                    if (is_endian.little)
#  ifdef BSWAP4
                        ctx->Yi.d[3] = BSWAP4(ctr);
#  else
                        PUTU32(ctx->Yi.c + 12, ctr);
#  endif
                    else
                        ctx->Yi.d[3] = ctr;
                    for (i = 0; i < 16 / sizeof(size_t); ++i)
                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
                    out += 16;
                    in += 16;
                    len -= 16;
                }
            }
# else
            while (len >= 16) {
                size_t *out_t = (size_t *)out;
                const size_t *in_t = (const size_t *)in;
                (*block) (ctx->Yi.c, ctx->EKi.c, key);
                ++ctr;
                if (is_endian.little)
#  ifdef BSWAP4
                    ctx->Yi.d[3] = BSWAP4(ctr);
#  else
                    PUTU32(ctx->Yi.c + 12, ctr);
#  endif
                else
                    ctx->Yi.d[3] = ctr;
                for (i = 0; i < 16 / sizeof(size_t); ++i) {
                    size_t c = in[i];
                    out[i] = c ^ ctx->EKi.t[i];
                    ctx->Xi.t[i] ^= c;
                }
                GCM_MUL(ctx);
                out += 16;
                in += 16;
                len -= 16;
            }
# endif
            if (len) {
                (*block) (ctx->Yi.c, ctx->EKi.c, key);
                ++ctr;
                if (is_endian.little)
# ifdef BSWAP4
                    ctx->Yi.d[3] = BSWAP4(ctr);
# else
                    PUTU32(ctx->Yi.c + 12, ctr);
# endif
                else
                    ctx->Yi.d[3] = ctr;
# if defined(GHASH)
                while (len--) {
                    out[n] = (ctx->Xn[mres++] = in[n]) ^ ctx->EKi.c[n];
                    ++n;
                }
# else
                while (len--) {
                    u8 c = in[n];
                    ctx->Xi.c[n] ^= c;
                    out[n] = c ^ ctx->EKi.c[n];
                    ++n;
                }
                mres = n;
# endif
            }
            ctx->mres = mres;
            return 0;
        } while (0);
    }
#endif
    for (i = 0; i < len; ++i) {
        u8 c;
        if (n == 0) {
            (*block) (ctx->Yi.c, ctx->EKi.c, key);
            ++ctr;
            if (is_endian.little)
#ifdef BSWAP4
                ctx->Yi.d[3] = BSWAP4(ctr);
#else
                PUTU32(ctx->Yi.c + 12, ctr);
#endif
            else
                ctx->Yi.d[3] = ctr;
        }
#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
        out[i] = (ctx->Xn[mres++] = c = in[i]) ^ ctx->EKi.c[n];
        n = (n + 1) % 16;
        if (mres == sizeof(ctx->Xn)) {
            GHASH(ctx,ctx->Xn,sizeof(ctx->Xn));
            mres = 0;
        }
#else
        c = in[i];
        out[i] = c ^ ctx->EKi.c[n];
        ctx->Xi.c[n] ^= c;
        mres = n = (n + 1) % 16;
        if (n == 0)
            GCM_MUL(ctx);
#endif
    }
    ctx->mres = mres;
    return 0;
}
['int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,\n                          const unsigned char *in, unsigned char *out,\n                          size_t len)\n{\n    const union {\n        long one;\n        char little;\n    } is_endian = { 1 };\n    unsigned int n, ctr, mres;\n    size_t i;\n    u64 mlen = ctx->len.u[1];\n    block128_f block = ctx->block;\n    void *key = ctx->key;\n#ifdef GCM_FUNCREF_4BIT\n    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;\n# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)\n    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],\n                         const u8 *inp, size_t len) = ctx->ghash;\n# endif\n#endif\n    mlen += len;\n    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))\n        return -1;\n    ctx->len.u[1] = mlen;\n    mres = ctx->mres;\n    if (ctx->ares) {\n#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)\n        if (len == 0) {\n            GCM_MUL(ctx);\n            ctx->ares = 0;\n            return 0;\n        }\n        memcpy(ctx->Xn, ctx->Xi.c, sizeof(ctx->Xi));\n        ctx->Xi.u[0] = 0;\n        ctx->Xi.u[1] = 0;\n        mres = sizeof(ctx->Xi);\n#else\n        GCM_MUL(ctx);\n#endif\n        ctx->ares = 0;\n    }\n    if (is_endian.little)\n#ifdef BSWAP4\n        ctr = BSWAP4(ctx->Yi.d[3]);\n#else\n        ctr = GETU32(ctx->Yi.c + 12);\n#endif\n    else\n        ctr = ctx->Yi.d[3];\n    n = mres % 16;\n#if !defined(OPENSSL_SMALL_FOOTPRINT)\n    if (16 % sizeof(size_t) == 0) {\n        do {\n            if (n) {\n# if defined(GHASH)\n                while (n && len) {\n                    *(out++) = (ctx->Xn[mres++] = *(in++)) ^ ctx->EKi.c[n];\n                    --len;\n                    n = (n + 1) % 16;\n                }\n                if (n == 0) {\n                    GHASH(ctx, ctx->Xn, mres);\n                    mres = 0;\n                } else {\n                    ctx->mres = mres;\n                    return 0;\n                }\n# else\n                while (n && len) {\n                    u8 c = *(in++);\n                    *(out++) = c ^ ctx->EKi.c[n];\n                    ctx->Xi.c[n] ^= c;\n                    --len;\n                    n = (n + 1) % 16;\n                }\n                if (n == 0) {\n                    GCM_MUL(ctx);\n                    mres = 0;\n                } else {\n                    ctx->mres = n;\n                    return 0;\n                }\n# endif\n            }\n# if defined(STRICT_ALIGNMENT)\n            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)\n                break;\n# endif\n# if defined(GHASH)\n            if (len >= 16 && mres) {\n                GHASH(ctx, ctx->Xn, mres);\n                mres = 0;\n            }\n#  if defined(GHASH_CHUNK)\n            while (len >= GHASH_CHUNK) {\n                size_t j = GHASH_CHUNK;\n                GHASH(ctx, in, GHASH_CHUNK);\n                while (j) {\n                    size_t *out_t = (size_t *)out;\n                    const size_t *in_t = (const size_t *)in;\n                    (*block) (ctx->Yi.c, ctx->EKi.c, key);\n                    ++ctr;\n                    if (is_endian.little)\n#   ifdef BSWAP4\n                        ctx->Yi.d[3] = BSWAP4(ctr);\n#   else\n                        PUTU32(ctx->Yi.c + 12, ctr);\n#   endif\n                    else\n                        ctx->Yi.d[3] = ctr;\n                    for (i = 0; i < 16 / sizeof(size_t); ++i)\n                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];\n                    out += 16;\n                    in += 16;\n                    j -= 16;\n                }\n                len -= GHASH_CHUNK;\n            }\n#  endif\n            if ((i = (len & (size_t)-16))) {\n                GHASH(ctx, in, i);\n                while (len >= 16) {\n                    size_t *out_t = (size_t *)out;\n                    const size_t *in_t = (const size_t *)in;\n                    (*block) (ctx->Yi.c, ctx->EKi.c, key);\n                    ++ctr;\n                    if (is_endian.little)\n#  ifdef BSWAP4\n                        ctx->Yi.d[3] = BSWAP4(ctr);\n#  else\n                        PUTU32(ctx->Yi.c + 12, ctr);\n#  endif\n                    else\n                        ctx->Yi.d[3] = ctr;\n                    for (i = 0; i < 16 / sizeof(size_t); ++i)\n                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];\n                    out += 16;\n                    in += 16;\n                    len -= 16;\n                }\n            }\n# else\n            while (len >= 16) {\n                size_t *out_t = (size_t *)out;\n                const size_t *in_t = (const size_t *)in;\n                (*block) (ctx->Yi.c, ctx->EKi.c, key);\n                ++ctr;\n                if (is_endian.little)\n#  ifdef BSWAP4\n                    ctx->Yi.d[3] = BSWAP4(ctr);\n#  else\n                    PUTU32(ctx->Yi.c + 12, ctr);\n#  endif\n                else\n                    ctx->Yi.d[3] = ctr;\n                for (i = 0; i < 16 / sizeof(size_t); ++i) {\n                    size_t c = in[i];\n                    out[i] = c ^ ctx->EKi.t[i];\n                    ctx->Xi.t[i] ^= c;\n                }\n                GCM_MUL(ctx);\n                out += 16;\n                in += 16;\n                len -= 16;\n            }\n# endif\n            if (len) {\n                (*block) (ctx->Yi.c, ctx->EKi.c, key);\n                ++ctr;\n                if (is_endian.little)\n# ifdef BSWAP4\n                    ctx->Yi.d[3] = BSWAP4(ctr);\n# else\n                    PUTU32(ctx->Yi.c + 12, ctr);\n# endif\n                else\n                    ctx->Yi.d[3] = ctr;\n# if defined(GHASH)\n                while (len--) {\n                    out[n] = (ctx->Xn[mres++] = in[n]) ^ ctx->EKi.c[n];\n                    ++n;\n                }\n# else\n                while (len--) {\n                    u8 c = in[n];\n                    ctx->Xi.c[n] ^= c;\n                    out[n] = c ^ ctx->EKi.c[n];\n                    ++n;\n                }\n                mres = n;\n# endif\n            }\n            ctx->mres = mres;\n            return 0;\n        } while (0);\n    }\n#endif\n    for (i = 0; i < len; ++i) {\n        u8 c;\n        if (n == 0) {\n            (*block) (ctx->Yi.c, ctx->EKi.c, key);\n            ++ctr;\n            if (is_endian.little)\n#ifdef BSWAP4\n                ctx->Yi.d[3] = BSWAP4(ctr);\n#else\n                PUTU32(ctx->Yi.c + 12, ctr);\n#endif\n            else\n                ctx->Yi.d[3] = ctr;\n        }\n#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)\n        out[i] = (ctx->Xn[mres++] = c = in[i]) ^ ctx->EKi.c[n];\n        n = (n + 1) % 16;\n        if (mres == sizeof(ctx->Xn)) {\n            GHASH(ctx,ctx->Xn,sizeof(ctx->Xn));\n            mres = 0;\n        }\n#else\n        c = in[i];\n        out[i] = c ^ ctx->EKi.c[n];\n        ctx->Xi.c[n] ^= c;\n        mres = n = (n + 1) % 16;\n        if (n == 0)\n            GCM_MUL(ctx);\n#endif\n    }\n    ctx->mres = mres;\n    return 0;\n}']