Back to index

php5  5.3.10
crypt_blowfish.c
Go to the documentation of this file.
00001 /* $Id: crypt_blowfish.c 313406 2011-07-18 21:26:29Z pajoye $ */
00002 /*
00003  * The crypt_blowfish homepage is:
00004  *
00005  *     http://www.openwall.com/crypt/
00006  *
00007  * This code comes from John the Ripper password cracker, with reentrant
00008  * and crypt(3) interfaces added, but optimizations specific to password
00009  * cracking removed.
00010  *
00011  * Written by Solar Designer <solar at openwall.com> in 1998-2011.
00012  * No copyright is claimed, and the software is hereby placed in the public
00013  * domain. In case this attempt to disclaim copyright and place the software
00014  * in the public domain is deemed null and void, then the software is
00015  * Copyright (c) 1998-2011 Solar Designer and it is hereby released to the
00016  * general public under the following terms:
00017  *
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted.
00020  *
00021  * There's ABSOLUTELY NO WARRANTY, express or implied.
00022  *
00023  * It is my intent that you should be able to use this on your system,
00024  * as part of a software package, or anywhere else to improve security,
00025  * ensure compatibility, or for any other purpose. I would appreciate
00026  * it if you give credit where it is due and keep your modifications in
00027  * the public domain as well, but I don't require that in order to let
00028  * you place this code and any modifications you make under a license
00029  * of your choice.
00030  *
00031  * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
00032  * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
00033  * ideas. The password hashing algorithm was designed by David Mazieres
00034  * <dm at lcs.mit.edu>. For more information on the level of compatibility,
00035  * please refer to the comments in BF_set_key() below and to the crypt(3)
00036  * man page included in the crypt_blowfish tarball.
00037  *
00038  * There's a paper on the algorithm that explains its design decisions:
00039  *
00040  *     http://www.usenix.org/events/usenix99/provos.html
00041  *
00042  * Some of the tricks in BF_ROUND might be inspired by Eric Young's
00043  * Blowfish library (I can't be sure if I would think of something if I
00044  * hadn't seen his code).
00045  */
00046 
00047 #include <string.h>
00048 
00049 #include <errno.h>
00050 #ifndef __set_errno
00051 #define __set_errno(val) errno = (val)
00052 #endif
00053 
00054 /* Just to make sure the prototypes match the actual definitions */
00055 #include "crypt_blowfish.h"
00056 
00057 #ifdef __i386__
00058 #define BF_ASM                            0
00059 #define BF_SCALE                   1
00060 #elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
00061 #define BF_ASM                            0
00062 #define BF_SCALE                   1
00063 #else
00064 #define BF_ASM                            0
00065 #define BF_SCALE                   0
00066 #endif
00067 
00068 typedef unsigned int BF_word;
00069 typedef signed int BF_word_signed;
00070 
00071 /* Number of Blowfish rounds, this is also hardcoded into a few places */
00072 #define BF_N                       16
00073 
00074 typedef BF_word BF_key[BF_N + 2];
00075 
00076 typedef struct {
00077        BF_word S[4][0x100];
00078        BF_key P;
00079 } BF_ctx;
00080 
00081 /*
00082  * Magic IV for 64 Blowfish encryptions that we do at the end.
00083  * The string is "OrpheanBeholderScryDoubt" on big-endian.
00084  */
00085 static BF_word BF_magic_w[6] = {
00086        0x4F727068, 0x65616E42, 0x65686F6C,
00087        0x64657253, 0x63727944, 0x6F756274
00088 };
00089 
00090 /*
00091  * P-box and S-box tables initialized with digits of Pi.
00092  */
00093 static BF_ctx BF_init_state = {
00094        {
00095               {
00096                      0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
00097                      0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
00098                      0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
00099                      0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
00100                      0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
00101                      0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
00102                      0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
00103                      0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
00104                      0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
00105                      0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
00106                      0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
00107                      0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
00108                      0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
00109                      0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
00110                      0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
00111                      0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
00112                      0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
00113                      0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
00114                      0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
00115                      0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
00116                      0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
00117                      0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
00118                      0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
00119                      0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
00120                      0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
00121                      0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
00122                      0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
00123                      0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
00124                      0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
00125                      0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
00126                      0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
00127                      0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
00128                      0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
00129                      0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
00130                      0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
00131                      0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
00132                      0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
00133                      0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
00134                      0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
00135                      0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
00136                      0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
00137                      0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
00138                      0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
00139                      0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
00140                      0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
00141                      0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
00142                      0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
00143                      0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
00144                      0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
00145                      0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
00146                      0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
00147                      0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
00148                      0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
00149                      0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
00150                      0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
00151                      0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
00152                      0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
00153                      0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
00154                      0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
00155                      0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
00156                      0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
00157                      0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
00158                      0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
00159                      0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
00160               }, {
00161                      0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
00162                      0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
00163                      0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
00164                      0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
00165                      0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
00166                      0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
00167                      0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
00168                      0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
00169                      0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
00170                      0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
00171                      0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
00172                      0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
00173                      0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
00174                      0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
00175                      0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
00176                      0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
00177                      0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
00178                      0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
00179                      0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
00180                      0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
00181                      0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
00182                      0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
00183                      0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
00184                      0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
00185                      0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
00186                      0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
00187                      0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
00188                      0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
00189                      0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
00190                      0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
00191                      0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
00192                      0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
00193                      0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
00194                      0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
00195                      0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
00196                      0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
00197                      0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
00198                      0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
00199                      0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
00200                      0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
00201                      0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
00202                      0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
00203                      0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
00204                      0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
00205                      0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
00206                      0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
00207                      0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
00208                      0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
00209                      0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
00210                      0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
00211                      0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
00212                      0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
00213                      0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
00214                      0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
00215                      0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
00216                      0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
00217                      0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
00218                      0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
00219                      0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
00220                      0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
00221                      0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
00222                      0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
00223                      0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
00224                      0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
00225               }, {
00226                      0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
00227                      0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
00228                      0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
00229                      0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
00230                      0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
00231                      0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
00232                      0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
00233                      0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
00234                      0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
00235                      0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
00236                      0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
00237                      0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
00238                      0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
00239                      0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
00240                      0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
00241                      0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
00242                      0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
00243                      0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
00244                      0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
00245                      0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
00246                      0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
00247                      0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
00248                      0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
00249                      0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
00250                      0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
00251                      0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
00252                      0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
00253                      0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
00254                      0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
00255                      0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
00256                      0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
00257                      0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
00258                      0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
00259                      0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
00260                      0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
00261                      0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
00262                      0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
00263                      0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
00264                      0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
00265                      0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
00266                      0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
00267                      0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
00268                      0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
00269                      0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
00270                      0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
00271                      0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
00272                      0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
00273                      0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
00274                      0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
00275                      0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
00276                      0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
00277                      0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
00278                      0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
00279                      0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
00280                      0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
00281                      0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
00282                      0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
00283                      0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
00284                      0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
00285                      0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
00286                      0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
00287                      0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
00288                      0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
00289                      0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
00290               }, {
00291                      0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
00292                      0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
00293                      0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
00294                      0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
00295                      0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
00296                      0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
00297                      0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
00298                      0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
00299                      0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
00300                      0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
00301                      0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
00302                      0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
00303                      0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
00304                      0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
00305                      0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
00306                      0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
00307                      0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
00308                      0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
00309                      0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
00310                      0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
00311                      0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
00312                      0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
00313                      0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
00314                      0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
00315                      0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
00316                      0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
00317                      0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
00318                      0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
00319                      0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
00320                      0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
00321                      0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
00322                      0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
00323                      0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
00324                      0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
00325                      0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
00326                      0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
00327                      0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
00328                      0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
00329                      0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
00330                      0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
00331                      0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
00332                      0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
00333                      0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
00334                      0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
00335                      0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
00336                      0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
00337                      0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
00338                      0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
00339                      0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
00340                      0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
00341                      0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
00342                      0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
00343                      0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
00344                      0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
00345                      0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
00346                      0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
00347                      0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
00348                      0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
00349                      0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
00350                      0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
00351                      0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
00352                      0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
00353                      0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
00354                      0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
00355               }
00356        }, {
00357               0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
00358               0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
00359               0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
00360               0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
00361               0x9216d5d9, 0x8979fb1b
00362        }
00363 };
00364 
00365 static unsigned char BF_itoa64[64 + 1] =
00366        "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
00367 
00368 static unsigned char BF_atoi64[0x60] = {
00369        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
00370        54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
00371        64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
00372        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
00373        64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
00374        43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
00375 };
00376 
00377 #define BF_safe_atoi64(dst, src) \
00378 { \
00379        tmp = (unsigned char)(src); \
00380        if (tmp == '$') break; /* PHP hack */ \
00381        if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
00382        tmp = BF_atoi64[tmp]; \
00383        if (tmp > 63) return -1; \
00384        (dst) = tmp; \
00385 }
00386 
00387 static int BF_decode(BF_word *dst, const char *src, int size)
00388 {
00389        unsigned char *dptr = (unsigned char *)dst;
00390        unsigned char *end = dptr + size;
00391        const unsigned char *sptr = (const unsigned char *)src;
00392        unsigned int tmp, c1, c2, c3, c4;
00393 
00394        do {
00395               BF_safe_atoi64(c1, *sptr++);
00396               BF_safe_atoi64(c2, *sptr++);
00397               *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
00398               if (dptr >= end) break;
00399 
00400               BF_safe_atoi64(c3, *sptr++);
00401               *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
00402               if (dptr >= end) break;
00403 
00404               BF_safe_atoi64(c4, *sptr++);
00405               *dptr++ = ((c3 & 0x03) << 6) | c4;
00406        } while (dptr < end);
00407 
00408        while (dptr < end) /* PHP hack */
00409               *dptr++ = 0;
00410 
00411        return 0;
00412 }
00413 
00414 static void BF_encode(char *dst, const BF_word *src, int size)
00415 {
00416        const unsigned char *sptr = (const unsigned char *)src;
00417        const unsigned char *end = sptr + size;
00418        unsigned char *dptr = (unsigned char *)dst;
00419        unsigned int c1, c2;
00420 
00421        do {
00422               c1 = *sptr++;
00423               *dptr++ = BF_itoa64[c1 >> 2];
00424               c1 = (c1 & 0x03) << 4;
00425               if (sptr >= end) {
00426                      *dptr++ = BF_itoa64[c1];
00427                      break;
00428               }
00429 
00430               c2 = *sptr++;
00431               c1 |= c2 >> 4;
00432               *dptr++ = BF_itoa64[c1];
00433               c1 = (c2 & 0x0f) << 2;
00434               if (sptr >= end) {
00435                      *dptr++ = BF_itoa64[c1];
00436                      break;
00437               }
00438 
00439               c2 = *sptr++;
00440               c1 |= c2 >> 6;
00441               *dptr++ = BF_itoa64[c1];
00442               *dptr++ = BF_itoa64[c2 & 0x3f];
00443        } while (sptr < end);
00444 }
00445 
00446 static void BF_swap(BF_word *x, int count)
00447 {
00448        static int endianness_check = 1;
00449        char *is_little_endian = (char *)&endianness_check;
00450        BF_word tmp;
00451 
00452        if (*is_little_endian)
00453        do {
00454               tmp = *x;
00455               tmp = (tmp << 16) | (tmp >> 16);
00456               *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
00457        } while (--count);
00458 }
00459 
00460 #if BF_SCALE
00461 /* Architectures which can shift addresses left by 2 bits with no extra cost */
00462 #define BF_ROUND(L, R, N) \
00463        tmp1 = L & 0xFF; \
00464        tmp2 = L >> 8; \
00465        tmp2 &= 0xFF; \
00466        tmp3 = L >> 16; \
00467        tmp3 &= 0xFF; \
00468        tmp4 = L >> 24; \
00469        tmp1 = data.ctx.S[3][tmp1]; \
00470        tmp2 = data.ctx.S[2][tmp2]; \
00471        tmp3 = data.ctx.S[1][tmp3]; \
00472        tmp3 += data.ctx.S[0][tmp4]; \
00473        tmp3 ^= tmp2; \
00474        R ^= data.ctx.P[N + 1]; \
00475        tmp3 += tmp1; \
00476        R ^= tmp3;
00477 #else
00478 /* Architectures with no complicated addressing modes supported */
00479 #define BF_INDEX(S, i) \
00480        (*((BF_word *)(((unsigned char *)S) + (i))))
00481 #define BF_ROUND(L, R, N) \
00482        tmp1 = L & 0xFF; \
00483        tmp1 <<= 2; \
00484        tmp2 = L >> 6; \
00485        tmp2 &= 0x3FC; \
00486        tmp3 = L >> 14; \
00487        tmp3 &= 0x3FC; \
00488        tmp4 = L >> 22; \
00489        tmp4 &= 0x3FC; \
00490        tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
00491        tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
00492        tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
00493        tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
00494        tmp3 ^= tmp2; \
00495        R ^= data.ctx.P[N + 1]; \
00496        tmp3 += tmp1; \
00497        R ^= tmp3;
00498 #endif
00499 
00500 /*
00501  * Encrypt one block, BF_N is hardcoded here.
00502  */
00503 #define BF_ENCRYPT \
00504        L ^= data.ctx.P[0]; \
00505        BF_ROUND(L, R, 0); \
00506        BF_ROUND(R, L, 1); \
00507        BF_ROUND(L, R, 2); \
00508        BF_ROUND(R, L, 3); \
00509        BF_ROUND(L, R, 4); \
00510        BF_ROUND(R, L, 5); \
00511        BF_ROUND(L, R, 6); \
00512        BF_ROUND(R, L, 7); \
00513        BF_ROUND(L, R, 8); \
00514        BF_ROUND(R, L, 9); \
00515        BF_ROUND(L, R, 10); \
00516        BF_ROUND(R, L, 11); \
00517        BF_ROUND(L, R, 12); \
00518        BF_ROUND(R, L, 13); \
00519        BF_ROUND(L, R, 14); \
00520        BF_ROUND(R, L, 15); \
00521        tmp4 = R; \
00522        R = L; \
00523        L = tmp4 ^ data.ctx.P[BF_N + 1];
00524 
00525 #if BF_ASM
00526 #define BF_body() \
00527        _BF_body_r(&data.ctx);
00528 #else
00529 #define BF_body() \
00530        L = R = 0; \
00531        ptr = data.ctx.P; \
00532        do { \
00533               ptr += 2; \
00534               BF_ENCRYPT; \
00535               *(ptr - 2) = L; \
00536               *(ptr - 1) = R; \
00537        } while (ptr < &data.ctx.P[BF_N + 2]); \
00538 \
00539        ptr = data.ctx.S[0]; \
00540        do { \
00541               ptr += 2; \
00542               BF_ENCRYPT; \
00543               *(ptr - 2) = L; \
00544               *(ptr - 1) = R; \
00545        } while (ptr < &data.ctx.S[3][0xFF]);
00546 #endif
00547 
00548 static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
00549     unsigned char flags)
00550 {
00551        const char *ptr = key;
00552        unsigned int bug, i, j;
00553        BF_word safety, sign, diff, tmp[2];
00554 
00555 /*
00556  * There was a sign extension bug in older revisions of this function. While
00557  * we would have liked to simply fix the bug and move on, we have to provide
00558  * a backwards compatibility feature (essentially the bug) for some systems and
00559  * a safety measure for some others. The latter is needed because for certain
00560  * multiple inputs to the buggy algorithm there exist easily found inputs to
00561  * the correct algorithm that produce the same hash. Thus, we optionally
00562  * deviate from the correct algorithm just enough to avoid such collisions.
00563  * While the bug itself affected the majority of passwords containing
00564  * characters with the 8th bit set (although only a percentage of those in a
00565  * collision-producing way), the anti-collision safety measure affects
00566  * only a subset of passwords containing the '\xff' character (not even all of
00567  * those passwords, just some of them). This character is not found in valid
00568  * UTF-8 sequences and is rarely used in popular 8-bit character encodings.
00569  * Thus, the safety measure is unlikely to cause much annoyance, and is a
00570  * reasonable tradeoff to use when authenticating against existing hashes that
00571  * are not reliably known to have been computed with the correct algorithm.
00572  *
00573  * We use an approach that tries to minimize side-channel leaks of password
00574  * information - that is, we mostly use fixed-cost bitwise operations instead
00575  * of branches or table lookups. (One conditional branch based on password
00576  * length remains. It is not part of the bug aftermath, though, and is
00577  * difficult and possibly unreasonable to avoid given the use of C strings by
00578  * the caller, which results in similar timing leaks anyway.)
00579  *
00580  * For actual implementation, we set an array index in the variable "bug"
00581  * (0 means no bug, 1 means sign extension bug emulation) and a flag in the
00582  * variable "safety" (bit 16 is set when the safety measure is requested).
00583  * Valid combinations of settings are:
00584  *
00585  * Prefix "$2a$": bug = 0, safety = 0x10000
00586  * Prefix "$2x$": bug = 1, safety = 0
00587  * Prefix "$2y$": bug = 0, safety = 0
00588  */
00589        bug = (unsigned int)flags & 1;
00590        safety = ((BF_word)flags & 2) << 15;
00591 
00592        sign = diff = 0;
00593 
00594        for (i = 0; i < BF_N + 2; i++) {
00595               tmp[0] = tmp[1] = 0;
00596               for (j = 0; j < 4; j++) {
00597                      tmp[0] <<= 8;
00598                      tmp[0] |= (unsigned char)*ptr; /* correct */
00599                      tmp[1] <<= 8;
00600                      tmp[1] |= (BF_word_signed)(signed char)*ptr; /* bug */
00601 /*
00602  * Sign extension in the first char has no effect - nothing to overwrite yet,
00603  * and those extra 24 bits will be fully shifted out of the 32-bit word. For
00604  * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
00605  * extension in tmp[1] occurs. Once this flag is set, it remains set.
00606  */
00607                      if (j)
00608                             sign |= tmp[1] & 0x80;
00609                      if (!*ptr)
00610                             ptr = key;
00611                      else
00612                             ptr++;
00613               }
00614               diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
00615 
00616               expanded[i] = tmp[bug];
00617               initial[i] = BF_init_state.P[i] ^ tmp[bug];
00618        }
00619 
00620 /*
00621  * At this point, "diff" is zero iff the correct and buggy algorithms produced
00622  * exactly the same result. If so and if "sign" is non-zero, which indicates
00623  * that there was a non-benign sign extension, this means that we have a
00624  * collision between the correctly computed hash for this password and a set of
00625  * passwords that could be supplied to the buggy algorithm. Our safety measure
00626  * is meant to protect from such many-buggy to one-correct collisions, by
00627  * deviating from the correct algorithm in such cases. Let's check for this.
00628  */
00629        diff |= diff >> 16; /* still zero iff exact match */
00630        diff &= 0xffff; /* ditto */
00631        diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
00632        sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
00633        sign &= ~diff & safety; /* action needed? */
00634 
00635 /*
00636  * If we have determined that we need to deviate from the correct algorithm,
00637  * flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but
00638  * let's stick to it now. It came out of the approach we used above, and it's
00639  * not any worse than any other choice we could make.)
00640  *
00641  * It is crucial that we don't do the same to the expanded key used in the main
00642  * Eksblowfish loop. By doing it to only one of these two, we deviate from a
00643  * state that could be directly specified by a password to the buggy algorithm
00644  * (and to the fully correct one as well, but that's a side-effect).
00645  */
00646        initial[0] ^= sign;
00647 }
00648 
00649 static char *BF_crypt(const char *key, const char *setting,
00650        char *output, int size,
00651        BF_word min)
00652 {
00653 #if BF_ASM
00654        extern void _BF_body_r(BF_ctx *ctx);
00655 #endif
00656        static const unsigned char flags_by_subtype[26] =
00657               {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00658               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
00659        struct {
00660               BF_ctx ctx;
00661               BF_key expanded_key;
00662               union {
00663                      BF_word salt[4];
00664                      BF_word output[6];
00665               } binary;
00666        } data;
00667        BF_word L, R;
00668        BF_word tmp1, tmp2, tmp3, tmp4;
00669        BF_word *ptr;
00670        BF_word count;
00671        int i;
00672 
00673        if (size < 7 + 22 + 31 + 1) {
00674               __set_errno(ERANGE);
00675               return NULL;
00676        }
00677 
00678        if (setting[0] != '$' ||
00679            setting[1] != '2' ||
00680            setting[2] < 'a' || setting[2] > 'z' ||
00681            !flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] ||
00682            setting[3] != '$' ||
00683            setting[4] < '0' || setting[4] > '3' ||
00684            setting[5] < '0' || setting[5] > '9' ||
00685            (setting[4] == '3' && setting[5] > '1') ||
00686            setting[6] != '$') {
00687               __set_errno(EINVAL);
00688               return NULL;
00689        }
00690 
00691        count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
00692        if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
00693               __set_errno(EINVAL);
00694               return NULL;
00695        }
00696        BF_swap(data.binary.salt, 4);
00697 
00698        BF_set_key(key, data.expanded_key, data.ctx.P,
00699            flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a']);
00700 
00701        memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
00702 
00703        L = R = 0;
00704        for (i = 0; i < BF_N + 2; i += 2) {
00705               L ^= data.binary.salt[i & 2];
00706               R ^= data.binary.salt[(i & 2) + 1];
00707               BF_ENCRYPT;
00708               data.ctx.P[i] = L;
00709               data.ctx.P[i + 1] = R;
00710        }
00711 
00712        ptr = data.ctx.S[0];
00713        do {
00714               ptr += 4;
00715               L ^= data.binary.salt[(BF_N + 2) & 3];
00716               R ^= data.binary.salt[(BF_N + 3) & 3];
00717               BF_ENCRYPT;
00718               *(ptr - 4) = L;
00719               *(ptr - 3) = R;
00720 
00721               L ^= data.binary.salt[(BF_N + 4) & 3];
00722               R ^= data.binary.salt[(BF_N + 5) & 3];
00723               BF_ENCRYPT;
00724               *(ptr - 2) = L;
00725               *(ptr - 1) = R;
00726        } while (ptr < &data.ctx.S[3][0xFF]);
00727 
00728        do {
00729               int done;
00730 
00731               for (i = 0; i < BF_N + 2; i += 2) {
00732                      data.ctx.P[i] ^= data.expanded_key[i];
00733                      data.ctx.P[i + 1] ^= data.expanded_key[i + 1];
00734               }
00735 
00736               done = 0;
00737               do {
00738                      BF_body();
00739                      if (done)
00740                             break;
00741                      done = 1;
00742 
00743                      tmp1 = data.binary.salt[0];
00744                      tmp2 = data.binary.salt[1];
00745                      tmp3 = data.binary.salt[2];
00746                      tmp4 = data.binary.salt[3];
00747                      for (i = 0; i < BF_N; i += 4) {
00748                             data.ctx.P[i] ^= tmp1;
00749                             data.ctx.P[i + 1] ^= tmp2;
00750                             data.ctx.P[i + 2] ^= tmp3;
00751                             data.ctx.P[i + 3] ^= tmp4;
00752                      }
00753                      data.ctx.P[16] ^= tmp1;
00754                      data.ctx.P[17] ^= tmp2;
00755               } while (1);
00756        } while (--count);
00757 
00758        for (i = 0; i < 6; i += 2) {
00759               L = BF_magic_w[i];
00760               R = BF_magic_w[i + 1];
00761 
00762               count = 64;
00763               do {
00764                      BF_ENCRYPT;
00765               } while (--count);
00766 
00767               data.binary.output[i] = L;
00768               data.binary.output[i + 1] = R;
00769        }
00770 
00771        memcpy(output, setting, 7 + 22 - 1);
00772        output[7 + 22 - 1] = BF_itoa64[(int)
00773               BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
00774 
00775 /* This has to be bug-compatible with the original implementation, so
00776  * only encode 23 of the 24 bytes. :-) */
00777        BF_swap(data.binary.output, 6);
00778        BF_encode(&output[7 + 22], data.binary.output, 23);
00779        output[7 + 22 + 31] = '\0';
00780 
00781        return output;
00782 }
00783 
00784 static int _crypt_output_magic(const char *setting, char *output, int size)
00785 {
00786        if (size < 3)
00787               return -1;
00788 
00789        output[0] = '*';
00790        output[1] = '0';
00791        output[2] = '\0';
00792 
00793        if (setting[0] == '*' && setting[1] == '0')
00794               output[1] = '1';
00795 
00796        return 0;
00797 }
00798 
00799 /*
00800  * Please preserve the runtime self-test. It serves two purposes at once:
00801  *
00802  * 1. We really can't afford the risk of producing incompatible hashes e.g.
00803  * when there's something like gcc bug 26587 again, whereas an application or
00804  * library integrating this code might not also integrate our external tests or
00805  * it might not run them after every build. Even if it does, the miscompile
00806  * might only occur on the production build, but not on a testing build (such
00807  * as because of different optimization settings). It is painful to recover
00808  * from incorrectly-computed hashes - merely fixing whatever broke is not
00809  * enough. Thus, a proactive measure like this self-test is needed.
00810  *
00811  * 2. We don't want to leave sensitive data from our actual password hash
00812  * computation on the stack or in registers. Previous revisions of the code
00813  * would do explicit cleanups, but simply running the self-test after hash
00814  * computation is more reliable.
00815  *
00816  * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
00817  * setting.
00818  */
00819 char *php_crypt_blowfish_rn(const char *key, const char *setting,
00820        char *output, int size)
00821 {
00822        const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
00823        const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
00824        static const char * const test_hash[2] =
00825               {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
00826               "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
00827        char *retval;
00828        const char *p;
00829        int save_errno, ok;
00830        struct {
00831               char s[7 + 22 + 1];
00832               char o[7 + 22 + 31 + 1 + 1 + 1];
00833        } buf;
00834 
00835 /* Hash the supplied password */
00836        _crypt_output_magic(setting, output, size);
00837        retval = BF_crypt(key, setting, output, size, 16);
00838        save_errno = errno;
00839 
00840 /*
00841  * Do a quick self-test. It is important that we make both calls to BF_crypt()
00842  * from the same scope such that they likely use the same stack locations,
00843  * which makes the second call overwrite the first call's sensitive data on the
00844  * stack and makes it more likely that any alignment related issues would be
00845  * detected by the self-test.
00846  */
00847        memcpy(buf.s, test_setting, sizeof(buf.s));
00848        if (retval)
00849               buf.s[2] = setting[2];
00850        memset(buf.o, 0x55, sizeof(buf.o));
00851        buf.o[sizeof(buf.o) - 1] = 0;
00852        p = BF_crypt(test_key, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1);
00853 
00854        ok = (p == buf.o &&
00855            !memcmp(p, buf.s, 7 + 22) &&
00856            !memcmp(p + (7 + 22),
00857            test_hash[(unsigned int)(unsigned char)buf.s[2] & 1],
00858            31 + 1 + 1 + 1));
00859 
00860        {
00861               const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
00862               BF_key ae, ai, ye, yi;
00863               BF_set_key(k, ae, ai, 2); /* $2a$ */
00864               BF_set_key(k, ye, yi, 4); /* $2y$ */
00865               ai[0] ^= 0x10000; /* undo the safety (for comparison) */
00866               ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
00867                   !memcmp(ae, ye, sizeof(ae)) &&
00868                   !memcmp(ai, yi, sizeof(ai));
00869        }
00870 
00871        __set_errno(save_errno);
00872        if (ok)
00873               return retval;
00874 
00875 /* Should not happen */
00876        _crypt_output_magic(setting, output, size);
00877        __set_errno(EINVAL); /* pretend we don't support this hash type */
00878        return NULL;
00879 }
00880 
00881 #if 0
00882 char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
00883        const char *input, int size, char *output, int output_size)
00884 {
00885        if (size < 16 || output_size < 7 + 22 + 1 ||
00886            (count && (count < 4 || count > 31)) ||
00887            prefix[0] != '$' || prefix[1] != '2' ||
00888            (prefix[2] != 'a' && prefix[2] != 'y')) {
00889               if (output_size > 0) output[0] = '\0';
00890               __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
00891               return NULL;
00892        }
00893 
00894        if (!count) count = 5;
00895 
00896        output[0] = '$';
00897        output[1] = '2';
00898        output[2] = prefix[2];
00899        output[3] = '$';
00900        output[4] = '0' + count / 10;
00901        output[5] = '0' + count % 10;
00902        output[6] = '$';
00903 
00904        BF_encode(&output[7], (const BF_word *)input, 16);
00905        output[7 + 22] = '\0';
00906 
00907        return output;
00908 }
00909 #endif