I am trying to track down a failure in my version of the nss_Ldap code
and have been using valgrind 3.3.0/3.3.1 on Fedora 9 running memcheck
with leak-check=full to assist in this.
I am getting problems reported in the kerberos code but cannot see why
they are being reported could anybody throw some light on this.
I attach my modified version of rc4.c which shows these errors, as does
the release version from krb5-1.6.3. My mods have been done to remove
some additional variables and to ensure that the memory passed into the
k5_arcfour_init routine are all pre-initialised.
We see 2 problems: first the use of uninitialised memory being reported
cannot be explained, but also the first reported sequence happens 4
times when there is only 2 iterations of the loop it falls within.
Although there are 2 calls of the routine which may explain this. (See
error report 1 below).
We then get a single report of an error on lines inside a loop that
iterates 256 times over data that has been initialised in code just
above the loop. BUT this is only reported once (hence in the second call
to the routine) See error report 2 below.
Any ideas?
Howard.
==13190== Conditional jump or move depends on uninitialised value(s)
==13190== at 0x5448BA: k5_arcfour_init (rc4.c:95)
==13190== by 0x544AF8: k5_arcfour_docrypt (rc4.c:152)
==13190== by 0x629162: kg_get_seq_num (util_seqnum.c:74)
==13190== by 0x6297BC: kg_make_seq_num (val_cred.c:56)
==13190== by 0x6239CC: rotate_left (string3.h:59)
==13190== by 0x62705E: krb5_gss_seal (set_allowable_enctypes.c:98)
==13190== by 0x625E96: gss_krb5_get_tkt_flags (krb5_gss_glue.c:1031)
==13190== by 0x616539: gss_unseal (g_unseal.c:83)
==13190== by 0x616596: gss_unwrap (g_unseal.c:118)
==13190== by 0x486D0B8: gssapi_client_mech_step (gssapi.c:1680)
==13190== by 0x14468A: sasl_client_step (client.c:655)
==13190== by 0x4691CDB: ldap_int_sasl_bind (in
/usr/lib/libnss_ldap-264.so)
==13190== Use of uninitialised value of size 4
==13190== at 0x544933: k5_arcfour_init (rc4.c:110)
==13190== by 0x544AF8: k5_arcfour_docrypt (rc4.c:152)
==13190== by 0x629162: kg_get_seq_num (util_seqnum.c:74)
==13190== by 0x6297BC: kg_make_seq_num (val_cred.c:56)
==13190== by 0x6239CC: rotate_left (string3.h:59)
==13190== by 0x62705E: krb5_gss_seal (set_allowable_enctypes.c:98)
==13190== by 0x625E96: gss_krb5_get_tkt_flags (krb5_gss_glue.c:1031)
==13190== by 0x616539: gss_unseal (g_unseal.c:83)
==13190== by 0x616596: gss_unwrap (g_unseal.c:118)
==13190== by 0x486D0B8: gssapi_client_mech_step (gssapi.c:1680)
==13190== by 0x14468A: sasl_client_step (client.c:655)
==13190== by 0x4691CDB: ldap_int_sasl_bind (in
/usr/lib/libnss_ldap-264.so)
==13190==
==13190== Use of uninitialised value of size 4
==13190== at 0x54493E: k5_arcfour_init (rc4.c:111)
==13190== by 0x544AF8: k5_arcfour_docrypt (rc4.c:152)
==13190== by 0x629162: kg_get_seq_num (util_seqnum.c:74)
==13190== by 0x6297BC: kg_make_seq_num (val_cred.c:56)
==13190== by 0x6239CC: rotate_left (string3.h:59)
==13190== by 0x62705E: krb5_gss_seal (set_allowable_enctypes.c:98)
==13190== by 0x625E96: gss_krb5_get_tkt_flags (krb5_gss_glue.c:1031)
==13190== by 0x616539: gss_unseal (g_unseal.c:83)
==13190== by 0x616596: gss_unwrap (g_unseal.c:118)
==13190== by 0x486D0B8: gssapi_client_mech_step (gssapi.c:1680)
==13190== by 0x14468A: sasl_client_step (client.c:655)
==13190== by 0x4691CDB: ldap_int_sasl_bind (in
/usr/lib/libnss_ldap-264.so)
==13190==
/* arcfour.c
*
* Copyright (c) 2000 by Computer Science Laboratory,
* Rensselaer Polytechnic Institute
*
* #include STD_DISCLAIMER
*/
#include "k5-int.h"
#include "arcfour-int.h"
#include "enc_provider.h"
/* gets the next byte from the PRNG */
#if ((__GNUC__ >= 2) )
static __inline__ unsigned int k5_arcfour_byte(ArcfourContext *);
#else
static unsigned int k5_arcfour_byte(ArcfourContext *);
#endif /* gcc inlines*/
/* Initializes the context and sets the key. */
static krb5_error_code k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key,
unsigned int keylen);
/* Encrypts/decrypts data. */
static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest,
const unsigned char *src, unsigned int len);
/* Interface layer to kerb5 crypto layer */
static krb5_error_code
k5_arcfour_docrypt(const krb5_keyblock *, const krb5_data *,
const krb5_data *, krb5_data *);
/* from a random bitstrem, construct a key */
static krb5_error_code
k5_arcfour_make_key(const krb5_data *, krb5_keyblock *);
static const unsigned char arcfour_weakkey1[] = {0x00, 0x00, 0xfd};
static const unsigned char arcfour_weakkey2[] = {0x03, 0xfd, 0xfc};
static const struct {
size_t length;
const unsigned char *data;
} arcfour_weakkeys[] = {
{ sizeof (arcfour_weakkey1), arcfour_weakkey1},
{ sizeof (arcfour_weakkey2), arcfour_weakkey2}
};
/*xxx we really should check for c9x here and use inline on
* more than just gcc. */
#if ((__GNUC__ >= 2) )
static __inline__ unsigned int k5_arcfour_byte(ArcfourContext * ctx)
#else
static unsigned int k5_arcfour_byte(ArcfourContext * ctx)
#endif /* gcc inlines*/
{
unsigned int x;
unsigned int y;
unsigned int sx, sy;
unsigned char *state;
state = ctx->state;
x = (ctx->x + 1) & 0xff;
sx = state[x];
y = (sx + ctx->y) & 0xff;
sy = state[y];
ctx->x = x;
ctx->y = y;
state[y] = sx;
state[x] = sy;
return state[(sx + sy) & 0xff];
}
static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest,
const unsigned char *src, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
dest[i] = src[i] ^ k5_arcfour_byte(ctx);
}
static krb5_error_code
k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key,
unsigned int key_len)
{
unsigned int keyindex;
unsigned int stateindex;
unsigned int counter;
if (key_len != 16)
return KRB5_BAD_MSIZE; /*this is probably not the correct error code
to return */
for(counter = 0;
counter < sizeof(arcfour_weakkeys)/sizeof(arcfour_weakkeys[0]);
counter++) {
assert(key_len >= arcfour_weakkeys[counter].length);
if (!memcmp(key, arcfour_weakkeys[counter].data,
arcfour_weakkeys[counter].length))
return KRB5DES_WEAK_KEY; /* most certainly not the correct error */
}
ctx->x = 0;
ctx->y = 0;
for (counter = 0; counter < sizeof(ctx->state); counter++)
ctx->state[counter] = counter;
for (keyindex = 0, stateindex = 0, counter = 0; counter < sizeof(ctx->state); counter++)
{
unsigned char t, u;
t = ctx->state[counter];
stateindex = (stateindex + key[keyindex] + t) % sizeof(ctx->state);
assert(stateindex < sizeof(ctx->state));
u = ctx->state[stateindex];
ctx->state[stateindex] = t;
ctx->state[counter] = u;
if ((keyindex += 1) >= key_len)
keyindex = 0;
}
return 0;
}
/* The workhorse of the arcfour system, this impliments the cipher */
static krb5_error_code
k5_arcfour_docrypt(const krb5_keyblock *key, const krb5_data *state,
const krb5_data *input, krb5_data *output)
{
ArcfourContext *arcfour_ctx;
ArcFourCipherState *cipher_state;
int ret;
if (key->length != 16)
return(KRB5_BAD_KEYSIZE);
if (state && (state->length != sizeof (ArcFourCipherState)))
return(KRB5_BAD_MSIZE);
if (input->length != output->length)
return(KRB5_BAD_MSIZE);
if (state) {
cipher_state = (ArcFourCipherState *) state->data;
arcfour_ctx=&cipher_state->ctx;
if (cipher_state->initialized == 0) {
if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) {
return ret;
}
cipher_state->initialized = 1;
}
k5_arcfour_crypt(arcfour_ctx, (unsigned char *) output->data, (const unsigned char *) input->data, input->length);
}
else {
arcfour_ctx=malloc(sizeof (ArcfourContext));
if (arcfour_ctx == NULL)
return ENOMEM;
memset(arcfour_ctx, 0, sizeof (ArcfourContext));
if ((ret=k5_arcfour_init(arcfour_ctx, key->contents, key->length))) {
free(arcfour_ctx);
return (ret);
}
k5_arcfour_crypt(arcfour_ctx, (unsigned char * ) output->data,
(const unsigned char * ) input->data, input->length);
memset(arcfour_ctx, 0, sizeof (ArcfourContext));
free(arcfour_ctx);
}
return 0;
}
static krb5_error_code
k5_arcfour_make_key(const krb5_data *randombits, krb5_keyblock *key)
{
if (key->length != 16)
return(KRB5_BAD_KEYSIZE);
if (randombits->length != 16)
return(KRB5_CRYPTO_INTERNAL);
key->magic = KV5M_KEYBLOCK;
key->length = 16;
memcpy(key->contents, randombits->data, randombits->length);
return(0);
}
static krb5_error_code
k5_arcfour_init_state (const krb5_keyblock *key,
krb5_keyusage keyusage, krb5_data *new_state)
{
/* Note that we can't actually set up the state here because the key
* will change between now and when encrypt is called
* because it is data dependent. Yeah, this has strange
* properties. --SDH
*/
new_state->length = sizeof (ArcFourCipherState);
new_state->data = malloc (new_state->length);
if (new_state->data) {
memset (new_state->data, 0 , new_state->length);
/* That will set initialized to zero*/
}else {
return (ENOMEM);
}
return 0;
}
/* Since the arcfour cipher is identical going forwards and backwards,
we just call "docrypt" directly
*/
const struct krb5_enc_provider krb5int_enc_arcfour = {
/* This seems to work... although I am not sure what the
implications are in other places in the kerberos library */
1,
/* Keysize is arbitrary in arcfour, but the constraints of the
system, and to attempt to work with the MSFT system forces us
to 16byte/128bit. Since there is no parity in the key, the
byte and length are the same. */
16, 16,
k5_arcfour_docrypt,
k5_arcfour_docrypt,
k5_arcfour_make_key,
k5_arcfour_init_state, /*xxx not implemented yet*/
krb5int_default_free_state
};
------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you. Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users