Go to the source code of this file.
Defines | |
#define | PX_MAX_CRYPT 128 |
#define | PX_MAX_SALT_LEN 128 |
#define | PX_XDES_ROUNDS (29 * 25) |
#define | PX_BF_ROUNDS 6 |
Functions | |
char * | px_crypt (const char *psw, const char *salt, char *buf, unsigned buflen) |
int | px_gen_salt (const char *salt_type, char *dst, int rounds) |
char * | _crypt_gensalt_traditional_rn (unsigned long count, const char *input, int size, char *output, int output_size) |
char * | _crypt_gensalt_extended_rn (unsigned long count, const char *input, int size, char *output, int output_size) |
char * | _crypt_gensalt_md5_rn (unsigned long count, const char *input, int size, char *output, int output_size) |
char * | _crypt_gensalt_blowfish_rn (unsigned long count, const char *input, int size, char *output, int output_size) |
char * | _crypt_blowfish_rn (const char *key, const char *setting, char *output, int size) |
char * | px_crypt_des (const char *key, const char *setting) |
char * | px_crypt_md5 (const char *pw, const char *salt, char *dst, unsigned dstlen) |
#define PX_BF_ROUNDS 6 |
Definition at line 46 of file px-crypt.h.
#define PX_MAX_CRYPT 128 |
Definition at line 36 of file px-crypt.h.
Referenced by pg_crypt().
#define PX_MAX_SALT_LEN 128 |
Definition at line 39 of file px-crypt.h.
Referenced by pg_gen_salt(), pg_gen_salt_rounds(), and px_gen_salt().
#define PX_XDES_ROUNDS (29 * 25) |
Definition at line 43 of file px-crypt.h.
char* _crypt_blowfish_rn | ( | const char * | key, | |
const char * | setting, | |||
char * | output, | |||
int | size | |||
) |
Definition at line 578 of file crypt-blowfish.c.
References BF_atoi64, BF_body, BF_decode(), BF_encode(), BF_itoa64, BF_magic_w, BF_N, BF_set_key(), BF_swap(), i, and BF_ctx::S.
Referenced by run_crypt_bf().
{ struct { BF_ctx ctx; BF_key expanded_key; union { BF_word salt[4]; BF_word output[6]; } binary; } data; BF_word L, R; BF_word tmp1, tmp2, tmp3, tmp4; BF_word *ptr; BF_word count; int i; if (size < 7 + 22 + 31 + 1) return NULL; if (setting[0] != '$' || setting[1] != '2' || (setting[2] != 'a' && setting[2] != 'x') || setting[3] != '$' || setting[4] < '0' || setting[4] > '3' || setting[5] < '0' || setting[5] > '9' || (setting[4] == '3' && setting[5] > '1') || setting[6] != '$') { return NULL; } count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { memset(data.binary.salt, 0, sizeof(data.binary.salt)); return NULL; } BF_swap(data.binary.salt, 4); BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x'); memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); L = R = 0; for (i = 0; i < BF_N + 2; i += 2) { L ^= data.binary.salt[i & 2]; R ^= data.binary.salt[(i & 2) + 1]; BF_ENCRYPT; data.ctx.P[i] = L; data.ctx.P[i + 1] = R; } ptr = data.ctx.S[0]; do { ptr += 4; L ^= data.binary.salt[(BF_N + 2) & 3]; R ^= data.binary.salt[(BF_N + 3) & 3]; BF_ENCRYPT; *(ptr - 4) = L; *(ptr - 3) = R; L ^= data.binary.salt[(BF_N + 4) & 3]; R ^= data.binary.salt[(BF_N + 5) & 3]; BF_ENCRYPT; *(ptr - 2) = L; *(ptr - 1) = R; } while (ptr < &data.ctx.S[3][0xFF]); do { data.ctx.P[0] ^= data.expanded_key[0]; data.ctx.P[1] ^= data.expanded_key[1]; data.ctx.P[2] ^= data.expanded_key[2]; data.ctx.P[3] ^= data.expanded_key[3]; data.ctx.P[4] ^= data.expanded_key[4]; data.ctx.P[5] ^= data.expanded_key[5]; data.ctx.P[6] ^= data.expanded_key[6]; data.ctx.P[7] ^= data.expanded_key[7]; data.ctx.P[8] ^= data.expanded_key[8]; data.ctx.P[9] ^= data.expanded_key[9]; data.ctx.P[10] ^= data.expanded_key[10]; data.ctx.P[11] ^= data.expanded_key[11]; data.ctx.P[12] ^= data.expanded_key[12]; data.ctx.P[13] ^= data.expanded_key[13]; data.ctx.P[14] ^= data.expanded_key[14]; data.ctx.P[15] ^= data.expanded_key[15]; data.ctx.P[16] ^= data.expanded_key[16]; data.ctx.P[17] ^= data.expanded_key[17]; BF_body(); tmp1 = data.binary.salt[0]; tmp2 = data.binary.salt[1]; tmp3 = data.binary.salt[2]; tmp4 = data.binary.salt[3]; data.ctx.P[0] ^= tmp1; data.ctx.P[1] ^= tmp2; data.ctx.P[2] ^= tmp3; data.ctx.P[3] ^= tmp4; data.ctx.P[4] ^= tmp1; data.ctx.P[5] ^= tmp2; data.ctx.P[6] ^= tmp3; data.ctx.P[7] ^= tmp4; data.ctx.P[8] ^= tmp1; data.ctx.P[9] ^= tmp2; data.ctx.P[10] ^= tmp3; data.ctx.P[11] ^= tmp4; data.ctx.P[12] ^= tmp1; data.ctx.P[13] ^= tmp2; data.ctx.P[14] ^= tmp3; data.ctx.P[15] ^= tmp4; data.ctx.P[16] ^= tmp1; data.ctx.P[17] ^= tmp2; BF_body(); } while (--count); for (i = 0; i < 6; i += 2) { L = BF_magic_w[i]; R = BF_magic_w[i + 1]; count = 64; do { BF_ENCRYPT; } while (--count); data.binary.output[i] = L; data.binary.output[i + 1] = R; } memcpy(output, setting, 7 + 22 - 1); output[7 + 22 - 1] = BF_itoa64[(int) BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30]; /* This has to be bug-compatible with the original implementation, so * only encode 23 of the 24 bytes. :-) */ BF_swap(data.binary.output, 6); BF_encode(&output[7 + 22], data.binary.output, 23); output[7 + 22 + 31] = '\0'; /* Overwrite the most obvious sensitive data we have on the stack. Note * that this does not guarantee there's no sensitive data left on the * stack and/or in registers; I'm not aware of portable code that does. */ memset(&data, 0, sizeof(data)); return output; }
char* _crypt_gensalt_blowfish_rn | ( | unsigned long | count, | |
const char * | input, | |||
int | size, | |||
char * | output, | |||
int | output_size | |||
) |
Definition at line 161 of file crypt-gensalt.c.
References BF_encode().
{ if (size < 16 || output_size < 7 + 22 + 1 || (count && (count < 4 || count > 31))) { if (output_size > 0) output[0] = '\0'; return NULL; } if (!count) count = 5; output[0] = '$'; output[1] = '2'; output[2] = 'a'; output[3] = '$'; output[4] = '0' + count / 10; output[5] = '0' + count % 10; output[6] = '$'; BF_encode(&output[7], (const BF_word *) input, 16); output[7 + 22] = '\0'; return output; }
char* _crypt_gensalt_extended_rn | ( | unsigned long | count, | |
const char * | input, | |||
int | size, | |||
char * | output, | |||
int | output_size | |||
) |
Definition at line 43 of file crypt-gensalt.c.
References _crypt_itoa64, and value.
{ unsigned long value; /* Even iteration counts make it easier to detect weak DES keys from a look * at the hash, so they should be avoided */ if (size < 3 || output_size < 1 + 4 + 4 + 1 || (count && (count > 0xffffff || !(count & 1)))) { if (output_size > 0) output[0] = '\0'; return NULL; } if (!count) count = 725; output[0] = '_'; output[1] = _crypt_itoa64[count & 0x3f]; output[2] = _crypt_itoa64[(count >> 6) & 0x3f]; output[3] = _crypt_itoa64[(count >> 12) & 0x3f]; output[4] = _crypt_itoa64[(count >> 18) & 0x3f]; value = (unsigned long) (unsigned char) input[0] | ((unsigned long) (unsigned char) input[1] << 8) | ((unsigned long) (unsigned char) input[2] << 16); output[5] = _crypt_itoa64[value & 0x3f]; output[6] = _crypt_itoa64[(value >> 6) & 0x3f]; output[7] = _crypt_itoa64[(value >> 12) & 0x3f]; output[8] = _crypt_itoa64[(value >> 18) & 0x3f]; output[9] = '\0'; return output; }
char* _crypt_gensalt_md5_rn | ( | unsigned long | count, | |
const char * | input, | |||
int | size, | |||
char * | output, | |||
int | output_size | |||
) |
Definition at line 79 of file crypt-gensalt.c.
References _crypt_itoa64, and value.
{ unsigned long value; if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) { if (output_size > 0) output[0] = '\0'; return NULL; } output[0] = '$'; output[1] = '1'; output[2] = '$'; value = (unsigned long) (unsigned char) input[0] | ((unsigned long) (unsigned char) input[1] << 8) | ((unsigned long) (unsigned char) input[2] << 16); output[3] = _crypt_itoa64[value & 0x3f]; output[4] = _crypt_itoa64[(value >> 6) & 0x3f]; output[5] = _crypt_itoa64[(value >> 12) & 0x3f]; output[6] = _crypt_itoa64[(value >> 18) & 0x3f]; output[7] = '\0'; if (size >= 6 && output_size >= 3 + 4 + 4 + 1) { value = (unsigned long) (unsigned char) input[3] | ((unsigned long) (unsigned char) input[4] << 8) | ((unsigned long) (unsigned char) input[5] << 16); output[7] = _crypt_itoa64[value & 0x3f]; output[8] = _crypt_itoa64[(value >> 6) & 0x3f]; output[9] = _crypt_itoa64[(value >> 12) & 0x3f]; output[10] = _crypt_itoa64[(value >> 18) & 0x3f]; output[11] = '\0'; } return output; }
char* _crypt_gensalt_traditional_rn | ( | unsigned long | count, | |
const char * | input, | |||
int | size, | |||
char * | output, | |||
int | output_size | |||
) |
Definition at line 25 of file crypt-gensalt.c.
References _crypt_itoa64.
{ if (size < 2 || output_size < 2 + 1 || (count && count != 25)) { if (output_size > 0) output[0] = '\0'; return NULL; } output[0] = _crypt_itoa64[(unsigned int) input[0] & 0x3f]; output[1] = _crypt_itoa64[(unsigned int) input[1] & 0x3f]; output[2] = '\0'; return output; }
char* px_crypt | ( | const char * | psw, | |
const char * | salt, | |||
char * | buf, | |||
unsigned | buflen | |||
) |
Definition at line 91 of file px-crypt.c.
References px_crypt_algo::crypt, px_crypt_algo::id, px_crypt_algo::id_len, and NULL.
Referenced by pg_crypt().
{ const struct px_crypt_algo *c; for (c = px_crypt_list; c->id; c++) { if (!c->id_len) break; if (strncmp(salt, c->id, c->id_len) == 0) break; } if (c->crypt == NULL) return NULL; return c->crypt(psw, salt, buf, len); }
char* px_crypt_des | ( | const char * | key, | |
const char * | setting | |||
) |
Definition at line 649 of file crypt-des.c.
References _crypt_a64, _PASSWORD_EFMT1, ascii_to_bin(), des_cipher(), des_init(), des_initialised, des_setkey(), do_des(), i, NULL, output(), and setup_salt().
Referenced by run_crypt_des().
{ int i; uint32 count, salt, l, r0, r1, keybuf[2]; char *p; uint8 *q; static char output[21]; if (!des_initialised) des_init(); /* * Copy the key, shifting each character up by one bit and padding with * zeros. */ q = (uint8 *) keybuf; while (q - (uint8 *) keybuf - 8) { *q++ = *key << 1; if (*key != '\0') key++; } if (des_setkey((char *) keybuf)) return (NULL); #ifndef DISABLE_XDES if (*setting == _PASSWORD_EFMT1) { /* * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of * salt key - unlimited characters */ for (i = 1, count = 0L; i < 5; i++) count |= ascii_to_bin(setting[i]) << (i - 1) * 6; for (i = 5, salt = 0L; i < 9; i++) salt |= ascii_to_bin(setting[i]) << (i - 5) * 6; while (*key) { /* * Encrypt the key with itself. */ if (des_cipher((char *) keybuf, (char *) keybuf, 0L, 1)) return (NULL); /* * And XOR with the next 8 characters of the key. */ q = (uint8 *) keybuf; while (q - (uint8 *) keybuf - 8 && *key) *q++ ^= *key++ << 1; if (des_setkey((char *) keybuf)) return (NULL); } strncpy(output, setting, 9); /* * Double check that we weren't given a short setting. If we were, the * above code will probably have created weird values for count and * salt, but we don't really care. Just make sure the output string * doesn't have an extra NUL in it. */ output[9] = '\0'; p = output + strlen(output); } else #endif /* !DISABLE_XDES */ { /* * "old"-style: setting - 2 bytes of salt key - up to 8 characters */ count = 25; salt = (ascii_to_bin(setting[1]) << 6) | ascii_to_bin(setting[0]); output[0] = setting[0]; /* * If the encrypted password that the salt was extracted from is only * 1 character long, the salt will be corrupted. We need to ensure * that the output string doesn't have an extra NUL in it! */ output[1] = setting[1] ? setting[1] : output[0]; p = output + 2; } setup_salt(salt); /* * Do it. */ if (do_des(0L, 0L, &r0, &r1, count)) return (NULL); /* * Now encode the result... */ l = (r0 >> 8); *p++ = _crypt_a64[(l >> 18) & 0x3f]; *p++ = _crypt_a64[(l >> 12) & 0x3f]; *p++ = _crypt_a64[(l >> 6) & 0x3f]; *p++ = _crypt_a64[l & 0x3f]; l = (r0 << 16) | ((r1 >> 16) & 0xffff); *p++ = _crypt_a64[(l >> 18) & 0x3f]; *p++ = _crypt_a64[(l >> 12) & 0x3f]; *p++ = _crypt_a64[(l >> 6) & 0x3f]; *p++ = _crypt_a64[l & 0x3f]; l = r1 << 2; *p++ = _crypt_a64[(l >> 12) & 0x3f]; *p++ = _crypt_a64[(l >> 6) & 0x3f]; *p++ = _crypt_a64[l & 0x3f]; *p = 0; return (output); }
char* px_crypt_md5 | ( | const char * | pw, | |
const char * | salt, | |||
char * | dst, | |||
unsigned | dstlen | |||
) |
Definition at line 34 of file crypt-md5.c.
References _crypt_to64(), i, MD5_SIZE, px_find_digest(), px_md_finish, px_md_free, px_md_reset, and px_md_update.
Referenced by run_crypt_md5().
{ static char *magic = "$1$"; /* This string is magic for this algorithm. * Having it this way, we can get better later * on */ static char *p; static const char *sp, *ep; unsigned char final[MD5_SIZE]; int sl, pl, i; PX_MD *ctx, *ctx1; int err; unsigned long l; if (!passwd || dstlen < 120) return NULL; /* Refine the Salt first */ sp = salt; /* If it starts with the magic string, then skip that */ if (strncmp(sp, magic, strlen(magic)) == 0) sp += strlen(magic); /* It stops at the first '$', max 8 chars */ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) continue; /* get the length of the true salt */ sl = ep - sp; /* */ err = px_find_digest("md5", &ctx); if (err) return NULL; err = px_find_digest("md5", &ctx1); /* The password first, since that is what is most unknown */ px_md_update(ctx, (const uint8 *) pw, strlen(pw)); /* Then our magic string */ px_md_update(ctx, (uint8 *) magic, strlen(magic)); /* Then the raw salt */ px_md_update(ctx, (const uint8 *) sp, sl); /* Then just as many characters of the MD5(pw,salt,pw) */ px_md_update(ctx1, (const uint8 *) pw, strlen(pw)); px_md_update(ctx1, (const uint8 *) sp, sl); px_md_update(ctx1, (const uint8 *) pw, strlen(pw)); px_md_finish(ctx1, final); for (pl = strlen(pw); pl > 0; pl -= MD5_SIZE) px_md_update(ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl); /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof final); /* Then something really weird... */ for (i = strlen(pw); i; i >>= 1) if (i & 1) px_md_update(ctx, final, 1); else px_md_update(ctx, (const uint8 *) pw, 1); /* Now make the output string */ strcpy(passwd, magic); strncat(passwd, sp, sl); strcat(passwd, "$"); px_md_finish(ctx, final); /* * and now, just to make sure things don't run too fast On a 60 Mhz * Pentium this takes 34 msec, so you would need 30 seconds to build a * 1000 entry dictionary... */ for (i = 0; i < 1000; i++) { px_md_reset(ctx1); if (i & 1) px_md_update(ctx1, (const uint8 *) pw, strlen(pw)); else px_md_update(ctx1, final, MD5_SIZE); if (i % 3) px_md_update(ctx1, (const uint8 *) sp, sl); if (i % 7) px_md_update(ctx1, (const uint8 *) pw, strlen(pw)); if (i & 1) px_md_update(ctx1, final, MD5_SIZE); else px_md_update(ctx1, (const uint8 *) pw, strlen(pw)); px_md_finish(ctx1, final); } p = passwd + strlen(passwd); l = (final[0] << 16) | (final[6] << 8) | final[12]; _crypt_to64(p, l, 4); p += 4; l = (final[1] << 16) | (final[7] << 8) | final[13]; _crypt_to64(p, l, 4); p += 4; l = (final[2] << 16) | (final[8] << 8) | final[14]; _crypt_to64(p, l, 4); p += 4; l = (final[3] << 16) | (final[9] << 8) | final[15]; _crypt_to64(p, l, 4); p += 4; l = (final[4] << 16) | (final[10] << 8) | final[5]; _crypt_to64(p, l, 4); p += 4; l = final[11]; _crypt_to64(p, l, 2); p += 2; *p = '\0'; /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof final); px_md_free(ctx1); px_md_free(ctx); return passwd; }
int px_gen_salt | ( | const char * | salt_type, | |
char * | dst, | |||
int | rounds | |||
) |
Definition at line 133 of file px-crypt.c.
References generator::def_rounds, generator::gen, generator::input_len, generator::max_rounds, generator::min_rounds, generator::name, NULL, pg_strcasecmp(), px_get_pseudo_random_bytes(), and PX_MAX_SALT_LEN.
Referenced by pg_gen_salt(), and pg_gen_salt_rounds().
{ int res; struct generator *g; char *p; char rbuf[16]; for (g = gen_list; g->name; g++) if (pg_strcasecmp(g->name, salt_type) == 0) break; if (g->name == NULL) return PXE_UNKNOWN_SALT_ALGO; if (g->def_rounds) { if (rounds == 0) rounds = g->def_rounds; if (rounds < g->min_rounds || rounds > g->max_rounds) return PXE_BAD_SALT_ROUNDS; } res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len); if (res < 0) return res; p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); memset(rbuf, 0, sizeof(rbuf)); if (p == NULL) return PXE_BAD_SALT_ROUNDS; return strlen(p); }