From: Szabolcs Nagy <nsz@port70.net>
To: musl@lists.openwall.com
Subject: Re: crypt* files in crypt directory
Date: Thu, 9 Aug 2012 13:58:12 +0200 [thread overview]
Message-ID: <20120809115811.GA32316@port70.net> (raw)
In-Reply-To: <20120809105348.GA27361@openwall.com>
it's scary how these crypto codes mix various
signed and unsigned integer types
i thought these algorithms were designed and
implemented with the c type system in mind..
i added review comments
the style comments are subjective of course
* Solar Designer <solar@openwall.com> [2012-08-09 14:53:48 +0400]:
> typedef unsigned int BF_word;
> typedef signed int BF_word_signed;
>
> /* Number of Blowfish rounds, this is also hardcoded into a few places */
> #define BF_N 16
>
> typedef BF_word BF_key[BF_N + 2];
i don't like these typedefs
it seems the code assumes 32bit unsigned BF_word
(eg. the way L>>24 is used below)
> #define BF_safe_atoi64(dst, src) \
> { \
> tmp = (unsigned char)(src); \
> if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
tmp is already unsigned int
> #define BF_ROUND(L, R, N) \
> tmp1 = L & 0xFF; \
> tmp2 = L >> 8; \
> tmp2 &= 0xFF; \
> tmp3 = L >> 16; \
> tmp3 &= 0xFF; \
> tmp4 = L >> 24; \
> tmp1 = ctx->s.S[3][tmp1]; \
> tmp2 = ctx->s.S[2][tmp2]; \
> tmp3 = ctx->s.S[1][tmp3]; \
> tmp3 += ctx->s.S[0][tmp4]; \
> tmp3 ^= tmp2; \
> R ^= ctx->s.P[N + 1]; \
> tmp3 += tmp1; \
> R ^= tmp3;
i guess this is performance critical, but
i wouldn't spread those expressions over
several lines
tmp1 = ctx->S[3][L & 0xff];
tmp2 = ctx->S[2][L>>8 & 0xff];
tmp3 = ctx->S[1][L>>16 & 0xff];
tmp4 = ctx->S[0][L>>24 & 0xff];
R ^= ctx->P[N+1];
R ^= ((tmp3 + tmp4) ^ tmp2) + tmp1;
> do {
> ptr += 2;
> L ^= ctx->s.P[0];
> BF_ROUND(L, R, 0);
> BF_ROUND(R, L, 1);
> BF_ROUND(L, R, 2);
> BF_ROUND(R, L, 3);
> BF_ROUND(L, R, 4);
> BF_ROUND(R, L, 5);
> BF_ROUND(L, R, 6);
> BF_ROUND(R, L, 7);
> BF_ROUND(L, R, 8);
> BF_ROUND(R, L, 9);
> BF_ROUND(L, R, 10);
> BF_ROUND(R, L, 11);
> BF_ROUND(L, R, 12);
> BF_ROUND(R, L, 13);
> BF_ROUND(L, R, 14);
> BF_ROUND(R, L, 15);
> tmp4 = R;
> R = L;
> L = tmp4 ^ ctx->s.P[BF_N + 1];
> *(ptr - 1) = R;
> *(ptr - 2) = L;
> } while (ptr < end);
why increase ptr at the begining?
it seems the idiomatic way would be
*ptr++ = L;
*ptr++ = R;
> tmp[1] |= (BF_word_signed)(signed char)*ptr; /* bug */
i don't think the BF_word_signed cast helps here
signed char is promoted to int and then
it will be converted to BF_word
> if (setting[0] != '$' ||
> setting[1] != '2' ||
> setting[2] < 'a' || setting[2] > 'z' ||
> !flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] ||
setting[2] is already range checked so
the casts are not necessary
(assuming 'a' < 'z')
> BF_set_key(key, data.expanded_key, data.ctx.s.P,
> flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a']);
ditto
> do {
> L = BF_encrypt(&data.ctx,
> L ^ data.binary.salt[0], R ^ data.binary.salt[1],
> ptr, ptr);
> R = *(ptr + 1);
> ptr += 2;
>
> if (ptr >= &data.ctx.PS[BF_N + 2 + 4 * 0x100])
> break;
>
> L = BF_encrypt(&data.ctx,
> L ^ data.binary.salt[2], R ^ data.binary.salt[3],
> ptr, ptr);
> R = *(ptr + 1);
> ptr += 2;
> } while (1);
i'd use for (;;) for infinite loops
eventhough most of the loops in the code are do{}while
> do {
> int done;
>
> for (i = 0; i < BF_N + 2; i += 2) {
> data.ctx.s.P[i] ^= data.expanded_key[i];
> data.ctx.s.P[i + 1] ^= data.expanded_key[i + 1];
> }
>
> done = 0;
> do {
> BF_encrypt(&data.ctx, 0, 0,
> &data.ctx.PS[0],
> &data.ctx.PS[BF_N + 2 + 4 * 0x100]);
>
> if (done)
> break;
> done = 1;
>
> {
> BF_word tmp1, tmp2, tmp3, tmp4;
>
> tmp1 = data.binary.salt[0];
> tmp2 = data.binary.salt[1];
> tmp3 = data.binary.salt[2];
> tmp4 = data.binary.salt[3];
> for (i = 0; i < BF_N; i += 4) {
> data.ctx.s.P[i] ^= tmp1;
> data.ctx.s.P[i + 1] ^= tmp2;
> data.ctx.s.P[i + 2] ^= tmp3;
> data.ctx.s.P[i + 3] ^= tmp4;
> }
> data.ctx.s.P[16] ^= tmp1;
> data.ctx.s.P[17] ^= tmp2;
> }
> } while (1);
i like for better
for (done = 0; ; done++) {
...
if (done)
break;
...
}
> count = 64;
> do {
> L = BF_encrypt(&data.ctx, L, LR[1],
> &LR[0], &LR[0]);
> } while (--count);
for (count = 0; count < 64; count++)
i assume it will be optimized to the same thing
(count is not used later)
> output[7 + 22 - 1] = BF_itoa64[(int)
> BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
is setting[28] range checked at this point?
the int casts do not help
> _crypt_output_magic(setting, output, size);
> retval = BF_crypt(key, setting, output, size, 16);
> save_errno = errno;
why save errno before the self test?
if the self test fails then errno can be anything anyway
if it does not fail then errno is unchanged i guess
> memcpy(buf.s, test_setting, sizeof(buf.s));
sizeof buf.s
without ()
> memset(buf.o, 0x55, sizeof(buf.o));
> buf.o[sizeof(buf.o) - 1] = 0;
> p = BF_crypt(test_key, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1);
ditto
i'd write (1 + 1) as 2
> test_hash[(unsigned int)(unsigned char)buf.s[2] & 1],
the extra (unsigned int) cast is unnecessary
next prev parent reply other threads:[~2012-08-09 11:58 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-21 15:23 Łukasz Sowa
2012-07-21 17:11 ` Solar Designer
2012-07-21 20:17 ` Rich Felker
2012-07-22 16:23 ` Łukasz Sowa
2012-07-25 7:57 ` Rich Felker
2012-08-08 2:24 ` Rich Felker
2012-08-08 4:42 ` Solar Designer
2012-08-08 5:28 ` Rich Felker
2012-08-08 6:27 ` Solar Designer
2012-08-08 7:03 ` Daniel Cegiełka
2012-08-08 7:24 ` Solar Designer
2012-08-08 7:42 ` Daniel Cegiełka
2012-08-08 21:48 ` Rich Felker
2012-08-08 23:08 ` Isaac Dunham
2012-08-08 23:24 ` John Spencer
2012-08-09 1:03 ` Isaac Dunham
2012-08-09 3:16 ` Rich Felker
2012-08-09 3:36 ` Solar Designer
2012-08-09 7:13 ` orc
2012-08-09 7:28 ` Rich Felker
2012-08-09 7:29 ` Solar Designer
2012-08-09 10:53 ` Solar Designer
2012-08-09 11:58 ` Szabolcs Nagy [this message]
2012-08-09 16:43 ` Solar Designer
2012-08-09 17:30 ` Szabolcs Nagy
2012-08-09 18:22 ` Rich Felker
2012-08-09 23:21 ` Rich Felker
2012-08-10 17:04 ` Solar Designer
2012-08-10 18:06 ` Rich Felker
2012-08-09 21:46 ` crypt_blowfish integration, optimization Rich Felker
2012-08-09 22:21 ` Solar Designer
2012-08-09 22:32 ` Rich Felker
2012-08-10 17:18 ` Solar Designer
2012-08-10 18:08 ` Rich Felker
2012-08-10 22:52 ` Solar Designer
2012-08-08 7:52 ` crypt* files in crypt directory Szabolcs Nagy
2012-08-08 13:06 ` Rich Felker
2012-08-08 14:30 ` orc
2012-08-08 14:53 ` Szabolcs Nagy
2012-08-08 15:05 ` orc
2012-08-08 18:10 ` Rich Felker
2012-08-09 1:51 ` Solar Designer
2012-08-09 3:25 ` Rich Felker
2012-08-09 4:04 ` Solar Designer
2012-08-09 5:48 ` Rich Felker
2012-08-09 15:52 ` Solar Designer
2012-08-09 17:59 ` Rich Felker
2012-08-09 21:17 ` Rich Felker
2012-08-09 21:44 ` Solar Designer
2012-08-09 22:08 ` Rich Felker
2012-08-09 23:33 ` Rich Felker
2012-08-09 6:03 ` Rich Felker
-- strict thread matches above, loose matches on Subject: below --
2012-07-17 9:40 Daniel Cegiełka
2012-07-17 17:51 ` Rich Felker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120809115811.GA32316@port70.net \
--to=nsz@port70.net \
--cc=musl@lists.openwall.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).