From b9bb8f67bbac9bab5314fb00974ad469476e936e Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 7 Sep 2012 00:48:25 -0400 Subject: cleanup src/linux and src/misc trees, etc. previously, it was pretty much random which one of these trees a given function appeared in. they have now been organized into: src/linux: non-POSIX linux syscalls (possibly shard with other nixen) src/legacy: various obsolete/legacy functions, mostly wrappers src/misc: still mostly uncategorized; some misc POSIX, some nonstd src/crypt: crypt hash functions further cleanup will be done later. --- src/crypt/crypt.c | 11 + src/crypt/crypt_blowfish.c | 798 ++++++++++++++++++++++++++++++++ src/crypt/crypt_des.c | 1021 +++++++++++++++++++++++++++++++++++++++++ src/crypt/crypt_r.c | 30 ++ src/crypt/crypt_sha256.c | 322 +++++++++++++ src/crypt/crypt_sha512.c | 371 +++++++++++++++ src/legacy/cuserid.c | 14 + src/legacy/daemon.c | 33 ++ src/legacy/err.c | 60 +++ src/legacy/ftw.c | 12 + src/legacy/futimes.c | 13 + src/legacy/getdtablesize.c | 9 + src/legacy/getpagesize.c | 7 + src/legacy/getpass.c | 39 ++ src/legacy/getusershell.c | 33 ++ src/legacy/isastream.c | 7 + src/legacy/lutimes.c | 13 + src/legacy/ulimit.c | 19 + src/legacy/utmpx.c | 43 ++ src/linux/daemon.c | 33 -- src/linux/epoll.c | 27 ++ src/linux/epoll_create.c | 7 - src/linux/epoll_create1.c | 7 - src/linux/epoll_ctl.c | 7 - src/linux/epoll_pwait.c | 7 - src/linux/epoll_wait.c | 7 - src/linux/err.c | 60 --- src/linux/eventfd.c | 11 + src/linux/eventfd_read.c | 7 - src/linux/eventfd_write.c | 7 - src/linux/getdtablesize.c | 9 - src/linux/gethostid.c | 4 - src/linux/getopt_long.c | 52 --- src/linux/getpagesize.c | 7 - src/linux/getpass.c | 39 -- src/linux/initgroups.c | 15 - src/linux/inotify.c | 21 + src/linux/inotify_add_watch.c | 7 - src/linux/inotify_init.c | 7 - src/linux/inotify_init1.c | 7 - src/linux/inotify_rm_watch.c | 7 - src/linux/mntent.c | 68 --- src/linux/mount.c | 10 + src/linux/prlimit.c | 8 + src/linux/ptrace.c | 25 + src/linux/swap.c | 12 + src/linux/swapoff.c | 7 - src/linux/swapon.c | 7 - src/linux/syscall.c | 19 - src/linux/umount.c | 7 - src/linux/umount2.c | 7 - src/misc/crypt.c | 11 - src/misc/crypt_blowfish.c | 798 -------------------------------- src/misc/crypt_des.c | 1021 ----------------------------------------- src/misc/crypt_r.c | 30 -- src/misc/crypt_sha256.c | 322 ------------- src/misc/crypt_sha512.c | 371 --------------- src/misc/cuserid.c | 14 - src/misc/ftw.c | 12 - src/misc/futimes.c | 13 - src/misc/gethostid.c | 4 + src/misc/getopt_long.c | 52 +++ src/misc/getusershell.c | 33 -- src/misc/initgroups.c | 15 + src/misc/isastream.c | 7 - src/misc/lutimes.c | 13 - src/misc/mntent.c | 68 +++ src/misc/prlimit.c | 8 - src/misc/ptrace.c | 25 - src/misc/syscall.c | 19 + src/misc/ulimit.c | 19 - src/stub/utmpx.c | 43 -- 72 files changed, 3127 insertions(+), 3151 deletions(-) create mode 100644 src/crypt/crypt.c create mode 100644 src/crypt/crypt_blowfish.c create mode 100644 src/crypt/crypt_des.c create mode 100644 src/crypt/crypt_r.c create mode 100644 src/crypt/crypt_sha256.c create mode 100644 src/crypt/crypt_sha512.c create mode 100644 src/legacy/cuserid.c create mode 100644 src/legacy/daemon.c create mode 100644 src/legacy/err.c create mode 100644 src/legacy/ftw.c create mode 100644 src/legacy/futimes.c create mode 100644 src/legacy/getdtablesize.c create mode 100644 src/legacy/getpagesize.c create mode 100644 src/legacy/getpass.c create mode 100644 src/legacy/getusershell.c create mode 100644 src/legacy/isastream.c create mode 100644 src/legacy/lutimes.c create mode 100644 src/legacy/ulimit.c create mode 100644 src/legacy/utmpx.c delete mode 100644 src/linux/daemon.c create mode 100644 src/linux/epoll.c delete mode 100644 src/linux/epoll_create.c delete mode 100644 src/linux/epoll_create1.c delete mode 100644 src/linux/epoll_ctl.c delete mode 100644 src/linux/epoll_pwait.c delete mode 100644 src/linux/epoll_wait.c delete mode 100644 src/linux/err.c delete mode 100644 src/linux/eventfd_read.c delete mode 100644 src/linux/eventfd_write.c delete mode 100644 src/linux/getdtablesize.c delete mode 100644 src/linux/gethostid.c delete mode 100644 src/linux/getopt_long.c delete mode 100644 src/linux/getpagesize.c delete mode 100644 src/linux/getpass.c delete mode 100644 src/linux/initgroups.c create mode 100644 src/linux/inotify.c delete mode 100644 src/linux/inotify_add_watch.c delete mode 100644 src/linux/inotify_init.c delete mode 100644 src/linux/inotify_init1.c delete mode 100644 src/linux/inotify_rm_watch.c delete mode 100644 src/linux/mntent.c create mode 100644 src/linux/prlimit.c create mode 100644 src/linux/ptrace.c create mode 100644 src/linux/swap.c delete mode 100644 src/linux/swapoff.c delete mode 100644 src/linux/swapon.c delete mode 100644 src/linux/syscall.c delete mode 100644 src/linux/umount.c delete mode 100644 src/linux/umount2.c delete mode 100644 src/misc/crypt.c delete mode 100644 src/misc/crypt_blowfish.c delete mode 100644 src/misc/crypt_des.c delete mode 100644 src/misc/crypt_r.c delete mode 100644 src/misc/crypt_sha256.c delete mode 100644 src/misc/crypt_sha512.c delete mode 100644 src/misc/cuserid.c delete mode 100644 src/misc/ftw.c delete mode 100644 src/misc/futimes.c create mode 100644 src/misc/gethostid.c create mode 100644 src/misc/getopt_long.c delete mode 100644 src/misc/getusershell.c create mode 100644 src/misc/initgroups.c delete mode 100644 src/misc/isastream.c delete mode 100644 src/misc/lutimes.c create mode 100644 src/misc/mntent.c delete mode 100644 src/misc/prlimit.c delete mode 100644 src/misc/ptrace.c create mode 100644 src/misc/syscall.c delete mode 100644 src/misc/ulimit.c delete mode 100644 src/stub/utmpx.c (limited to 'src') diff --git a/src/crypt/crypt.c b/src/crypt/crypt.c new file mode 100644 index 00000000..f1e310f6 --- /dev/null +++ b/src/crypt/crypt.c @@ -0,0 +1,11 @@ +#include +#include + +char *__crypt_r(const char *, const char *, struct crypt_data *); + +char *crypt(const char *key, const char *salt) +{ + /* Note: update this size when we add more hash types */ + static char buf[128]; + return __crypt_r(key, salt, (struct crypt_data *)buf); +} diff --git a/src/crypt/crypt_blowfish.c b/src/crypt/crypt_blowfish.c new file mode 100644 index 00000000..bd37be84 --- /dev/null +++ b/src/crypt/crypt_blowfish.c @@ -0,0 +1,798 @@ +/* Modified by Rich Felker in for inclusion in musl libc, based on + * Solar Designer's second size-optimized version sent to the musl + * mailing list. */ + +/* + * The crypt_blowfish homepage is: + * + * http://www.openwall.com/crypt/ + * + * This code comes from John the Ripper password cracker, with reentrant + * and crypt(3) interfaces added, but optimizations specific to password + * cracking removed. + * + * Written by Solar Designer in 1998-2012. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * It is my intent that you should be able to use this on your system, + * as part of a software package, or anywhere else to improve security, + * ensure compatibility, or for any other purpose. I would appreciate + * it if you give credit where it is due and keep your modifications in + * the public domain as well, but I don't require that in order to let + * you place this code and any modifications you make under a license + * of your choice. + * + * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix + * "$2a$") by Niels Provos , and uses some of his + * ideas. The password hashing algorithm was designed by David Mazieres + * . For more information on the level of compatibility, + * please refer to the comments in BF_set_key() below and to the included + * crypt(3) man page. + * + * There's a paper on the algorithm that explains its design decisions: + * + * http://www.usenix.org/events/usenix99/provos.html + * + * Some of the tricks in BF_ROUND might be inspired by Eric Young's + * Blowfish library (I can't be sure if I would think of something if I + * hadn't seen his code). + */ + +#include +#include + +typedef uint32_t BF_word; +typedef int32_t 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]; + +typedef union { + struct { + BF_key P; + BF_word S[4][0x100]; + } s; + BF_word PS[BF_N + 2 + 4 * 0x100]; +} BF_ctx; + +/* + * Magic IV for 64 Blowfish encryptions that we do at the end. + * The string is "OrpheanBeholderScryDoubt" on big-endian. + */ +static const BF_word BF_magic_w[6] = { + 0x4F727068, 0x65616E42, 0x65686F6C, + 0x64657253, 0x63727944, 0x6F756274 +}; + +/* + * P-box and S-box tables initialized with digits of Pi. + */ +static const BF_ctx BF_init_state = {{ + { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b + }, { + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + }, { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + }, { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + }, { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + } + } +}}; + +static const unsigned char BF_itoa64[64 + 1] = + "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +static const unsigned char BF_atoi64[0x60] = { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, + 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, + 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 +}; + +#define BF_safe_atoi64(dst, src) \ +{ \ + tmp = (unsigned char)(src); \ + if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ + tmp = BF_atoi64[tmp]; \ + if (tmp > 63) return -1; \ + (dst) = tmp; \ +} + +static int BF_decode(BF_word *dst, const char *src, int size) +{ + unsigned char *dptr = (unsigned char *)dst; + unsigned char *end = dptr + size; + const unsigned char *sptr = (const unsigned char *)src; + unsigned int tmp, c1, c2, c3, c4; + + do { + BF_safe_atoi64(c1, *sptr++); + BF_safe_atoi64(c2, *sptr++); + *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); + if (dptr >= end) break; + + BF_safe_atoi64(c3, *sptr++); + *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); + if (dptr >= end) break; + + BF_safe_atoi64(c4, *sptr++); + *dptr++ = ((c3 & 0x03) << 6) | c4; + } while (dptr < end); + + return 0; +} + +static void BF_encode(char *dst, const BF_word *src, int size) +{ + const unsigned char *sptr = (const unsigned char *)src; + const unsigned char *end = sptr + size; + unsigned char *dptr = (unsigned char *)dst; + unsigned int c1, c2; + + do { + c1 = *sptr++; + *dptr++ = BF_itoa64[c1 >> 2]; + c1 = (c1 & 0x03) << 4; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 4; + *dptr++ = BF_itoa64[c1]; + c1 = (c2 & 0x0f) << 2; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 6; + *dptr++ = BF_itoa64[c1]; + *dptr++ = BF_itoa64[c2 & 0x3f]; + } while (sptr < end); +} + +static void BF_swap(BF_word *x, int count) +{ + if ((union { int i; char c; }){1}.c) + do { + BF_word tmp = *x; + tmp = (tmp << 16) | (tmp >> 16); + *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); + } while (--count); +} + +#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; + +static BF_word BF_encrypt(BF_ctx *ctx, + BF_word L, BF_word R, + BF_word *start, BF_word *end) +{ + BF_word tmp1, tmp2, tmp3, tmp4; + BF_word *ptr = start; + + do { + L ^= ctx->s.P[0]; +#if 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); +#else + for (int i=0; i<16; i+=2) { + BF_ROUND(L, R, i); + BF_ROUND(R, L, i+1); + } +#endif + tmp4 = R; + R = L; + L = tmp4 ^ ctx->s.P[BF_N + 1]; + *ptr++ = L; + *ptr++ = R; + } while (ptr < end); + + return L; +} + +static void BF_set_key(const char *key, BF_key expanded, BF_key initial, + unsigned char flags) +{ + const char *ptr = key; + unsigned int bug, i, j; + BF_word safety, sign, diff, tmp[2]; + +/* + * There was a sign extension bug in older revisions of this function. While + * we would have liked to simply fix the bug and move on, we have to provide + * a backwards compatibility feature (essentially the bug) for some systems and + * a safety measure for some others. The latter is needed because for certain + * multiple inputs to the buggy algorithm there exist easily found inputs to + * the correct algorithm that produce the same hash. Thus, we optionally + * deviate from the correct algorithm just enough to avoid such collisions. + * While the bug itself affected the majority of passwords containing + * characters with the 8th bit set (although only a percentage of those in a + * collision-producing way), the anti-collision safety measure affects + * only a subset of passwords containing the '\xff' character (not even all of + * those passwords, just some of them). This character is not found in valid + * UTF-8 sequences and is rarely used in popular 8-bit character encodings. + * Thus, the safety measure is unlikely to cause much annoyance, and is a + * reasonable tradeoff to use when authenticating against existing hashes that + * are not reliably known to have been computed with the correct algorithm. + * + * We use an approach that tries to minimize side-channel leaks of password + * information - that is, we mostly use fixed-cost bitwise operations instead + * of branches or table lookups. (One conditional branch based on password + * length remains. It is not part of the bug aftermath, though, and is + * difficult and possibly unreasonable to avoid given the use of C strings by + * the caller, which results in similar timing leaks anyway.) + * + * For actual implementation, we set an array index in the variable "bug" + * (0 means no bug, 1 means sign extension bug emulation) and a flag in the + * variable "safety" (bit 16 is set when the safety measure is requested). + * Valid combinations of settings are: + * + * Prefix "$2a$": bug = 0, safety = 0x10000 + * Prefix "$2x$": bug = 1, safety = 0 + * Prefix "$2y$": bug = 0, safety = 0 + */ + bug = flags & 1; + safety = ((BF_word)flags & 2) << 15; + + sign = diff = 0; + + for (i = 0; i < BF_N + 2; i++) { + tmp[0] = tmp[1] = 0; + for (j = 0; j < 4; j++) { + tmp[0] <<= 8; + tmp[0] |= (unsigned char)*ptr; /* correct */ + tmp[1] <<= 8; + tmp[1] |= (signed char)*ptr; /* bug */ +/* + * Sign extension in the first char has no effect - nothing to overwrite yet, + * and those extra 24 bits will be fully shifted out of the 32-bit word. For + * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign + * extension in tmp[1] occurs. Once this flag is set, it remains set. + */ + if (j) + sign |= tmp[1] & 0x80; + if (!*ptr) + ptr = key; + else + ptr++; + } + diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */ + + expanded[i] = tmp[bug]; + initial[i] = BF_init_state.s.P[i] ^ tmp[bug]; + } + +/* + * At this point, "diff" is zero iff the correct and buggy algorithms produced + * exactly the same result. If so and if "sign" is non-zero, which indicates + * that there was a non-benign sign extension, this means that we have a + * collision between the correctly computed hash for this password and a set of + * passwords that could be supplied to the buggy algorithm. Our safety measure + * is meant to protect from such many-buggy to one-correct collisions, by + * deviating from the correct algorithm in such cases. Let's check for this. + */ + diff |= diff >> 16; /* still zero iff exact match */ + diff &= 0xffff; /* ditto */ + diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */ + sign <<= 9; /* move the non-benign sign extension flag to bit 16 */ + sign &= ~diff & safety; /* action needed? */ + +/* + * If we have determined that we need to deviate from the correct algorithm, + * flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but + * let's stick to it now. It came out of the approach we used above, and it's + * not any worse than any other choice we could make.) + * + * It is crucial that we don't do the same to the expanded key used in the main + * Eksblowfish loop. By doing it to only one of these two, we deviate from a + * state that could be directly specified by a password to the buggy algorithm + * (and to the fully correct one as well, but that's a side-effect). + */ + initial[0] ^= sign; +} + +static char *BF_crypt(const char *key, const char *setting, + char *output, BF_word min) +{ + static const unsigned char flags_by_subtype[26] = + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0}; + struct { + BF_ctx ctx; + BF_key expanded_key; + union { + BF_word salt[4]; + BF_word output[6]; + } binary; + } data; + BF_word count; + int i; + + if (setting[0] != '$' || + setting[1] != '2' || + setting[2] - 'a' > 25U || + !flags_by_subtype[setting[2] - 'a'] || + setting[3] != '$' || + setting[4] - '0' > 1U || + setting[5] - '0' > 9U || + setting[6] != '$') { + return NULL; + } + + count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); + if (count < min || count > 2048 || BF_decode(data.binary.salt, &setting[7], 16)) { + return NULL; + } + BF_swap(data.binary.salt, 4); + + BF_set_key(key, data.expanded_key, data.ctx.s.P, + flags_by_subtype[setting[2] - 'a']); + + memcpy(data.ctx.s.S, BF_init_state.s.S, sizeof(data.ctx.s.S)); + + { + BF_word L = 0, R = 0; + BF_word *ptr = &data.ctx.PS[0]; + 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); + } + + 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); + } while (--count); + + for (i = 0; i < 6; i += 2) { + BF_word L, LR[2]; + + L = BF_magic_w[i]; + LR[1] = BF_magic_w[i + 1]; + + count = 64; + do { + L = BF_encrypt(&data.ctx, L, LR[1], + &LR[0], &LR[0]); + } while (--count); + + data.binary.output[i] = L; + data.binary.output[i + 1] = LR[1]; + } + + memcpy(output, setting, 7 + 22 - 1); + output[7 + 22 - 1] = BF_itoa64[ + BF_atoi64[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'; + + return output; +} + +/* + * Please preserve the runtime self-test. It serves two purposes at once: + * + * 1. We really can't afford the risk of producing incompatible hashes e.g. + * when there's something like gcc bug 26587 again, whereas an application or + * library integrating this code might not also integrate our external tests or + * it might not run them after every build. Even if it does, the miscompile + * might only occur on the production build, but not on a testing build (such + * as because of different optimization settings). It is painful to recover + * from incorrectly-computed hashes - merely fixing whatever broke is not + * enough. Thus, a proactive measure like this self-test is needed. + * + * 2. We don't want to leave sensitive data from our actual password hash + * computation on the stack or in registers. Previous revisions of the code + * would do explicit cleanups, but simply running the self-test after hash + * computation is more reliable. + * + * The performance cost of this quick self-test is around 0.6% at the "$2a$08" + * setting. + */ +char *__crypt_blowfish(const char *key, const char *setting, char *output) +{ + const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8"; + const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu"; + static const char test_hash[2][34] = + {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */ + "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */ + char *retval; + const char *p; + int ok; + struct { + char s[7 + 22 + 1]; + char o[7 + 22 + 31 + 1 + 1 + 1]; + } buf; + +/* Hash the supplied password */ + retval = BF_crypt(key, setting, output, 16); + +/* + * Do a quick self-test. It is important that we make both calls to BF_crypt() + * from the same scope such that they likely use the same stack locations, + * which makes the second call overwrite the first call's sensitive data on the + * stack and makes it more likely that any alignment related issues would be + * detected by the self-test. + */ + memcpy(buf.s, test_setting, sizeof(buf.s)); + if (retval) + buf.s[2] = setting[2]; + memset(buf.o, 0x55, sizeof(buf.o)); + buf.o[sizeof(buf.o) - 1] = 0; + p = BF_crypt(test_key, buf.s, buf.o, 1); + + ok = (p == buf.o && + !memcmp(p, buf.s, 7 + 22) && + !memcmp(p + (7 + 22), + test_hash[buf.s[2] & 1], + 31 + 1 + 1 + 1)); + + { + const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"; + BF_key ae, ai, ye, yi; + BF_set_key(k, ae, ai, 2); /* $2a$ */ + BF_set_key(k, ye, yi, 4); /* $2y$ */ + ai[0] ^= 0x10000; /* undo the safety (for comparison) */ + ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 && + !memcmp(ae, ye, sizeof(ae)) && + !memcmp(ai, yi, sizeof(ai)); + } + + if (ok && retval) + return retval; + + return "*"; +} diff --git a/src/crypt/crypt_des.c b/src/crypt/crypt_des.c new file mode 100644 index 00000000..d7b2b15a --- /dev/null +++ b/src/crypt/crypt_des.c @@ -0,0 +1,1021 @@ +/* + * This version has been further modified by Rich Felker, primary author + * and maintainer of musl libc, to remove table generation code and + * replaced all runtime-generated constant tables with static-initialized + * tables in the binary, in the interest of minimizing non-shareable + * memory usage and stack size requirements. + */ +/* + * This version is derived from the original implementation of FreeSec + * (release 1.1) by David Burren. I've made it reentrant, reduced its memory + * usage from about 70 KB to about 7 KB (with only minimal performance impact + * and keeping code size about the same), made the handling of invalid salts + * mostly UFC-crypt compatible, added a quick runtime self-test (which also + * serves to zeroize the stack from sensitive data), and added optional tests. + * - Solar Designer + */ + +/* + * FreeSec: libcrypt for NetBSD + * + * Copyright (c) 1994 David Burren + * Copyright (c) 2000,2002,2010,2012 Solar Designer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $ + * $Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp $ + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren. It has been heavily re-worked by Solar Designer. + */ + +#include +#include + +struct expanded_key { + uint32_t l[16], r[16]; +}; + +#define _PASSWORD_EFMT1 '_' + +static const unsigned char key_shifts[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +static const uint32_t psbox[8][64] = { + { + 0x00808200,0x00000000,0x00008000,0x00808202, + 0x00808002,0x00008202,0x00000002,0x00008000, + 0x00000200,0x00808200,0x00808202,0x00000200, + 0x00800202,0x00808002,0x00800000,0x00000002, + 0x00000202,0x00800200,0x00800200,0x00008200, + 0x00008200,0x00808000,0x00808000,0x00800202, + 0x00008002,0x00800002,0x00800002,0x00008002, + 0x00000000,0x00000202,0x00008202,0x00800000, + 0x00008000,0x00808202,0x00000002,0x00808000, + 0x00808200,0x00800000,0x00800000,0x00000200, + 0x00808002,0x00008000,0x00008200,0x00800002, + 0x00000200,0x00000002,0x00800202,0x00008202, + 0x00808202,0x00008002,0x00808000,0x00800202, + 0x00800002,0x00000202,0x00008202,0x00808200, + 0x00000202,0x00800200,0x00800200,0x00000000, + 0x00008002,0x00008200,0x00000000,0x00808002, + },{ + 0x40084010,0x40004000,0x00004000,0x00084010, + 0x00080000,0x00000010,0x40080010,0x40004010, + 0x40000010,0x40084010,0x40084000,0x40000000, + 0x40004000,0x00080000,0x00000010,0x40080010, + 0x00084000,0x00080010,0x40004010,0x00000000, + 0x40000000,0x00004000,0x00084010,0x40080000, + 0x00080010,0x40000010,0x00000000,0x00084000, + 0x00004010,0x40084000,0x40080000,0x00004010, + 0x00000000,0x00084010,0x40080010,0x00080000, + 0x40004010,0x40080000,0x40084000,0x00004000, + 0x40080000,0x40004000,0x00000010,0x40084010, + 0x00084010,0x00000010,0x00004000,0x40000000, + 0x00004010,0x40084000,0x00080000,0x40000010, + 0x00080010,0x40004010,0x40000010,0x00080010, + 0x00084000,0x00000000,0x40004000,0x00004010, + 0x40000000,0x40080010,0x40084010,0x00084000, + },{ + 0x00000104,0x04010100,0x00000000,0x04010004, + 0x04000100,0x00000000,0x00010104,0x04000100, + 0x00010004,0x04000004,0x04000004,0x00010000, + 0x04010104,0x00010004,0x04010000,0x00000104, + 0x04000000,0x00000004,0x04010100,0x00000100, + 0x00010100,0x04010000,0x04010004,0x00010104, + 0x04000104,0x00010100,0x00010000,0x04000104, + 0x00000004,0x04010104,0x00000100,0x04000000, + 0x04010100,0x04000000,0x00010004,0x00000104, + 0x00010000,0x04010100,0x04000100,0x00000000, + 0x00000100,0x00010004,0x04010104,0x04000100, + 0x04000004,0x00000100,0x00000000,0x04010004, + 0x04000104,0x00010000,0x04000000,0x04010104, + 0x00000004,0x00010104,0x00010100,0x04000004, + 0x04010000,0x04000104,0x00000104,0x04010000, + 0x00010104,0x00000004,0x04010004,0x00010100, + },{ + 0x80401000,0x80001040,0x80001040,0x00000040, + 0x00401040,0x80400040,0x80400000,0x80001000, + 0x00000000,0x00401000,0x00401000,0x80401040, + 0x80000040,0x00000000,0x00400040,0x80400000, + 0x80000000,0x00001000,0x00400000,0x80401000, + 0x00000040,0x00400000,0x80001000,0x00001040, + 0x80400040,0x80000000,0x00001040,0x00400040, + 0x00001000,0x00401040,0x80401040,0x80000040, + 0x00400040,0x80400000,0x00401000,0x80401040, + 0x80000040,0x00000000,0x00000000,0x00401000, + 0x00001040,0x00400040,0x80400040,0x80000000, + 0x80401000,0x80001040,0x80001040,0x00000040, + 0x80401040,0x80000040,0x80000000,0x00001000, + 0x80400000,0x80001000,0x00401040,0x80400040, + 0x80001000,0x00001040,0x00400000,0x80401000, + 0x00000040,0x00400000,0x00001000,0x00401040, + },{ + 0x00000080,0x01040080,0x01040000,0x21000080, + 0x00040000,0x00000080,0x20000000,0x01040000, + 0x20040080,0x00040000,0x01000080,0x20040080, + 0x21000080,0x21040000,0x00040080,0x20000000, + 0x01000000,0x20040000,0x20040000,0x00000000, + 0x20000080,0x21040080,0x21040080,0x01000080, + 0x21040000,0x20000080,0x00000000,0x21000000, + 0x01040080,0x01000000,0x21000000,0x00040080, + 0x00040000,0x21000080,0x00000080,0x01000000, + 0x20000000,0x01040000,0x21000080,0x20040080, + 0x01000080,0x20000000,0x21040000,0x01040080, + 0x20040080,0x00000080,0x01000000,0x21040000, + 0x21040080,0x00040080,0x21000000,0x21040080, + 0x01040000,0x00000000,0x20040000,0x21000000, + 0x00040080,0x01000080,0x20000080,0x00040000, + 0x00000000,0x20040000,0x01040080,0x20000080, + },{ + 0x10000008,0x10200000,0x00002000,0x10202008, + 0x10200000,0x00000008,0x10202008,0x00200000, + 0x10002000,0x00202008,0x00200000,0x10000008, + 0x00200008,0x10002000,0x10000000,0x00002008, + 0x00000000,0x00200008,0x10002008,0x00002000, + 0x00202000,0x10002008,0x00000008,0x10200008, + 0x10200008,0x00000000,0x00202008,0x10202000, + 0x00002008,0x00202000,0x10202000,0x10000000, + 0x10002000,0x00000008,0x10200008,0x00202000, + 0x10202008,0x00200000,0x00002008,0x10000008, + 0x00200000,0x10002000,0x10000000,0x00002008, + 0x10000008,0x10202008,0x00202000,0x10200000, + 0x00202008,0x10202000,0x00000000,0x10200008, + 0x00000008,0x00002000,0x10200000,0x00202008, + 0x00002000,0x00200008,0x10002008,0x00000000, + 0x10202000,0x10000000,0x00200008,0x10002008, + },{ + 0x00100000,0x02100001,0x02000401,0x00000000, + 0x00000400,0x02000401,0x00100401,0x02100400, + 0x02100401,0x00100000,0x00000000,0x02000001, + 0x00000001,0x02000000,0x02100001,0x00000401, + 0x02000400,0x00100401,0x00100001,0x02000400, + 0x02000001,0x02100000,0x02100400,0x00100001, + 0x02100000,0x00000400,0x00000401,0x02100401, + 0x00100400,0x00000001,0x02000000,0x00100400, + 0x02000000,0x00100400,0x00100000,0x02000401, + 0x02000401,0x02100001,0x02100001,0x00000001, + 0x00100001,0x02000000,0x02000400,0x00100000, + 0x02100400,0x00000401,0x00100401,0x02100400, + 0x00000401,0x02000001,0x02100401,0x02100000, + 0x00100400,0x00000000,0x00000001,0x02100401, + 0x00000000,0x00100401,0x02100000,0x00000400, + 0x02000001,0x02000400,0x00000400,0x00100001, + },{ + 0x08000820,0x00000800,0x00020000,0x08020820, + 0x08000000,0x08000820,0x00000020,0x08000000, + 0x00020020,0x08020000,0x08020820,0x00020800, + 0x08020800,0x00020820,0x00000800,0x00000020, + 0x08020000,0x08000020,0x08000800,0x00000820, + 0x00020800,0x00020020,0x08020020,0x08020800, + 0x00000820,0x00000000,0x00000000,0x08020020, + 0x08000020,0x08000800,0x00020820,0x00020000, + 0x00020820,0x00020000,0x08020800,0x00000800, + 0x00000020,0x08020020,0x00000800,0x00020820, + 0x08000800,0x00000020,0x08000020,0x08020000, + 0x08020020,0x08000000,0x00020000,0x08000820, + 0x00000000,0x08020820,0x00020020,0x08000020, + 0x08020000,0x08000800,0x08000820,0x00000000, + 0x08020820,0x00020800,0x00020800,0x00000820, + 0x00000820,0x00020020,0x08000000,0x08020800, + }, +}; +static const uint32_t ip_maskl[16][16] = { + { + 0x00000000,0x00010000,0x00000000,0x00010000, + 0x01000000,0x01010000,0x01000000,0x01010000, + 0x00000000,0x00010000,0x00000000,0x00010000, + 0x01000000,0x01010000,0x01000000,0x01010000, + },{ + 0x00000000,0x00000001,0x00000000,0x00000001, + 0x00000100,0x00000101,0x00000100,0x00000101, + 0x00000000,0x00000001,0x00000000,0x00000001, + 0x00000100,0x00000101,0x00000100,0x00000101, + },{ + 0x00000000,0x00020000,0x00000000,0x00020000, + 0x02000000,0x02020000,0x02000000,0x02020000, + 0x00000000,0x00020000,0x00000000,0x00020000, + 0x02000000,0x02020000,0x02000000,0x02020000, + },{ + 0x00000000,0x00000002,0x00000000,0x00000002, + 0x00000200,0x00000202,0x00000200,0x00000202, + 0x00000000,0x00000002,0x00000000,0x00000002, + 0x00000200,0x00000202,0x00000200,0x00000202, + },{ + 0x00000000,0x00040000,0x00000000,0x00040000, + 0x04000000,0x04040000,0x04000000,0x04040000, + 0x00000000,0x00040000,0x00000000,0x00040000, + 0x04000000,0x04040000,0x04000000,0x04040000, + },{ + 0x00000000,0x00000004,0x00000000,0x00000004, + 0x00000400,0x00000404,0x00000400,0x00000404, + 0x00000000,0x00000004,0x00000000,0x00000004, + 0x00000400,0x00000404,0x00000400,0x00000404, + },{ + 0x00000000,0x00080000,0x00000000,0x00080000, + 0x08000000,0x08080000,0x08000000,0x08080000, + 0x00000000,0x00080000,0x00000000,0x00080000, + 0x08000000,0x08080000,0x08000000,0x08080000, + },{ + 0x00000000,0x00000008,0x00000000,0x00000008, + 0x00000800,0x00000808,0x00000800,0x00000808, + 0x00000000,0x00000008,0x00000000,0x00000008, + 0x00000800,0x00000808,0x00000800,0x00000808, + },{ + 0x00000000,0x00100000,0x00000000,0x00100000, + 0x10000000,0x10100000,0x10000000,0x10100000, + 0x00000000,0x00100000,0x00000000,0x00100000, + 0x10000000,0x10100000,0x10000000,0x10100000, + },{ + 0x00000000,0x00000010,0x00000000,0x00000010, + 0x00001000,0x00001010,0x00001000,0x00001010, + 0x00000000,0x00000010,0x00000000,0x00000010, + 0x00001000,0x00001010,0x00001000,0x00001010, + },{ + 0x00000000,0x00200000,0x00000000,0x00200000, + 0x20000000,0x20200000,0x20000000,0x20200000, + 0x00000000,0x00200000,0x00000000,0x00200000, + 0x20000000,0x20200000,0x20000000,0x20200000, + },{ + 0x00000000,0x00000020,0x00000000,0x00000020, + 0x00002000,0x00002020,0x00002000,0x00002020, + 0x00000000,0x00000020,0x00000000,0x00000020, + 0x00002000,0x00002020,0x00002000,0x00002020, + },{ + 0x00000000,0x00400000,0x00000000,0x00400000, + 0x40000000,0x40400000,0x40000000,0x40400000, + 0x00000000,0x00400000,0x00000000,0x00400000, + 0x40000000,0x40400000,0x40000000,0x40400000, + },{ + 0x00000000,0x00000040,0x00000000,0x00000040, + 0x00004000,0x00004040,0x00004000,0x00004040, + 0x00000000,0x00000040,0x00000000,0x00000040, + 0x00004000,0x00004040,0x00004000,0x00004040, + },{ + 0x00000000,0x00800000,0x00000000,0x00800000, + 0x80000000,0x80800000,0x80000000,0x80800000, + 0x00000000,0x00800000,0x00000000,0x00800000, + 0x80000000,0x80800000,0x80000000,0x80800000, + },{ + 0x00000000,0x00000080,0x00000000,0x00000080, + 0x00008000,0x00008080,0x00008000,0x00008080, + 0x00000000,0x00000080,0x00000000,0x00000080, + 0x00008000,0x00008080,0x00008000,0x00008080, + }, +}; +static const uint32_t ip_maskr[16][16] = { + { + 0x00000000,0x00000000,0x00010000,0x00010000, + 0x00000000,0x00000000,0x00010000,0x00010000, + 0x01000000,0x01000000,0x01010000,0x01010000, + 0x01000000,0x01000000,0x01010000,0x01010000, + },{ + 0x00000000,0x00000000,0x00000001,0x00000001, + 0x00000000,0x00000000,0x00000001,0x00000001, + 0x00000100,0x00000100,0x00000101,0x00000101, + 0x00000100,0x00000100,0x00000101,0x00000101, + },{ + 0x00000000,0x00000000,0x00020000,0x00020000, + 0x00000000,0x00000000,0x00020000,0x00020000, + 0x02000000,0x02000000,0x02020000,0x02020000, + 0x02000000,0x02000000,0x02020000,0x02020000, + },{ + 0x00000000,0x00000000,0x00000002,0x00000002, + 0x00000000,0x00000000,0x00000002,0x00000002, + 0x00000200,0x00000200,0x00000202,0x00000202, + 0x00000200,0x00000200,0x00000202,0x00000202, + },{ + 0x00000000,0x00000000,0x00040000,0x00040000, + 0x00000000,0x00000000,0x00040000,0x00040000, + 0x04000000,0x04000000,0x04040000,0x04040000, + 0x04000000,0x04000000,0x04040000,0x04040000, + },{ + 0x00000000,0x00000000,0x00000004,0x00000004, + 0x00000000,0x00000000,0x00000004,0x00000004, + 0x00000400,0x00000400,0x00000404,0x00000404, + 0x00000400,0x00000400,0x00000404,0x00000404, + },{ + 0x00000000,0x00000000,0x00080000,0x00080000, + 0x00000000,0x00000000,0x00080000,0x00080000, + 0x08000000,0x08000000,0x08080000,0x08080000, + 0x08000000,0x08000000,0x08080000,0x08080000, + },{ + 0x00000000,0x00000000,0x00000008,0x00000008, + 0x00000000,0x00000000,0x00000008,0x00000008, + 0x00000800,0x00000800,0x00000808,0x00000808, + 0x00000800,0x00000800,0x00000808,0x00000808, + },{ + 0x00000000,0x00000000,0x00100000,0x00100000, + 0x00000000,0x00000000,0x00100000,0x00100000, + 0x10000000,0x10000000,0x10100000,0x10100000, + 0x10000000,0x10000000,0x10100000,0x10100000, + },{ + 0x00000000,0x00000000,0x00000010,0x00000010, + 0x00000000,0x00000000,0x00000010,0x00000010, + 0x00001000,0x00001000,0x00001010,0x00001010, + 0x00001000,0x00001000,0x00001010,0x00001010, + },{ + 0x00000000,0x00000000,0x00200000,0x00200000, + 0x00000000,0x00000000,0x00200000,0x00200000, + 0x20000000,0x20000000,0x20200000,0x20200000, + 0x20000000,0x20000000,0x20200000,0x20200000, + },{ + 0x00000000,0x00000000,0x00000020,0x00000020, + 0x00000000,0x00000000,0x00000020,0x00000020, + 0x00002000,0x00002000,0x00002020,0x00002020, + 0x00002000,0x00002000,0x00002020,0x00002020, + },{ + 0x00000000,0x00000000,0x00400000,0x00400000, + 0x00000000,0x00000000,0x00400000,0x00400000, + 0x40000000,0x40000000,0x40400000,0x40400000, + 0x40000000,0x40000000,0x40400000,0x40400000, + },{ + 0x00000000,0x00000000,0x00000040,0x00000040, + 0x00000000,0x00000000,0x00000040,0x00000040, + 0x00004000,0x00004000,0x00004040,0x00004040, + 0x00004000,0x00004000,0x00004040,0x00004040, + },{ + 0x00000000,0x00000000,0x00800000,0x00800000, + 0x00000000,0x00000000,0x00800000,0x00800000, + 0x80000000,0x80000000,0x80800000,0x80800000, + 0x80000000,0x80000000,0x80800000,0x80800000, + },{ + 0x00000000,0x00000000,0x00000080,0x00000080, + 0x00000000,0x00000000,0x00000080,0x00000080, + 0x00008000,0x00008000,0x00008080,0x00008080, + 0x00008000,0x00008000,0x00008080,0x00008080, + }, +}; +static const uint32_t fp_maskl[8][16] = { + { + 0x00000000,0x40000000,0x00400000,0x40400000, + 0x00004000,0x40004000,0x00404000,0x40404000, + 0x00000040,0x40000040,0x00400040,0x40400040, + 0x00004040,0x40004040,0x00404040,0x40404040, + },{ + 0x00000000,0x10000000,0x00100000,0x10100000, + 0x00001000,0x10001000,0x00101000,0x10101000, + 0x00000010,0x10000010,0x00100010,0x10100010, + 0x00001010,0x10001010,0x00101010,0x10101010, + },{ + 0x00000000,0x04000000,0x00040000,0x04040000, + 0x00000400,0x04000400,0x00040400,0x04040400, + 0x00000004,0x04000004,0x00040004,0x04040004, + 0x00000404,0x04000404,0x00040404,0x04040404, + },{ + 0x00000000,0x01000000,0x00010000,0x01010000, + 0x00000100,0x01000100,0x00010100,0x01010100, + 0x00000001,0x01000001,0x00010001,0x01010001, + 0x00000101,0x01000101,0x00010101,0x01010101, + },{ + 0x00000000,0x80000000,0x00800000,0x80800000, + 0x00008000,0x80008000,0x00808000,0x80808000, + 0x00000080,0x80000080,0x00800080,0x80800080, + 0x00008080,0x80008080,0x00808080,0x80808080, + },{ + 0x00000000,0x20000000,0x00200000,0x20200000, + 0x00002000,0x20002000,0x00202000,0x20202000, + 0x00000020,0x20000020,0x00200020,0x20200020, + 0x00002020,0x20002020,0x00202020,0x20202020, + },{ + 0x00000000,0x08000000,0x00080000,0x08080000, + 0x00000800,0x08000800,0x00080800,0x08080800, + 0x00000008,0x08000008,0x00080008,0x08080008, + 0x00000808,0x08000808,0x00080808,0x08080808, + },{ + 0x00000000,0x02000000,0x00020000,0x02020000, + 0x00000200,0x02000200,0x00020200,0x02020200, + 0x00000002,0x02000002,0x00020002,0x02020002, + 0x00000202,0x02000202,0x00020202,0x02020202, + }, +}; +static const uint32_t fp_maskr[8][16] = { + { + 0x00000000,0x40000000,0x00400000,0x40400000, + 0x00004000,0x40004000,0x00404000,0x40404000, + 0x00000040,0x40000040,0x00400040,0x40400040, + 0x00004040,0x40004040,0x00404040,0x40404040, + },{ + 0x00000000,0x10000000,0x00100000,0x10100000, + 0x00001000,0x10001000,0x00101000,0x10101000, + 0x00000010,0x10000010,0x00100010,0x10100010, + 0x00001010,0x10001010,0x00101010,0x10101010, + },{ + 0x00000000,0x04000000,0x00040000,0x04040000, + 0x00000400,0x04000400,0x00040400,0x04040400, + 0x00000004,0x04000004,0x00040004,0x04040004, + 0x00000404,0x04000404,0x00040404,0x04040404, + },{ + 0x00000000,0x01000000,0x00010000,0x01010000, + 0x00000100,0x01000100,0x00010100,0x01010100, + 0x00000001,0x01000001,0x00010001,0x01010001, + 0x00000101,0x01000101,0x00010101,0x01010101, + },{ + 0x00000000,0x80000000,0x00800000,0x80800000, + 0x00008000,0x80008000,0x00808000,0x80808000, + 0x00000080,0x80000080,0x00800080,0x80800080, + 0x00008080,0x80008080,0x00808080,0x80808080, + },{ + 0x00000000,0x20000000,0x00200000,0x20200000, + 0x00002000,0x20002000,0x00202000,0x20202000, + 0x00000020,0x20000020,0x00200020,0x20200020, + 0x00002020,0x20002020,0x00202020,0x20202020, + },{ + 0x00000000,0x08000000,0x00080000,0x08080000, + 0x00000800,0x08000800,0x00080800,0x08080800, + 0x00000008,0x08000008,0x00080008,0x08080008, + 0x00000808,0x08000808,0x00080808,0x08080808, + },{ + 0x00000000,0x02000000,0x00020000,0x02020000, + 0x00000200,0x02000200,0x00020200,0x02020200, + 0x00000002,0x02000002,0x00020002,0x02020002, + 0x00000202,0x02000202,0x00020202,0x02020202, + }, +}; +static const uint32_t key_perm_maskl[8][16] = { + { + 0x00000000,0x00000000,0x00000010,0x00000010, + 0x00001000,0x00001000,0x00001010,0x00001010, + 0x00100000,0x00100000,0x00100010,0x00100010, + 0x00101000,0x00101000,0x00101010,0x00101010, + },{ + 0x00000000,0x00000000,0x00000020,0x00000020, + 0x00002000,0x00002000,0x00002020,0x00002020, + 0x00200000,0x00200000,0x00200020,0x00200020, + 0x00202000,0x00202000,0x00202020,0x00202020, + },{ + 0x00000000,0x00000000,0x00000040,0x00000040, + 0x00004000,0x00004000,0x00004040,0x00004040, + 0x00400000,0x00400000,0x00400040,0x00400040, + 0x00404000,0x00404000,0x00404040,0x00404040, + },{ + 0x00000000,0x00000000,0x00000080,0x00000080, + 0x00008000,0x00008000,0x00008080,0x00008080, + 0x00800000,0x00800000,0x00800080,0x00800080, + 0x00808000,0x00808000,0x00808080,0x00808080, + },{ + 0x00000000,0x00000001,0x00000100,0x00000101, + 0x00010000,0x00010001,0x00010100,0x00010101, + 0x01000000,0x01000001,0x01000100,0x01000101, + 0x01010000,0x01010001,0x01010100,0x01010101, + },{ + 0x00000000,0x00000002,0x00000200,0x00000202, + 0x00020000,0x00020002,0x00020200,0x00020202, + 0x02000000,0x02000002,0x02000200,0x02000202, + 0x02020000,0x02020002,0x02020200,0x02020202, + },{ + 0x00000000,0x00000004,0x00000400,0x00000404, + 0x00040000,0x00040004,0x00040400,0x00040404, + 0x04000000,0x04000004,0x04000400,0x04000404, + 0x04040000,0x04040004,0x04040400,0x04040404, + },{ + 0x00000000,0x00000008,0x00000800,0x00000808, + 0x00080000,0x00080008,0x00080800,0x00080808, + 0x08000000,0x08000008,0x08000800,0x08000808, + 0x08080000,0x08080008,0x08080800,0x08080808, + }, +}; +static const uint32_t key_perm_maskr[12][16] = { + { + 0x00000000,0x00000001,0x00000000,0x00000001, + 0x00000000,0x00000001,0x00000000,0x00000001, + 0x00000000,0x00000001,0x00000000,0x00000001, + 0x00000000,0x00000001,0x00000000,0x00000001, + },{ + 0x00000000,0x00000000,0x00100000,0x00100000, + 0x00001000,0x00001000,0x00101000,0x00101000, + 0x00000010,0x00000010,0x00100010,0x00100010, + 0x00001010,0x00001010,0x00101010,0x00101010, + },{ + 0x00000000,0x00000002,0x00000000,0x00000002, + 0x00000000,0x00000002,0x00000000,0x00000002, + 0x00000000,0x00000002,0x00000000,0x00000002, + 0x00000000,0x00000002,0x00000000,0x00000002, + },{ + 0x00000000,0x00000000,0x00200000,0x00200000, + 0x00002000,0x00002000,0x00202000,0x00202000, + 0x00000020,0x00000020,0x00200020,0x00200020, + 0x00002020,0x00002020,0x00202020,0x00202020, + },{ + 0x00000000,0x00000004,0x00000000,0x00000004, + 0x00000000,0x00000004,0x00000000,0x00000004, + 0x00000000,0x00000004,0x00000000,0x00000004, + 0x00000000,0x00000004,0x00000000,0x00000004, + },{ + 0x00000000,0x00000000,0x00400000,0x00400000, + 0x00004000,0x00004000,0x00404000,0x00404000, + 0x00000040,0x00000040,0x00400040,0x00400040, + 0x00004040,0x00004040,0x00404040,0x00404040, + },{ + 0x00000000,0x00000008,0x00000000,0x00000008, + 0x00000000,0x00000008,0x00000000,0x00000008, + 0x00000000,0x00000008,0x00000000,0x00000008, + 0x00000000,0x00000008,0x00000000,0x00000008, + },{ + 0x00000000,0x00000000,0x00800000,0x00800000, + 0x00008000,0x00008000,0x00808000,0x00808000, + 0x00000080,0x00000080,0x00800080,0x00800080, + 0x00008080,0x00008080,0x00808080,0x00808080, + },{ + 0x00000000,0x00000000,0x01000000,0x01000000, + 0x00010000,0x00010000,0x01010000,0x01010000, + 0x00000100,0x00000100,0x01000100,0x01000100, + 0x00010100,0x00010100,0x01010100,0x01010100, + },{ + 0x00000000,0x00000000,0x02000000,0x02000000, + 0x00020000,0x00020000,0x02020000,0x02020000, + 0x00000200,0x00000200,0x02000200,0x02000200, + 0x00020200,0x00020200,0x02020200,0x02020200, + },{ + 0x00000000,0x00000000,0x04000000,0x04000000, + 0x00040000,0x00040000,0x04040000,0x04040000, + 0x00000400,0x00000400,0x04000400,0x04000400, + 0x00040400,0x00040400,0x04040400,0x04040400, + },{ + 0x00000000,0x00000000,0x08000000,0x08000000, + 0x00080000,0x00080000,0x08080000,0x08080000, + 0x00000800,0x00000800,0x08000800,0x08000800, + 0x00080800,0x00080800,0x08080800,0x08080800, + }, +}; +static const uint32_t comp_maskl0[4][8] = { + { + 0x00000000,0x00020000,0x00000001,0x00020001, + 0x00080000,0x000a0000,0x00080001,0x000a0001, + },{ + 0x00000000,0x00001000,0x00000000,0x00001000, + 0x00000040,0x00001040,0x00000040,0x00001040, + },{ + 0x00000000,0x00400000,0x00000020,0x00400020, + 0x00008000,0x00408000,0x00008020,0x00408020, + },{ + 0x00000000,0x00100000,0x00000800,0x00100800, + 0x00000000,0x00100000,0x00000800,0x00100800, + }, +}; +static const uint32_t comp_maskr0[4][8] = { + { + 0x00000000,0x00200000,0x00020000,0x00220000, + 0x00000002,0x00200002,0x00020002,0x00220002, + },{ + 0x00000000,0x00000000,0x00100000,0x00100000, + 0x00000004,0x00000004,0x00100004,0x00100004, + },{ + 0x00000000,0x00004000,0x00000800,0x00004800, + 0x00000000,0x00004000,0x00000800,0x00004800, + },{ + 0x00000000,0x00400000,0x00008000,0x00408000, + 0x00000008,0x00400008,0x00008008,0x00408008, + }, +}; +static const uint32_t comp_maskl1[4][16] = { + { + 0x00000000,0x00000010,0x00004000,0x00004010, + 0x00040000,0x00040010,0x00044000,0x00044010, + 0x00000100,0x00000110,0x00004100,0x00004110, + 0x00040100,0x00040110,0x00044100,0x00044110, + },{ + 0x00000000,0x00800000,0x00000002,0x00800002, + 0x00000200,0x00800200,0x00000202,0x00800202, + 0x00200000,0x00a00000,0x00200002,0x00a00002, + 0x00200200,0x00a00200,0x00200202,0x00a00202, + },{ + 0x00000000,0x00002000,0x00000004,0x00002004, + 0x00000400,0x00002400,0x00000404,0x00002404, + 0x00000000,0x00002000,0x00000004,0x00002004, + 0x00000400,0x00002400,0x00000404,0x00002404, + },{ + 0x00000000,0x00010000,0x00000008,0x00010008, + 0x00000080,0x00010080,0x00000088,0x00010088, + 0x00000000,0x00010000,0x00000008,0x00010008, + 0x00000080,0x00010080,0x00000088,0x00010088, + }, +}; +static const uint32_t comp_maskr1[4][16] = { + { + 0x00000000,0x00000000,0x00000080,0x00000080, + 0x00002000,0x00002000,0x00002080,0x00002080, + 0x00000001,0x00000001,0x00000081,0x00000081, + 0x00002001,0x00002001,0x00002081,0x00002081, + },{ + 0x00000000,0x00000010,0x00800000,0x00800010, + 0x00010000,0x00010010,0x00810000,0x00810010, + 0x00000200,0x00000210,0x00800200,0x00800210, + 0x00010200,0x00010210,0x00810200,0x00810210, + },{ + 0x00000000,0x00000400,0x00001000,0x00001400, + 0x00080000,0x00080400,0x00081000,0x00081400, + 0x00000020,0x00000420,0x00001020,0x00001420, + 0x00080020,0x00080420,0x00081020,0x00081420, + },{ + 0x00000000,0x00000100,0x00040000,0x00040100, + 0x00000000,0x00000100,0x00040000,0x00040100, + 0x00000040,0x00000140,0x00040040,0x00040140, + 0x00000040,0x00000140,0x00040040,0x00040140, + }, +}; + +static const unsigned char ascii64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +/* 0000000000111111111122222222223333333333444444444455555555556666 */ +/* 0123456789012345678901234567890123456789012345678901234567890123 */ + +/* + * We match the behavior of UFC-crypt on systems where "char" is signed by + * default (the majority), regardless of char's signedness on our system. + */ +static uint32_t ascii_to_bin(int ch) +{ + int sch = (ch < 0x80) ? ch : -(0x100 - ch); + int retval; + + retval = sch - '.'; + if (sch >= 'A') { + retval = sch - ('A' - 12); + if (sch >= 'a') + retval = sch - ('a' - 38); + } + retval &= 0x3f; + + return retval; +} + +/* + * When we choose to "support" invalid salts, nevertheless disallow those + * containing characters that would violate the passwd file format. + */ +static inline int ascii_is_unsafe(unsigned char ch) +{ + return !ch || ch == '\n' || ch == ':'; +} + +static uint32_t setup_salt(uint32_t salt) +{ + uint32_t obit, saltbit, saltbits; + unsigned int i; + + saltbits = 0; + saltbit = 1; + obit = 0x800000; + for (i = 0; i < 24; i++) { + if (salt & saltbit) + saltbits |= obit; + saltbit <<= 1; + obit >>= 1; + } + + return saltbits; +} + +static void des_setkey(const unsigned char *key, struct expanded_key *ekey) +{ + uint32_t k0, k1, rawkey0, rawkey1; + unsigned int shifts, round, i, ibit; + + rawkey0 = + (uint32_t)key[3] | + ((uint32_t)key[2] << 8) | + ((uint32_t)key[1] << 16) | + ((uint32_t)key[0] << 24); + rawkey1 = + (uint32_t)key[7] | + ((uint32_t)key[6] << 8) | + ((uint32_t)key[5] << 16) | + ((uint32_t)key[4] << 24); + + /* + * Do key permutation and split into two 28-bit subkeys. + */ + k0 = k1 = 0; + for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) { + unsigned int j = i << 1; + k0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] | + key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf]; + k1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf]; + ibit -= 4; + k1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] | + key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf]; + } + + /* + * Rotate subkeys and do compression permutation. + */ + shifts = 0; + for (round = 0; round < 16; round++) { + uint32_t t0, t1; + uint32_t kl, kr; + + shifts += key_shifts[round]; + + t0 = (k0 << shifts) | (k0 >> (28 - shifts)); + t1 = (k1 << shifts) | (k1 >> (28 - shifts)); + + kl = kr = 0; + ibit = 25; + for (i = 0; i < 4; i++) { + kl |= comp_maskl0[i][(t0 >> ibit) & 7]; + kr |= comp_maskr0[i][(t1 >> ibit) & 7]; + ibit -= 4; + kl |= comp_maskl1[i][(t0 >> ibit) & 0xf]; + kr |= comp_maskr1[i][(t1 >> ibit) & 0xf]; + ibit -= 3; + } + ekey->l[round] = kl; + ekey->r[round] = kr; + } +} + +/* + * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. + */ +static void do_des(uint32_t l_in, uint32_t r_in, + uint32_t *l_out, uint32_t *r_out, + uint32_t count, uint32_t saltbits, const struct expanded_key *ekey) +{ + uint32_t l, r; + + /* + * Do initial permutation (IP). + */ + l = r = 0; + if (l_in | r_in) { + unsigned int i, ibit; + for (i = 0, ibit = 28; i < 8; i++, ibit -= 4) { + l |= ip_maskl[i][(l_in >> ibit) & 0xf] | + ip_maskl[i + 8][(r_in >> ibit) & 0xf]; + r |= ip_maskr[i][(l_in >> ibit) & 0xf] | + ip_maskr[i + 8][(r_in >> ibit) & 0xf]; + } + } + + while (count--) { + /* + * Do each round. + */ + unsigned int round = 16; + const uint32_t *kl = ekey->l; + const uint32_t *kr = ekey->r; + uint32_t f; + while (round--) { + uint32_t r48l, r48r; + /* + * Expand R to 48 bits (simulate the E-box). + */ + r48l = ((r & 0x00000001) << 23) + | ((r & 0xf8000000) >> 9) + | ((r & 0x1f800000) >> 11) + | ((r & 0x01f80000) >> 13) + | ((r & 0x001f8000) >> 15); + + r48r = ((r & 0x0001f800) << 7) + | ((r & 0x00001f80) << 5) + | ((r & 0x000001f8) << 3) + | ((r & 0x0000001f) << 1) + | ((r & 0x80000000) >> 31); + /* + * Do salting for crypt() and friends, and + * XOR with the permuted key. + */ + f = (r48l ^ r48r) & saltbits; + r48l ^= f ^ *kl++; + r48r ^= f ^ *kr++; + /* + * Do S-box lookups (which shrink it back to 32 bits) + * and do the P-box permutation at the same time. + */ + f = psbox[0][r48l >> 18] + | psbox[1][(r48l >> 12) & 0x3f] + | psbox[2][(r48l >> 6) & 0x3f] + | psbox[3][r48l & 0x3f] + | psbox[4][r48r >> 18] + | psbox[5][(r48r >> 12) & 0x3f] + | psbox[6][(r48r >> 6) & 0x3f] + | psbox[7][r48r & 0x3f]; + /* + * Now that we've permuted things, complete f(). + */ + f ^= l; + l = r; + r = f; + } + r = l; + l = f; + } + + /* + * Do final permutation (inverse of IP). + */ + { + unsigned int i, ibit; + uint32_t lo, ro; + lo = ro = 0; + for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) { + ro |= fp_maskr[i][(l >> ibit) & 0xf] | + fp_maskr[i + 4][(r >> ibit) & 0xf]; + ibit -= 4; + lo |= fp_maskl[i][(l >> ibit) & 0xf] | + fp_maskl[i + 4][(r >> ibit) & 0xf]; + } + *l_out = lo; + *r_out = ro; + } +} + +static void des_cipher(const unsigned char *in, unsigned char *out, + uint32_t count, uint32_t saltbits, const struct expanded_key *ekey) +{ + uint32_t l_out, r_out, rawl, rawr; + + rawl = + (uint32_t)in[3] | + ((uint32_t)in[2] << 8) | + ((uint32_t)in[1] << 16) | + ((uint32_t)in[0] << 24); + rawr = + (uint32_t)in[7] | + ((uint32_t)in[6] << 8) | + ((uint32_t)in[5] << 16) | + ((uint32_t)in[4] << 24); + + do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey); + + out[0] = l_out >> 24; + out[1] = l_out >> 16; + out[2] = l_out >> 8; + out[3] = l_out; + out[4] = r_out >> 24; + out[5] = r_out >> 16; + out[6] = r_out >> 8; + out[7] = r_out; +} + +static char *_crypt_extended_r_uut(const char *_key, const char *_setting, char *output) +{ + const unsigned char *key = (const unsigned char *)_key; + const unsigned char *setting = (const unsigned char *)_setting; + struct expanded_key ekey; + union { + unsigned char c[8]; + uint32_t i[2]; + } keybuf; + unsigned char *p, *q; + uint32_t count, salt, l, r0, r1; + unsigned int i; + + /* + * Copy the key, shifting each character left by one bit and padding + * with zeroes. + */ + q = keybuf.c; + while (q <= &keybuf.c[sizeof(keybuf.c) - 1]) { + *q++ = *key << 1; + if (*key) + key++; + } + des_setkey(keybuf.c, &ekey); + + if (*setting == _PASSWORD_EFMT1) { + /* + * "new"-style: + * setting - underscore, 4 chars of count, 4 chars of salt + * key - unlimited characters + */ + for (i = 1, count = 0; i < 5; i++) { + uint32_t value = ascii_to_bin(setting[i]); + if (ascii64[value] != setting[i]) + return NULL; + count |= value << (i - 1) * 6; + } + if (!count || count > 262143) + return NULL; + + for (i = 5, salt = 0; i < 9; i++) { + uint32_t value = ascii_to_bin(setting[i]); + if (ascii64[value] != setting[i]) + return NULL; + salt |= value << (i - 5) * 6; + } + + while (*key) { + /* + * Encrypt the key with itself. + */ + des_cipher(keybuf.c, keybuf.c, 1, 0, &ekey); + /* + * And XOR with the next 8 characters of the key. + */ + q = keybuf.c; + while (q <= &keybuf.c[sizeof(keybuf.c) - 1] && *key) + *q++ ^= *key++ << 1; + des_setkey(keybuf.c, &ekey); + } + + memcpy(output, setting, 9); + output[9] = '\0'; + p = (unsigned char *)output + 9; + } else { + /* + * "old"-style: + * setting - 2 chars of salt + * key - up to 8 characters + */ + count = 25; + + if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1])) + return NULL; + + salt = (ascii_to_bin(setting[1]) << 6) + | ascii_to_bin(setting[0]); + + output[0] = setting[0]; + output[1] = setting[1]; + p = (unsigned char *)output + 2; + } + + /* + * Do it. + */ + do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey); + + /* + * Now encode the result... + */ + l = (r0 >> 8); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = (r0 << 16) | ((r1 >> 16) & 0xffff); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = r1 << 2; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + *p = 0; + + return output; +} + +char *__crypt_des(const char *key, const char *setting, char *output) +{ + const char *test_key = "\x80\xff\x80\x01 " + "\x7f\x81\x80\x80\x0d\x0a\xff\x7f \x81 test"; + const char *test_setting = "_0.../9Zz"; + const char *test_hash = "_0.../9ZzX7iSJNd21sU"; + char test_buf[21]; + char *retval; + const char *p; + + if (*setting != _PASSWORD_EFMT1) { + test_setting = "\x80x"; + test_hash = "\x80x22/wK52ZKGA"; + } + + /* + * Hash the supplied password. + */ + retval = _crypt_extended_r_uut(key, setting, output); + + /* + * Perform a quick self-test. It is important that we make both calls + * to _crypt_extended_r_uut() from the same scope such that they likely + * use the same stack locations, which makes the second call overwrite + * the first call's sensitive data on the stack and makes it more + * likely that any alignment related issues would be detected. + */ + p = _crypt_extended_r_uut(test_key, test_setting, test_buf); + if (p && !strcmp(p, test_hash) && retval) + return retval; + + return (setting[0]=='*') ? "x" : "*"; +} diff --git a/src/crypt/crypt_r.c b/src/crypt/crypt_r.c new file mode 100644 index 00000000..1c7f9cf0 --- /dev/null +++ b/src/crypt/crypt_r.c @@ -0,0 +1,30 @@ +#include +#include "libc.h" + +struct crypt_data; + +char *__crypt_des(const char *, const char *, char *); +char *__crypt_md5(const char *, const char *, char *); +char *__crypt_blowfish(const char *, const char *, char *); +char *__crypt_sha256(const char *, const char *, char *); +char *__crypt_sha512(const char *, const char *, char *); + +char *__crypt_r(const char *key, const char *salt, struct crypt_data *data) +{ + char *output = (char *)data; + if (salt[0] == '$' && salt[1] && salt[2]) { +#if 0 + if (salt[1] == '1' && salt[2] == '$') + return __crypt_md5(key, salt, output); +#endif + if (salt[1] == '2' && salt[3] == '$') + return __crypt_blowfish(key, salt, output); + if (salt[1] == '5' && salt[2] == '$') + return __crypt_sha256(key, salt, output); + if (salt[1] == '6' && salt[2] == '$') + return __crypt_sha512(key, salt, output); + } + return __crypt_des(key, salt, output); +} + +weak_alias(__crypt_r, crypt_r); diff --git a/src/crypt/crypt_sha256.c b/src/crypt/crypt_sha256.c new file mode 100644 index 00000000..2dc27ee7 --- /dev/null +++ b/src/crypt/crypt_sha256.c @@ -0,0 +1,322 @@ +/* + * public domain sha256 crypt implementation + * + * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt + * in this implementation at least 32bit int is assumed, + * key length is limited, the $5$ prefix is mandatory, '\n' and ':' is rejected + * in the salt and rounds= setting must contain a valid iteration count, + * on error "*" is returned. + */ +#include +#include +#include +#include +#include + +/* public domain sha256 implementation based on fips180-3 */ + +struct sha256 { + uint64_t len; /* processed message length */ + uint32_t h[8]; /* hash state */ + uint8_t buf[64]; /* message block buffer */ +}; + +static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,2) ^ ror(x,13) ^ ror(x,22)) +#define S1(x) (ror(x,6) ^ ror(x,11) ^ ror(x,25)) +#define R0(x) (ror(x,7) ^ ror(x,18) ^ (x>>3)) +#define R1(x) (ror(x,17) ^ ror(x,19) ^ (x>>10)) + +static const uint32_t K[64] = { +0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, +0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, +0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, +0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, +0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, +0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, +0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, +0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static void processblock(struct sha256 *s, const uint8_t *buf) +{ + uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) { + W[i] = (uint32_t)buf[4*i]<<24; + W[i] |= (uint32_t)buf[4*i+1]<<16; + W[i] |= (uint32_t)buf[4*i+2]<<8; + W[i] |= buf[4*i+3]; + } + for (; i < 64; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + a = s->h[0]; + b = s->h[1]; + c = s->h[2]; + d = s->h[3]; + e = s->h[4]; + f = s->h[5]; + g = s->h[6]; + h = s->h[7]; + for (i = 0; i < 64; i++) { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + s->h[0] += a; + s->h[1] += b; + s->h[2] += c; + s->h[3] += d; + s->h[4] += e; + s->h[5] += f; + s->h[6] += g; + s->h[7] += h; +} + +static void pad(struct sha256 *s) +{ + unsigned r = s->len % 64; + + s->buf[r++] = 0x80; + if (r > 56) { + memset(s->buf + r, 0, 64 - r); + r = 0; + processblock(s, s->buf); + } + memset(s->buf + r, 0, 56 - r); + s->len *= 8; + s->buf[56] = s->len >> 56; + s->buf[57] = s->len >> 48; + s->buf[58] = s->len >> 40; + s->buf[59] = s->len >> 32; + s->buf[60] = s->len >> 24; + s->buf[61] = s->len >> 16; + s->buf[62] = s->len >> 8; + s->buf[63] = s->len; + processblock(s, s->buf); +} + +static void sha256_init(struct sha256 *s) +{ + s->len = 0; + s->h[0] = 0x6a09e667; + s->h[1] = 0xbb67ae85; + s->h[2] = 0x3c6ef372; + s->h[3] = 0xa54ff53a; + s->h[4] = 0x510e527f; + s->h[5] = 0x9b05688c; + s->h[6] = 0x1f83d9ab; + s->h[7] = 0x5be0cd19; +} + +static void sha256_sum(struct sha256 *s, uint8_t md[20]) +{ + int i; + + pad(s); + for (i = 0; i < 8; i++) { + md[4*i] = s->h[i] >> 24; + md[4*i+1] = s->h[i] >> 16; + md[4*i+2] = s->h[i] >> 8; + md[4*i+3] = s->h[i]; + } +} + +static void sha256_update(struct sha256 *s, const void *m, unsigned long len) +{ + const uint8_t *p = m; + unsigned r = s->len % 64; + + s->len += len; + if (r) { + if (len < 64 - r) { + memcpy(s->buf + r, p, len); + return; + } + memcpy(s->buf + r, p, 64 - r); + len -= 64 - r; + p += 64 - r; + processblock(s, s->buf); + } + for (; len >= 64; len -= 64, p += 64) + processblock(s, p); + memcpy(s->buf, p, len); +} + +static unsigned char b64[] = +"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *to64(char *s, unsigned int u, int n) +{ + while (--n >= 0) { + *s++ = b64[u % 64]; + u /= 64; + } + return s; +} + +/* key limit is not part of the original design, added for DoS protection. + * rounds limit has been lowered (versus the reference/spec), also for DoS + * protection. runtime is O(klen^2 + klen*rounds) */ +#define KEY_MAX 256 +#define SALT_MAX 16 +#define ROUNDS_DEFAULT 5000 +#define ROUNDS_MIN 1000 +#define ROUNDS_MAX 50000 + +/* hash n bytes of the repeated md message digest */ +static void hashmd(struct sha256 *s, unsigned int n, const void *md) +{ + unsigned int i; + + for (i = n; i > 32; i -= 32) + sha256_update(s, md, 32); + sha256_update(s, md, i); +} + +static char *sha256crypt(const char *key, const char *setting, char *output) +{ + struct sha256 ctx; + unsigned char md[32], kmd[32], smd[32]; + unsigned int i, r, klen, slen; + char rounds[20] = ""; + const char *salt; + char *p; + + /* reject large keys */ + klen = strnlen(key, KEY_MAX+1); + if (klen > KEY_MAX) + return 0; + + /* setting: $5$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ + if (strncmp(setting, "$5$", 3) != 0) + return 0; + salt = setting + 3; + + r = ROUNDS_DEFAULT; + if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { + unsigned long u; + char *end; + + /* + * this is a deviation from the reference: + * bad rounds setting is rejected if it is + * - empty + * - unterminated (missing '$') + * - begins with anything but a decimal digit + * the reference implementation treats these bad + * rounds as part of the salt or parse them with + * strtoul semantics which may cause problems + * including non-portable hashes that depend on + * the host's value of ULONG_MAX. + */ + salt += sizeof "rounds=" - 1; + if (!isdigit(*salt)) + return 0; + u = strtoul(salt, &end, 10); + if (*end != '$') + return 0; + salt = end+1; + if (u < ROUNDS_MIN) + r = ROUNDS_MIN; + else if (u > ROUNDS_MAX) + r = ROUNDS_MAX; + else + r = u; + /* needed when rounds is zero prefixed or out of bounds */ + sprintf(rounds, "rounds=%u$", r); + } + + for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) + /* reject characters that interfere with /etc/shadow parsing */ + if (salt[i] == '\n' || salt[i] == ':') + return 0; + slen = i; + + /* B = sha(key salt key) */ + sha256_init(&ctx); + sha256_update(&ctx, key, klen); + sha256_update(&ctx, salt, slen); + sha256_update(&ctx, key, klen); + sha256_sum(&ctx, md); + + /* A = sha(key salt repeat-B alternate-B-key) */ + sha256_init(&ctx); + sha256_update(&ctx, key, klen); + sha256_update(&ctx, salt, slen); + hashmd(&ctx, klen, md); + for (i = klen; i > 0; i >>= 1) + if (i & 1) + sha256_update(&ctx, md, sizeof md); + else + sha256_update(&ctx, key, klen); + sha256_sum(&ctx, md); + + /* DP = sha(repeat-key), this step takes O(klen^2) time */ + sha256_init(&ctx); + for (i = 0; i < klen; i++) + sha256_update(&ctx, key, klen); + sha256_sum(&ctx, kmd); + + /* DS = sha(repeat-salt) */ + sha256_init(&ctx); + for (i = 0; i < 16 + md[0]; i++) + sha256_update(&ctx, salt, slen); + sha256_sum(&ctx, smd); + + /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ + for (i = 0; i < r; i++) { + sha256_init(&ctx); + if (i % 2) + hashmd(&ctx, klen, kmd); + else + sha256_update(&ctx, md, sizeof md); + if (i % 3) + sha256_update(&ctx, smd, slen); + if (i % 7) + hashmd(&ctx, klen, kmd); + if (i % 2) + sha256_update(&ctx, md, sizeof md); + else + hashmd(&ctx, klen, kmd); + sha256_sum(&ctx, md); + } + + /* output is $5$rounds=n$salt$hash */ + p = output; + p += sprintf(p, "$5$%s%.*s$", rounds, slen, salt); + static const unsigned char perm[][3] = { + 0,10,20,21,1,11,12,22,2,3,13,23,24,4,14, + 15,25,5,6,16,26,27,7,17,18,28,8,9,19,29 }; + for (i=0; i<10; i++) p = to64(p, + (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); + p = to64(p, (md[31]<<8)|md[30], 3); + *p = 0; + return output; +} + +char *__crypt_sha256(const char *key, const char *setting, char *output) +{ + static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; + static const char testsetting[] = "$5$rounds=1234$abc0123456789$"; + static const char testhash[] = "$5$rounds=1234$abc0123456789$3VfDjPt05VHFn47C/ojFZ6KRPYrOjj1lLbH.dkF3bZ6"; + char testbuf[128]; + char *p, *q; + + p = sha256crypt(key, setting, output); + /* self test and stack cleanup */ + q = sha256crypt(testkey, testsetting, testbuf); + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + return "*"; + return p; +} diff --git a/src/crypt/crypt_sha512.c b/src/crypt/crypt_sha512.c new file mode 100644 index 00000000..2c0de698 --- /dev/null +++ b/src/crypt/crypt_sha512.c @@ -0,0 +1,371 @@ +/* + * public domain sha512 crypt implementation + * + * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt + * in this implementation at least 32bit int is assumed, + * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected + * in the salt and rounds= setting must contain a valid iteration count, + * on error "*" is returned. + */ +#include +#include +#include +#include +#include + +/* public domain sha512 implementation based on fips180-3 */ +/* >=2^64 bits messages are not supported (about 2000 peta bytes) */ + +struct sha512 { + uint64_t len; /* processed message length */ + uint64_t h[8]; /* hash state */ + uint8_t buf[128]; /* message block buffer */ +}; + +static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) +#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) +#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) +#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) + +static const uint64_t K[80] = { +0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, +0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, +0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, +0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, +0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, +0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, +0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, +0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, +0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, +0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, +0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, +0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, +0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, +0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, +0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, +0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, +0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, +0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, +0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, +0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +static void processblock(struct sha512 *s, const uint8_t *buf) +{ + uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) { + W[i] = (uint64_t)buf[8*i]<<56; + W[i] |= (uint64_t)buf[8*i+1]<<48; + W[i] |= (uint64_t)buf[8*i+2]<<40; + W[i] |= (uint64_t)buf[8*i+3]<<32; + W[i] |= (uint64_t)buf[8*i+4]<<24; + W[i] |= (uint64_t)buf[8*i+5]<<16; + W[i] |= (uint64_t)buf[8*i+6]<<8; + W[i] |= buf[8*i+7]; + } + for (; i < 80; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + a = s->h[0]; + b = s->h[1]; + c = s->h[2]; + d = s->h[3]; + e = s->h[4]; + f = s->h[5]; + g = s->h[6]; + h = s->h[7]; + for (i = 0; i < 80; i++) { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + s->h[0] += a; + s->h[1] += b; + s->h[2] += c; + s->h[3] += d; + s->h[4] += e; + s->h[5] += f; + s->h[6] += g; + s->h[7] += h; +} + +static void pad(struct sha512 *s) +{ + unsigned r = s->len % 128; + + s->buf[r++] = 0x80; + if (r > 112) { + memset(s->buf + r, 0, 128 - r); + r = 0; + processblock(s, s->buf); + } + memset(s->buf + r, 0, 120 - r); + s->len *= 8; + s->buf[120] = s->len >> 56; + s->buf[121] = s->len >> 48; + s->buf[122] = s->len >> 40; + s->buf[123] = s->len >> 32; + s->buf[124] = s->len >> 24; + s->buf[125] = s->len >> 16; + s->buf[126] = s->len >> 8; + s->buf[127] = s->len; + processblock(s, s->buf); +} + +static void sha512_init(struct sha512 *s) +{ + s->len = 0; + s->h[0] = 0x6a09e667f3bcc908ULL; + s->h[1] = 0xbb67ae8584caa73bULL; + s->h[2] = 0x3c6ef372fe94f82bULL; + s->h[3] = 0xa54ff53a5f1d36f1ULL; + s->h[4] = 0x510e527fade682d1ULL; + s->h[5] = 0x9b05688c2b3e6c1fULL; + s->h[6] = 0x1f83d9abfb41bd6bULL; + s->h[7] = 0x5be0cd19137e2179ULL; +} + +static void sha512_sum(struct sha512 *s, uint8_t md[20]) +{ + int i; + + pad(s); + for (i = 0; i < 8; i++) { + md[8*i] = s->h[i] >> 56; + md[8*i+1] = s->h[i] >> 48; + md[8*i+2] = s->h[i] >> 40; + md[8*i+3] = s->h[i] >> 32; + md[8*i+4] = s->h[i] >> 24; + md[8*i+5] = s->h[i] >> 16; + md[8*i+6] = s->h[i] >> 8; + md[8*i+7] = s->h[i]; + } +} + +static void sha512_update(struct sha512 *s, const void *m, unsigned long len) +{ + const uint8_t *p = m; + unsigned r = s->len % 128; + + s->len += len; + if (r) { + if (len < 128 - r) { + memcpy(s->buf + r, p, len); + return; + } + memcpy(s->buf + r, p, 128 - r); + len -= 128 - r; + p += 128 - r; + processblock(s, s->buf); + } + for (; len >= 128; len -= 128, p += 128) + processblock(s, p); + memcpy(s->buf, p, len); +} + +static unsigned char b64[] = +"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static char *to64(char *s, unsigned int u, int n) +{ + while (--n >= 0) { + *s++ = b64[u % 64]; + u /= 64; + } + return s; +} + +/* key limit is not part of the original design, added for DoS protection. + * rounds limit has been lowered (versus the reference/spec), also for DoS + * protection. runtime is O(klen^2 + klen*rounds) */ +#define KEY_MAX 256 +#define SALT_MAX 16 +#define ROUNDS_DEFAULT 5000 +#define ROUNDS_MIN 1000 +#define ROUNDS_MAX 20000 + +/* hash n bytes of the repeated md message digest */ +static void hashmd(struct sha512 *s, unsigned int n, const void *md) +{ + unsigned int i; + + for (i = n; i > 64; i -= 64) + sha512_update(s, md, 64); + sha512_update(s, md, i); +} + +static char *sha512crypt(const char *key, const char *setting, char *output) +{ + struct sha512 ctx; + unsigned char md[64], kmd[64], smd[64]; + unsigned int i, r, klen, slen; + char rounds[20] = ""; + const char *salt; + char *p; + + /* reject large keys */ + for (i = 0; i <= KEY_MAX && key[i]; i++); + if (i > KEY_MAX) + return 0; + klen = i; + + /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ + if (strncmp(setting, "$6$", 3) != 0) + return 0; + salt = setting + 3; + + r = ROUNDS_DEFAULT; + if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { + unsigned long u; + char *end; + + /* + * this is a deviation from the reference: + * bad rounds setting is rejected if it is + * - empty + * - unterminated (missing '$') + * - begins with anything but a decimal digit + * the reference implementation treats these bad + * rounds as part of the salt or parse them with + * strtoul semantics which may cause problems + * including non-portable hashes that depend on + * the host's value of ULONG_MAX. + */ + salt += sizeof "rounds=" - 1; + if (!isdigit(*salt)) + return 0; + u = strtoul(salt, &end, 10); + if (*end != '$') + return 0; + salt = end+1; + if (u < ROUNDS_MIN) + r = ROUNDS_MIN; + else if (u > ROUNDS_MAX) + r = ROUNDS_MAX; + else + r = u; + /* needed when rounds is zero prefixed or out of bounds */ + sprintf(rounds, "rounds=%u$", r); + } + + for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) + /* reject characters that interfere with /etc/shadow parsing */ + if (salt[i] == '\n' || salt[i] == ':') + return 0; + slen = i; + + /* B = sha(key salt key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* A = sha(key salt repeat-B alternate-B-key) */ + sha512_init(&ctx); + sha512_update(&ctx, key, klen); + sha512_update(&ctx, salt, slen); + hashmd(&ctx, klen, md); + for (i = klen; i > 0; i >>= 1) + if (i & 1) + sha512_update(&ctx, md, sizeof md); + else + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, md); + + /* DP = sha(repeat-key), this step takes O(klen^2) time */ + sha512_init(&ctx); + for (i = 0; i < klen; i++) + sha512_update(&ctx, key, klen); + sha512_sum(&ctx, kmd); + + /* DS = sha(repeat-salt) */ + sha512_init(&ctx); + for (i = 0; i < 16 + md[0]; i++) + sha512_update(&ctx, salt, slen); + sha512_sum(&ctx, smd); + + /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ + for (i = 0; i < r; i++) { + sha512_init(&ctx); + if (i % 2) + hashmd(&ctx, klen, kmd); + else + sha512_update(&ctx, md, sizeof md); + if (i % 3) + sha512_update(&ctx, smd, slen); + if (i % 7) + hashmd(&ctx, klen, kmd); + if (i % 2) + sha512_update(&ctx, md, sizeof md); + else + hashmd(&ctx, klen, kmd); + sha512_sum(&ctx, md); + } + + /* output is $6$rounds=n$salt$hash */ + p = output; + p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); +#if 1 + static const unsigned char perm[][3] = { + 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, + 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, + 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, + 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, + 62,20,41 }; + for (i=0; i<21; i++) p = to64(p, + (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); +#else + p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); + p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); + p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); + p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); + p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); + p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); + p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); + p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); + p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); + p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); + p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); + p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); + p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); + p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); + p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); + p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); + p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); + p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); + p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); + p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); + p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); +#endif + p = to64(p, md[63], 2); + *p = 0; + return output; +} + +char *__crypt_sha512(const char *key, const char *setting, char *output) +{ + static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; + static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; + static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; + char testbuf[128]; + char *p, *q; + + p = sha512crypt(key, setting, output); + /* self test and stack cleanup */ + q = sha512crypt(testkey, testsetting, testbuf); + if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) + return "*"; + return p; +} diff --git a/src/legacy/cuserid.c b/src/legacy/cuserid.c new file mode 100644 index 00000000..4e78798d --- /dev/null +++ b/src/legacy/cuserid.c @@ -0,0 +1,14 @@ +#define _GNU_SOURCE +#include +#include +#include + +char *cuserid(char *buf) +{ + struct passwd pw, *ppw; + long pwb[256]; + if (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw)) + return 0; + snprintf(buf, L_cuserid, "%s", pw.pw_name); + return buf; +} diff --git a/src/legacy/daemon.c b/src/legacy/daemon.c new file mode 100644 index 00000000..1568b1dc --- /dev/null +++ b/src/legacy/daemon.c @@ -0,0 +1,33 @@ +#define _GNU_SOURCE +#include +#include + +int daemon(int nochdir, int noclose) +{ + if (!nochdir && chdir("/")) + return -1; + if (!noclose) { + int fd, failed = 0; + if ((fd = open("/dev/null", O_RDWR)) < 0) return -1; + if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) + failed++; + if (fd > 2) close(fd); + if (failed) return -1; + } + + switch(fork()) { + case 0: break; + case -1: return -1; + default: _exit(0); + } + + if (setsid() < 0) return -1; + + switch(fork()) { + case 0: break; + case -1: return -1; + default: _exit(0); + } + + return 0; +} diff --git a/src/legacy/err.c b/src/legacy/err.c new file mode 100644 index 00000000..0f748538 --- /dev/null +++ b/src/legacy/err.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +void vwarn(const char *fmt, va_list ap) +{ + if (fmt) vfprintf(stderr, fmt, ap); + perror(""); +} + +void vwarnx(const char *fmt, va_list ap) +{ + if (fmt) vfprintf(stderr, fmt, ap); + putc('\n', stderr); +} + +_Noreturn void verr(int status, const char *fmt, va_list ap) +{ + vwarn(fmt, ap); + exit(status); +} + +_Noreturn void verrx(int status, const char *fmt, va_list ap) +{ + vwarnx(fmt, ap); + exit(status); +} + +void warn(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarn(fmt, ap); + va_end(ap); +} + +void warnx(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} + +_Noreturn void err(int status, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verr(status, fmt, ap); + va_end(ap); +} + +_Noreturn void errx(int status, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(status, fmt, ap); + va_end(ap); +} diff --git a/src/legacy/ftw.c b/src/legacy/ftw.c new file mode 100644 index 00000000..0429aba4 --- /dev/null +++ b/src/legacy/ftw.c @@ -0,0 +1,12 @@ +#include +#include "libc.h" + +int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit) +{ + /* The following cast assumes that calling a function with one + * argument more than it needs behaves as expected. This is + * actually undefined, but works on all real-world machines. */ + return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS); +} + +LFS64(ftw); diff --git a/src/legacy/futimes.c b/src/legacy/futimes.c new file mode 100644 index 00000000..f8fd1cde --- /dev/null +++ b/src/legacy/futimes.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int futimes(int fd, const struct timeval tv[2]) +{ + struct timespec times[2]; + times[0].tv_sec = tv[0].tv_sec; + times[0].tv_nsec = tv[0].tv_usec * 1000; + times[1].tv_sec = tv[1].tv_sec; + times[1].tv_nsec = tv[1].tv_usec * 1000; + return futimens(fd, times); +} diff --git a/src/legacy/getdtablesize.c b/src/legacy/getdtablesize.c new file mode 100644 index 00000000..623a6af3 --- /dev/null +++ b/src/legacy/getdtablesize.c @@ -0,0 +1,9 @@ +#include +#include + +int getdtablesize(void) +{ + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + return rl.rlim_max < INT_MAX ? rl.rlim_max : INT_MAX; +} diff --git a/src/legacy/getpagesize.c b/src/legacy/getpagesize.c new file mode 100644 index 00000000..5ede652b --- /dev/null +++ b/src/legacy/getpagesize.c @@ -0,0 +1,7 @@ +#include +#include + +int getpagesize(void) +{ + return PAGE_SIZE; +} diff --git a/src/legacy/getpass.c b/src/legacy/getpass.c new file mode 100644 index 00000000..d439a2a5 --- /dev/null +++ b/src/legacy/getpass.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +char *getpass(const char *prompt) +{ + int fd; + struct termios s, t; + ssize_t l; + static char password[128]; + + if ((fd = open("/dev/tty", O_RDONLY|O_NOCTTY)) < 0) fd = 0; + + tcgetattr(fd, &t); + s = t; + t.c_lflag &= ~(ECHO|ISIG); + t.c_lflag |= ICANON; + t.c_iflag &= ~(INLCR|IGNCR); + t.c_iflag |= ICRNL; + tcsetattr(fd, TCSAFLUSH, &t); + tcdrain(fd); + + fputs(prompt, stderr); + fflush(stderr); + + l = read(fd, password, sizeof password); + if (l >= 0) { + if (l > 0 && password[l-1] == '\n') l--; + password[l] = 0; + } + + tcsetattr(fd, TCSAFLUSH, &s); + + if (fd > 2) close(fd); + + return password; +} diff --git a/src/legacy/getusershell.c b/src/legacy/getusershell.c new file mode 100644 index 00000000..683158c8 --- /dev/null +++ b/src/legacy/getusershell.c @@ -0,0 +1,33 @@ +#define _GNU_SOURCE +#include +#include +#include + +static const char defshells[] = "/bin/sh\n/bin/csh\n"; + +static char *line; +static size_t linesize; +static FILE *f; + +void endusershell(void) +{ + if (f) fclose(f); + f = 0; +} + +void setusershell(void) +{ + if (!f) f = fopen("/etc/shells", "rb"); + if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb"); +} + +char *getusershell(void) +{ + ssize_t l; + if (!f) setusershell(); + if (!f) return 0; + l = getline(&line, &linesize, f); + if (l <= 0) return 0; + if (line[l-1]=='\n') line[l-1]=0; + return line; +} diff --git a/src/legacy/isastream.c b/src/legacy/isastream.c new file mode 100644 index 00000000..4dafdb08 --- /dev/null +++ b/src/legacy/isastream.c @@ -0,0 +1,7 @@ +#include +#include + +int isastream(int fd) +{ + return fcntl(fd, F_GETFD) < 0 ? -1 : 0; +} diff --git a/src/legacy/lutimes.c b/src/legacy/lutimes.c new file mode 100644 index 00000000..13dfe4ef --- /dev/null +++ b/src/legacy/lutimes.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int lutimes(const char *filename, const struct timeval tv[2]) +{ + struct timespec times[2]; + times[0].tv_sec = tv[0].tv_sec; + times[0].tv_nsec = tv[0].tv_usec * 1000; + times[1].tv_sec = tv[1].tv_sec; + times[1].tv_nsec = tv[1].tv_usec * 1000; + return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW); +} diff --git a/src/legacy/ulimit.c b/src/legacy/ulimit.c new file mode 100644 index 00000000..1f59e8e6 --- /dev/null +++ b/src/legacy/ulimit.c @@ -0,0 +1,19 @@ +#include +#include +#include + +long ulimit(int cmd, ...) +{ + struct rlimit rl; + getrlimit(RLIMIT_FSIZE, &rl); + if (cmd == UL_SETFSIZE) { + long val; + va_list ap; + va_start(ap, cmd); + val = va_arg(ap, long); + va_end(ap); + rl.rlim_cur = 512ULL * val; + if (setrlimit(RLIMIT_FSIZE, &rl)) return -1; + } + return rl.rlim_cur / 512; +} diff --git a/src/legacy/utmpx.c b/src/legacy/utmpx.c new file mode 100644 index 00000000..c483e4ed --- /dev/null +++ b/src/legacy/utmpx.c @@ -0,0 +1,43 @@ +#include +#include +#include "libc.h" + +void endutxent(void) +{ +} + +void setutxent(void) +{ +} + +struct utmpx *getutxent(void) +{ + return NULL; +} + +struct utmpx *getutxid(const struct utmpx *ut) +{ + return NULL; +} + +struct utmpx *getutxline(const struct utmpx *ut) +{ + return NULL; +} + +struct utmpx *pututxline(const struct utmpx *ut) +{ + return NULL; +} + +void updwtmpx(const char *f, const struct utmpx *u) +{ +} + +weak_alias(endutxent, endutent); +weak_alias(setutxent, setutent); +weak_alias(getutxent, getutent); +weak_alias(getutxid, getutid); +weak_alias(getutxline, getutline); +weak_alias(pututxline, pututline); +weak_alias(updwtmpx, updwtmp); diff --git a/src/linux/daemon.c b/src/linux/daemon.c deleted file mode 100644 index 1568b1dc..00000000 --- a/src/linux/daemon.c +++ /dev/null @@ -1,33 +0,0 @@ -#define _GNU_SOURCE -#include -#include - -int daemon(int nochdir, int noclose) -{ - if (!nochdir && chdir("/")) - return -1; - if (!noclose) { - int fd, failed = 0; - if ((fd = open("/dev/null", O_RDWR)) < 0) return -1; - if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) - failed++; - if (fd > 2) close(fd); - if (failed) return -1; - } - - switch(fork()) { - case 0: break; - case -1: return -1; - default: _exit(0); - } - - if (setsid() < 0) return -1; - - switch(fork()) { - case 0: break; - case -1: return -1; - default: _exit(0); - } - - return 0; -} diff --git a/src/linux/epoll.c b/src/linux/epoll.c new file mode 100644 index 00000000..35f70ed1 --- /dev/null +++ b/src/linux/epoll.c @@ -0,0 +1,27 @@ +#include +#include "syscall.h" + +int epoll_create(int size) +{ + return syscall(SYS_epoll_create, size); +} + +int epoll_create1(int flags) +{ + return syscall(SYS_epoll_create1, flags); +} + +int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev) +{ + return syscall(SYS_epoll_ctl, fd, op, fd2, ev); +} + +int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs) +{ + return syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, __SYSCALL_SSLEN); +} + +int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to) +{ + return syscall(SYS_epoll_wait, fd, ev, cnt, to); +} diff --git a/src/linux/epoll_create.c b/src/linux/epoll_create.c deleted file mode 100644 index 29d82999..00000000 --- a/src/linux/epoll_create.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int epoll_create(int size) -{ - return syscall(SYS_epoll_create, size); -} diff --git a/src/linux/epoll_create1.c b/src/linux/epoll_create1.c deleted file mode 100644 index 380b5dad..00000000 --- a/src/linux/epoll_create1.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int epoll_create1(int flags) -{ - return syscall(SYS_epoll_create1, flags); -} diff --git a/src/linux/epoll_ctl.c b/src/linux/epoll_ctl.c deleted file mode 100644 index da3e999b..00000000 --- a/src/linux/epoll_ctl.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev) -{ - return syscall(SYS_epoll_ctl, fd, op, fd2, ev); -} diff --git a/src/linux/epoll_pwait.c b/src/linux/epoll_pwait.c deleted file mode 100644 index 3ecdbb59..00000000 --- a/src/linux/epoll_pwait.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs) -{ - return syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, __SYSCALL_SSLEN); -} diff --git a/src/linux/epoll_wait.c b/src/linux/epoll_wait.c deleted file mode 100644 index 9d3924e0..00000000 --- a/src/linux/epoll_wait.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to) -{ - return syscall(SYS_epoll_wait, fd, ev, cnt, to); -} diff --git a/src/linux/err.c b/src/linux/err.c deleted file mode 100644 index 0f748538..00000000 --- a/src/linux/err.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include - -void vwarn(const char *fmt, va_list ap) -{ - if (fmt) vfprintf(stderr, fmt, ap); - perror(""); -} - -void vwarnx(const char *fmt, va_list ap) -{ - if (fmt) vfprintf(stderr, fmt, ap); - putc('\n', stderr); -} - -_Noreturn void verr(int status, const char *fmt, va_list ap) -{ - vwarn(fmt, ap); - exit(status); -} - -_Noreturn void verrx(int status, const char *fmt, va_list ap) -{ - vwarnx(fmt, ap); - exit(status); -} - -void warn(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vwarn(fmt, ap); - va_end(ap); -} - -void warnx(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vwarnx(fmt, ap); - va_end(ap); -} - -_Noreturn void err(int status, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - verr(status, fmt, ap); - va_end(ap); -} - -_Noreturn void errx(int status, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - verrx(status, fmt, ap); - va_end(ap); -} diff --git a/src/linux/eventfd.c b/src/linux/eventfd.c index cb39a7ba..53066487 100644 --- a/src/linux/eventfd.c +++ b/src/linux/eventfd.c @@ -1,7 +1,18 @@ #include +#include #include "syscall.h" int eventfd(unsigned int count, int flags) { return syscall(flags ? SYS_eventfd2 : SYS_eventfd, count, flags); } + +int eventfd_read(int fd, eventfd_t *value) +{ + return (sizeof(*value) == read(fd, value, sizeof(*value))) ? 0 : -1; +} + +int eventfd_write(int fd, eventfd_t value) +{ + return (sizeof(value) == write(fd, &value, sizeof(value))) ? 0 : -1; +} diff --git a/src/linux/eventfd_read.c b/src/linux/eventfd_read.c deleted file mode 100644 index 969e6615..00000000 --- a/src/linux/eventfd_read.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int eventfd_read(int fd, eventfd_t *value) -{ - return (sizeof(*value) == read(fd, value, sizeof(*value))) ? 0 : -1; -} diff --git a/src/linux/eventfd_write.c b/src/linux/eventfd_write.c deleted file mode 100644 index 734fa367..00000000 --- a/src/linux/eventfd_write.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int eventfd_write(int fd, eventfd_t value) -{ - return (sizeof(value) == write(fd, &value, sizeof(value))) ? 0 : -1; -} diff --git a/src/linux/getdtablesize.c b/src/linux/getdtablesize.c deleted file mode 100644 index 623a6af3..00000000 --- a/src/linux/getdtablesize.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int getdtablesize(void) -{ - struct rlimit rl; - getrlimit(RLIMIT_NOFILE, &rl); - return rl.rlim_max < INT_MAX ? rl.rlim_max : INT_MAX; -} diff --git a/src/linux/gethostid.c b/src/linux/gethostid.c deleted file mode 100644 index ea65611a..00000000 --- a/src/linux/gethostid.c +++ /dev/null @@ -1,4 +0,0 @@ -long gethostid() -{ - return 0; -} diff --git a/src/linux/getopt_long.c b/src/linux/getopt_long.c deleted file mode 100644 index 6d3a4a6e..00000000 --- a/src/linux/getopt_long.c +++ /dev/null @@ -1,52 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include - -static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) -{ - if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1; - if ((longonly && argv[optind][1]) || - (argv[optind][1] == '-' && argv[optind][2])) - { - int i; - for (i=0; longopts[i].name; i++) { - const char *name = longopts[i].name; - char *opt = argv[optind]+1; - if (*opt == '-') opt++; - for (; *name && *name == *opt; name++, opt++); - if (*name || (*opt && *opt != '=')) continue; - if (*opt == '=') { - if (!longopts[i].has_arg) continue; - optarg = opt+1; - } else { - if (longopts[i].has_arg == required_argument) { - if (!(optarg = argv[++optind])) - return ':'; - } else optarg = NULL; - } - optind++; - if (idx) *idx = i; - if (longopts[i].flag) { - *longopts[i].flag = longopts[i].val; - return 0; - } - return longopts[i].val; - } - if (argv[optind][1] == '-') { - optind++; - return '?'; - } - } - return getopt(argc, argv, optstring); -} - -int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) -{ - return __getopt_long(argc, argv, optstring, longopts, idx, 0); -} - -int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) -{ - return __getopt_long(argc, argv, optstring, longopts, idx, 1); -} diff --git a/src/linux/getpagesize.c b/src/linux/getpagesize.c deleted file mode 100644 index 5ede652b..00000000 --- a/src/linux/getpagesize.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int getpagesize(void) -{ - return PAGE_SIZE; -} diff --git a/src/linux/getpass.c b/src/linux/getpass.c deleted file mode 100644 index d439a2a5..00000000 --- a/src/linux/getpass.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include -#include -#include - -char *getpass(const char *prompt) -{ - int fd; - struct termios s, t; - ssize_t l; - static char password[128]; - - if ((fd = open("/dev/tty", O_RDONLY|O_NOCTTY)) < 0) fd = 0; - - tcgetattr(fd, &t); - s = t; - t.c_lflag &= ~(ECHO|ISIG); - t.c_lflag |= ICANON; - t.c_iflag &= ~(INLCR|IGNCR); - t.c_iflag |= ICRNL; - tcsetattr(fd, TCSAFLUSH, &t); - tcdrain(fd); - - fputs(prompt, stderr); - fflush(stderr); - - l = read(fd, password, sizeof password); - if (l >= 0) { - if (l > 0 && password[l-1] == '\n') l--; - password[l] = 0; - } - - tcsetattr(fd, TCSAFLUSH, &s); - - if (fd > 2) close(fd); - - return password; -} diff --git a/src/linux/initgroups.c b/src/linux/initgroups.c deleted file mode 100644 index 545d1859..00000000 --- a/src/linux/initgroups.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include -#include - -int getgrouplist(const char *, gid_t, gid_t *, int *); -int setgroups(size_t, const gid_t *); - -int initgroups(const char *user, gid_t gid) -{ - gid_t groups[NGROUPS_MAX]; - int count = NGROUPS_MAX; - if (getgrouplist(user, gid, groups, &count) < 0) return -1; - return setgroups(count, groups); -} diff --git a/src/linux/inotify.c b/src/linux/inotify.c new file mode 100644 index 00000000..d3b4fa0b --- /dev/null +++ b/src/linux/inotify.c @@ -0,0 +1,21 @@ +#include +#include "syscall.h" + +int inotify_init() +{ + return syscall(SYS_inotify_init); +} +int inotify_init1(int flags) +{ + return syscall(SYS_inotify_init1, flags); +} + +int inotify_add_watch(int fd, const char *pathname, uint32_t mask) +{ + return syscall(SYS_inotify_add_watch, fd, pathname, mask); +} + +int inotify_rm_watch(int fd, uint32_t wd) +{ + return syscall(SYS_inotify_rm_watch, fd, wd); +} diff --git a/src/linux/inotify_add_watch.c b/src/linux/inotify_add_watch.c deleted file mode 100644 index 75f207d7..00000000 --- a/src/linux/inotify_add_watch.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int inotify_add_watch(int fd, const char *pathname, uint32_t mask) -{ - return syscall(SYS_inotify_add_watch, fd, pathname, mask); -} diff --git a/src/linux/inotify_init.c b/src/linux/inotify_init.c deleted file mode 100644 index 05070846..00000000 --- a/src/linux/inotify_init.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int inotify_init() -{ - return syscall(SYS_inotify_init); -} diff --git a/src/linux/inotify_init1.c b/src/linux/inotify_init1.c deleted file mode 100644 index 6472a7b2..00000000 --- a/src/linux/inotify_init1.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int inotify_init1(int flags) -{ - return syscall(SYS_inotify_init1, flags); -} diff --git a/src/linux/inotify_rm_watch.c b/src/linux/inotify_rm_watch.c deleted file mode 100644 index cba597eb..00000000 --- a/src/linux/inotify_rm_watch.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int inotify_rm_watch(int fd, uint32_t wd) -{ - return syscall(SYS_inotify_rm_watch, fd, wd); -} diff --git a/src/linux/mntent.c b/src/linux/mntent.c deleted file mode 100644 index 3eafba5e..00000000 --- a/src/linux/mntent.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -FILE *setmntent(const char *name, const char *mode) -{ - return fopen(name, mode); -} - -int endmntent(FILE *f) -{ - fclose(f); - return 1; -} - -struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen) -{ - int cnt, n[8]; - - mnt->mnt_freq = 0; - mnt->mnt_passno = 0; - - do { - fgets(linebuf, buflen, f); - if (feof(f) || ferror(f)) return 0; - if (!strchr(linebuf, '\n')) { - fscanf(f, "%*[^\n]%*[\n]"); - errno = ERANGE; - return 0; - } - cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", - n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, - &mnt->mnt_freq, &mnt->mnt_passno); - } while (cnt < 2 || linebuf[n[0]] == '#'); - - linebuf[n[1]] = 0; - linebuf[n[3]] = 0; - linebuf[n[5]] = 0; - linebuf[n[7]] = 0; - - mnt->mnt_fsname = linebuf+n[0]; - mnt->mnt_dir = linebuf+n[2]; - mnt->mnt_type = linebuf+n[4]; - mnt->mnt_opts = linebuf+n[6]; - - return mnt; -} - -struct mntent *getmntent(FILE *f) -{ - static char linebuf[256]; - static struct mntent mnt; - return getmntent_r(f, &mnt, linebuf, sizeof linebuf); -} - -int addmntent(FILE *f, const struct mntent *mnt) -{ - if (fseek(f, 0, SEEK_END)) return 1; - return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n", - mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts, - mnt->mnt_freq, mnt->mnt_passno) < 0; -} - -char *hasmntopt(const struct mntent *mnt, const char *opt) -{ - return strstr(mnt->mnt_opts, opt); -} diff --git a/src/linux/mount.c b/src/linux/mount.c index 83a8db44..34e11af1 100644 --- a/src/linux/mount.c +++ b/src/linux/mount.c @@ -5,3 +5,13 @@ int mount(const char *special, const char *dir, const char *fstype, unsigned lon { return syscall(SYS_mount, special, dir, fstype, flags, data); } + +int umount(const char *special) +{ + return syscall(SYS_umount2, special, 0); +} + +int umount2(const char *special, int flags) +{ + return syscall(SYS_umount2, special, flags); +} diff --git a/src/linux/prlimit.c b/src/linux/prlimit.c new file mode 100644 index 00000000..b9dbb446 --- /dev/null +++ b/src/linux/prlimit.c @@ -0,0 +1,8 @@ +#include +#include +#include "syscall.h" + +int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit) +{ + return syscall(SYS_prlimit64, pid, resource, new_limit, old_limit); +} diff --git a/src/linux/ptrace.c b/src/linux/ptrace.c new file mode 100644 index 00000000..83b8022b --- /dev/null +++ b/src/linux/ptrace.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include "syscall.h" + +long ptrace(int req, ...) +{ + va_list ap; + pid_t pid; + void *addr, *data, *addr2; + long ret, result; + + va_start(ap, req); + pid = va_arg(ap, pid_t); + addr = va_arg(ap, void *); + data = va_arg(ap, void *); + addr2 = va_arg(ap, void *); + va_end(ap); + + if (req-1U < 3) data = &result; + ret = syscall(SYS_ptrace, req, pid, addr, data, addr2); + + if (ret < 0 || req-1U >= 3) return ret; + return result; +} diff --git a/src/linux/swap.c b/src/linux/swap.c new file mode 100644 index 00000000..8137d51e --- /dev/null +++ b/src/linux/swap.c @@ -0,0 +1,12 @@ +#include +#include "syscall.h" + +int swapon(const char *path, int flags) +{ + return syscall(SYS_swapon, path, flags); +} + +int swapoff(const char *path) +{ + return syscall(SYS_swapoff, path); +} diff --git a/src/linux/swapoff.c b/src/linux/swapoff.c deleted file mode 100644 index 9f95e82d..00000000 --- a/src/linux/swapoff.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int swapoff(const char *path) -{ - return syscall(SYS_swapoff, path); -} diff --git a/src/linux/swapon.c b/src/linux/swapon.c deleted file mode 100644 index 2b40a30b..00000000 --- a/src/linux/swapon.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int swapon(const char *path, int flags) -{ - return syscall(SYS_swapon, path, flags); -} diff --git a/src/linux/syscall.c b/src/linux/syscall.c deleted file mode 100644 index 15355609..00000000 --- a/src/linux/syscall.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "syscall.h" -#include - -#undef syscall - -long syscall(long n, ...) -{ - va_list ap; - long a,b,c,d,e,f; - va_start(ap, n); - a=va_arg(ap, long); - b=va_arg(ap, long); - c=va_arg(ap, long); - d=va_arg(ap, long); - e=va_arg(ap, long); - f=va_arg(ap, long); - va_end(ap); - return __syscall_ret(__syscall(n,a,b,c,d,e,f)); -} diff --git a/src/linux/umount.c b/src/linux/umount.c deleted file mode 100644 index fb9b5e73..00000000 --- a/src/linux/umount.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int umount(const char *special) -{ - return syscall(SYS_umount2, special, 0); -} diff --git a/src/linux/umount2.c b/src/linux/umount2.c deleted file mode 100644 index 25ad057c..00000000 --- a/src/linux/umount2.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "syscall.h" - -int umount2(const char *special, int flags) -{ - return syscall(SYS_umount2, special, flags); -} diff --git a/src/misc/crypt.c b/src/misc/crypt.c deleted file mode 100644 index f1e310f6..00000000 --- a/src/misc/crypt.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -char *__crypt_r(const char *, const char *, struct crypt_data *); - -char *crypt(const char *key, const char *salt) -{ - /* Note: update this size when we add more hash types */ - static char buf[128]; - return __crypt_r(key, salt, (struct crypt_data *)buf); -} diff --git a/src/misc/crypt_blowfish.c b/src/misc/crypt_blowfish.c deleted file mode 100644 index bd37be84..00000000 --- a/src/misc/crypt_blowfish.c +++ /dev/null @@ -1,798 +0,0 @@ -/* Modified by Rich Felker in for inclusion in musl libc, based on - * Solar Designer's second size-optimized version sent to the musl - * mailing list. */ - -/* - * The crypt_blowfish homepage is: - * - * http://www.openwall.com/crypt/ - * - * This code comes from John the Ripper password cracker, with reentrant - * and crypt(3) interfaces added, but optimizations specific to password - * cracking removed. - * - * Written by Solar Designer in 1998-2012. - * No copyright is claimed, and the software is hereby placed in the public - * domain. In case this attempt to disclaim copyright and place the software - * in the public domain is deemed null and void, then the software is - * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * It is my intent that you should be able to use this on your system, - * as part of a software package, or anywhere else to improve security, - * ensure compatibility, or for any other purpose. I would appreciate - * it if you give credit where it is due and keep your modifications in - * the public domain as well, but I don't require that in order to let - * you place this code and any modifications you make under a license - * of your choice. - * - * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix - * "$2a$") by Niels Provos , and uses some of his - * ideas. The password hashing algorithm was designed by David Mazieres - * . For more information on the level of compatibility, - * please refer to the comments in BF_set_key() below and to the included - * crypt(3) man page. - * - * There's a paper on the algorithm that explains its design decisions: - * - * http://www.usenix.org/events/usenix99/provos.html - * - * Some of the tricks in BF_ROUND might be inspired by Eric Young's - * Blowfish library (I can't be sure if I would think of something if I - * hadn't seen his code). - */ - -#include -#include - -typedef uint32_t BF_word; -typedef int32_t 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]; - -typedef union { - struct { - BF_key P; - BF_word S[4][0x100]; - } s; - BF_word PS[BF_N + 2 + 4 * 0x100]; -} BF_ctx; - -/* - * Magic IV for 64 Blowfish encryptions that we do at the end. - * The string is "OrpheanBeholderScryDoubt" on big-endian. - */ -static const BF_word BF_magic_w[6] = { - 0x4F727068, 0x65616E42, 0x65686F6C, - 0x64657253, 0x63727944, 0x6F756274 -}; - -/* - * P-box and S-box tables initialized with digits of Pi. - */ -static const BF_ctx BF_init_state = {{ - { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b - }, { - { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - }, { - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - }, { - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - }, { - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - } - } -}}; - -static const unsigned char BF_itoa64[64 + 1] = - "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -static const unsigned char BF_atoi64[0x60] = { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, - 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, - 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -}; - -#define BF_safe_atoi64(dst, src) \ -{ \ - tmp = (unsigned char)(src); \ - if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ - tmp = BF_atoi64[tmp]; \ - if (tmp > 63) return -1; \ - (dst) = tmp; \ -} - -static int BF_decode(BF_word *dst, const char *src, int size) -{ - unsigned char *dptr = (unsigned char *)dst; - unsigned char *end = dptr + size; - const unsigned char *sptr = (const unsigned char *)src; - unsigned int tmp, c1, c2, c3, c4; - - do { - BF_safe_atoi64(c1, *sptr++); - BF_safe_atoi64(c2, *sptr++); - *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); - if (dptr >= end) break; - - BF_safe_atoi64(c3, *sptr++); - *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); - if (dptr >= end) break; - - BF_safe_atoi64(c4, *sptr++); - *dptr++ = ((c3 & 0x03) << 6) | c4; - } while (dptr < end); - - return 0; -} - -static void BF_encode(char *dst, const BF_word *src, int size) -{ - const unsigned char *sptr = (const unsigned char *)src; - const unsigned char *end = sptr + size; - unsigned char *dptr = (unsigned char *)dst; - unsigned int c1, c2; - - do { - c1 = *sptr++; - *dptr++ = BF_itoa64[c1 >> 2]; - c1 = (c1 & 0x03) << 4; - if (sptr >= end) { - *dptr++ = BF_itoa64[c1]; - break; - } - - c2 = *sptr++; - c1 |= c2 >> 4; - *dptr++ = BF_itoa64[c1]; - c1 = (c2 & 0x0f) << 2; - if (sptr >= end) { - *dptr++ = BF_itoa64[c1]; - break; - } - - c2 = *sptr++; - c1 |= c2 >> 6; - *dptr++ = BF_itoa64[c1]; - *dptr++ = BF_itoa64[c2 & 0x3f]; - } while (sptr < end); -} - -static void BF_swap(BF_word *x, int count) -{ - if ((union { int i; char c; }){1}.c) - do { - BF_word tmp = *x; - tmp = (tmp << 16) | (tmp >> 16); - *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); - } while (--count); -} - -#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; - -static BF_word BF_encrypt(BF_ctx *ctx, - BF_word L, BF_word R, - BF_word *start, BF_word *end) -{ - BF_word tmp1, tmp2, tmp3, tmp4; - BF_word *ptr = start; - - do { - L ^= ctx->s.P[0]; -#if 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); -#else - for (int i=0; i<16; i+=2) { - BF_ROUND(L, R, i); - BF_ROUND(R, L, i+1); - } -#endif - tmp4 = R; - R = L; - L = tmp4 ^ ctx->s.P[BF_N + 1]; - *ptr++ = L; - *ptr++ = R; - } while (ptr < end); - - return L; -} - -static void BF_set_key(const char *key, BF_key expanded, BF_key initial, - unsigned char flags) -{ - const char *ptr = key; - unsigned int bug, i, j; - BF_word safety, sign, diff, tmp[2]; - -/* - * There was a sign extension bug in older revisions of this function. While - * we would have liked to simply fix the bug and move on, we have to provide - * a backwards compatibility feature (essentially the bug) for some systems and - * a safety measure for some others. The latter is needed because for certain - * multiple inputs to the buggy algorithm there exist easily found inputs to - * the correct algorithm that produce the same hash. Thus, we optionally - * deviate from the correct algorithm just enough to avoid such collisions. - * While the bug itself affected the majority of passwords containing - * characters with the 8th bit set (although only a percentage of those in a - * collision-producing way), the anti-collision safety measure affects - * only a subset of passwords containing the '\xff' character (not even all of - * those passwords, just some of them). This character is not found in valid - * UTF-8 sequences and is rarely used in popular 8-bit character encodings. - * Thus, the safety measure is unlikely to cause much annoyance, and is a - * reasonable tradeoff to use when authenticating against existing hashes that - * are not reliably known to have been computed with the correct algorithm. - * - * We use an approach that tries to minimize side-channel leaks of password - * information - that is, we mostly use fixed-cost bitwise operations instead - * of branches or table lookups. (One conditional branch based on password - * length remains. It is not part of the bug aftermath, though, and is - * difficult and possibly unreasonable to avoid given the use of C strings by - * the caller, which results in similar timing leaks anyway.) - * - * For actual implementation, we set an array index in the variable "bug" - * (0 means no bug, 1 means sign extension bug emulation) and a flag in the - * variable "safety" (bit 16 is set when the safety measure is requested). - * Valid combinations of settings are: - * - * Prefix "$2a$": bug = 0, safety = 0x10000 - * Prefix "$2x$": bug = 1, safety = 0 - * Prefix "$2y$": bug = 0, safety = 0 - */ - bug = flags & 1; - safety = ((BF_word)flags & 2) << 15; - - sign = diff = 0; - - for (i = 0; i < BF_N + 2; i++) { - tmp[0] = tmp[1] = 0; - for (j = 0; j < 4; j++) { - tmp[0] <<= 8; - tmp[0] |= (unsigned char)*ptr; /* correct */ - tmp[1] <<= 8; - tmp[1] |= (signed char)*ptr; /* bug */ -/* - * Sign extension in the first char has no effect - nothing to overwrite yet, - * and those extra 24 bits will be fully shifted out of the 32-bit word. For - * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign - * extension in tmp[1] occurs. Once this flag is set, it remains set. - */ - if (j) - sign |= tmp[1] & 0x80; - if (!*ptr) - ptr = key; - else - ptr++; - } - diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */ - - expanded[i] = tmp[bug]; - initial[i] = BF_init_state.s.P[i] ^ tmp[bug]; - } - -/* - * At this point, "diff" is zero iff the correct and buggy algorithms produced - * exactly the same result. If so and if "sign" is non-zero, which indicates - * that there was a non-benign sign extension, this means that we have a - * collision between the correctly computed hash for this password and a set of - * passwords that could be supplied to the buggy algorithm. Our safety measure - * is meant to protect from such many-buggy to one-correct collisions, by - * deviating from the correct algorithm in such cases. Let's check for this. - */ - diff |= diff >> 16; /* still zero iff exact match */ - diff &= 0xffff; /* ditto */ - diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */ - sign <<= 9; /* move the non-benign sign extension flag to bit 16 */ - sign &= ~diff & safety; /* action needed? */ - -/* - * If we have determined that we need to deviate from the correct algorithm, - * flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but - * let's stick to it now. It came out of the approach we used above, and it's - * not any worse than any other choice we could make.) - * - * It is crucial that we don't do the same to the expanded key used in the main - * Eksblowfish loop. By doing it to only one of these two, we deviate from a - * state that could be directly specified by a password to the buggy algorithm - * (and to the fully correct one as well, but that's a side-effect). - */ - initial[0] ^= sign; -} - -static char *BF_crypt(const char *key, const char *setting, - char *output, BF_word min) -{ - static const unsigned char flags_by_subtype[26] = - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0}; - struct { - BF_ctx ctx; - BF_key expanded_key; - union { - BF_word salt[4]; - BF_word output[6]; - } binary; - } data; - BF_word count; - int i; - - if (setting[0] != '$' || - setting[1] != '2' || - setting[2] - 'a' > 25U || - !flags_by_subtype[setting[2] - 'a'] || - setting[3] != '$' || - setting[4] - '0' > 1U || - setting[5] - '0' > 9U || - setting[6] != '$') { - return NULL; - } - - count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); - if (count < min || count > 2048 || BF_decode(data.binary.salt, &setting[7], 16)) { - return NULL; - } - BF_swap(data.binary.salt, 4); - - BF_set_key(key, data.expanded_key, data.ctx.s.P, - flags_by_subtype[setting[2] - 'a']); - - memcpy(data.ctx.s.S, BF_init_state.s.S, sizeof(data.ctx.s.S)); - - { - BF_word L = 0, R = 0; - BF_word *ptr = &data.ctx.PS[0]; - 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); - } - - 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); - } while (--count); - - for (i = 0; i < 6; i += 2) { - BF_word L, LR[2]; - - L = BF_magic_w[i]; - LR[1] = BF_magic_w[i + 1]; - - count = 64; - do { - L = BF_encrypt(&data.ctx, L, LR[1], - &LR[0], &LR[0]); - } while (--count); - - data.binary.output[i] = L; - data.binary.output[i + 1] = LR[1]; - } - - memcpy(output, setting, 7 + 22 - 1); - output[7 + 22 - 1] = BF_itoa64[ - BF_atoi64[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'; - - return output; -} - -/* - * Please preserve the runtime self-test. It serves two purposes at once: - * - * 1. We really can't afford the risk of producing incompatible hashes e.g. - * when there's something like gcc bug 26587 again, whereas an application or - * library integrating this code might not also integrate our external tests or - * it might not run them after every build. Even if it does, the miscompile - * might only occur on the production build, but not on a testing build (such - * as because of different optimization settings). It is painful to recover - * from incorrectly-computed hashes - merely fixing whatever broke is not - * enough. Thus, a proactive measure like this self-test is needed. - * - * 2. We don't want to leave sensitive data from our actual password hash - * computation on the stack or in registers. Previous revisions of the code - * would do explicit cleanups, but simply running the self-test after hash - * computation is more reliable. - * - * The performance cost of this quick self-test is around 0.6% at the "$2a$08" - * setting. - */ -char *__crypt_blowfish(const char *key, const char *setting, char *output) -{ - const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8"; - const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu"; - static const char test_hash[2][34] = - {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */ - "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */ - char *retval; - const char *p; - int ok; - struct { - char s[7 + 22 + 1]; - char o[7 + 22 + 31 + 1 + 1 + 1]; - } buf; - -/* Hash the supplied password */ - retval = BF_crypt(key, setting, output, 16); - -/* - * Do a quick self-test. It is important that we make both calls to BF_crypt() - * from the same scope such that they likely use the same stack locations, - * which makes the second call overwrite the first call's sensitive data on the - * stack and makes it more likely that any alignment related issues would be - * detected by the self-test. - */ - memcpy(buf.s, test_setting, sizeof(buf.s)); - if (retval) - buf.s[2] = setting[2]; - memset(buf.o, 0x55, sizeof(buf.o)); - buf.o[sizeof(buf.o) - 1] = 0; - p = BF_crypt(test_key, buf.s, buf.o, 1); - - ok = (p == buf.o && - !memcmp(p, buf.s, 7 + 22) && - !memcmp(p + (7 + 22), - test_hash[buf.s[2] & 1], - 31 + 1 + 1 + 1)); - - { - const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345"; - BF_key ae, ai, ye, yi; - BF_set_key(k, ae, ai, 2); /* $2a$ */ - BF_set_key(k, ye, yi, 4); /* $2y$ */ - ai[0] ^= 0x10000; /* undo the safety (for comparison) */ - ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 && - !memcmp(ae, ye, sizeof(ae)) && - !memcmp(ai, yi, sizeof(ai)); - } - - if (ok && retval) - return retval; - - return "*"; -} diff --git a/src/misc/crypt_des.c b/src/misc/crypt_des.c deleted file mode 100644 index d7b2b15a..00000000 --- a/src/misc/crypt_des.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * This version has been further modified by Rich Felker, primary author - * and maintainer of musl libc, to remove table generation code and - * replaced all runtime-generated constant tables with static-initialized - * tables in the binary, in the interest of minimizing non-shareable - * memory usage and stack size requirements. - */ -/* - * This version is derived from the original implementation of FreeSec - * (release 1.1) by David Burren. I've made it reentrant, reduced its memory - * usage from about 70 KB to about 7 KB (with only minimal performance impact - * and keeping code size about the same), made the handling of invalid salts - * mostly UFC-crypt compatible, added a quick runtime self-test (which also - * serves to zeroize the stack from sensitive data), and added optional tests. - * - Solar Designer - */ - -/* - * FreeSec: libcrypt for NetBSD - * - * Copyright (c) 1994 David Burren - * Copyright (c) 2000,2002,2010,2012 Solar Designer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $ - * $Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp $ - * - * This is an original implementation of the DES and the crypt(3) interfaces - * by David Burren. It has been heavily re-worked by Solar Designer. - */ - -#include -#include - -struct expanded_key { - uint32_t l[16], r[16]; -}; - -#define _PASSWORD_EFMT1 '_' - -static const unsigned char key_shifts[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -static const uint32_t psbox[8][64] = { - { - 0x00808200,0x00000000,0x00008000,0x00808202, - 0x00808002,0x00008202,0x00000002,0x00008000, - 0x00000200,0x00808200,0x00808202,0x00000200, - 0x00800202,0x00808002,0x00800000,0x00000002, - 0x00000202,0x00800200,0x00800200,0x00008200, - 0x00008200,0x00808000,0x00808000,0x00800202, - 0x00008002,0x00800002,0x00800002,0x00008002, - 0x00000000,0x00000202,0x00008202,0x00800000, - 0x00008000,0x00808202,0x00000002,0x00808000, - 0x00808200,0x00800000,0x00800000,0x00000200, - 0x00808002,0x00008000,0x00008200,0x00800002, - 0x00000200,0x00000002,0x00800202,0x00008202, - 0x00808202,0x00008002,0x00808000,0x00800202, - 0x00800002,0x00000202,0x00008202,0x00808200, - 0x00000202,0x00800200,0x00800200,0x00000000, - 0x00008002,0x00008200,0x00000000,0x00808002, - },{ - 0x40084010,0x40004000,0x00004000,0x00084010, - 0x00080000,0x00000010,0x40080010,0x40004010, - 0x40000010,0x40084010,0x40084000,0x40000000, - 0x40004000,0x00080000,0x00000010,0x40080010, - 0x00084000,0x00080010,0x40004010,0x00000000, - 0x40000000,0x00004000,0x00084010,0x40080000, - 0x00080010,0x40000010,0x00000000,0x00084000, - 0x00004010,0x40084000,0x40080000,0x00004010, - 0x00000000,0x00084010,0x40080010,0x00080000, - 0x40004010,0x40080000,0x40084000,0x00004000, - 0x40080000,0x40004000,0x00000010,0x40084010, - 0x00084010,0x00000010,0x00004000,0x40000000, - 0x00004010,0x40084000,0x00080000,0x40000010, - 0x00080010,0x40004010,0x40000010,0x00080010, - 0x00084000,0x00000000,0x40004000,0x00004010, - 0x40000000,0x40080010,0x40084010,0x00084000, - },{ - 0x00000104,0x04010100,0x00000000,0x04010004, - 0x04000100,0x00000000,0x00010104,0x04000100, - 0x00010004,0x04000004,0x04000004,0x00010000, - 0x04010104,0x00010004,0x04010000,0x00000104, - 0x04000000,0x00000004,0x04010100,0x00000100, - 0x00010100,0x04010000,0x04010004,0x00010104, - 0x04000104,0x00010100,0x00010000,0x04000104, - 0x00000004,0x04010104,0x00000100,0x04000000, - 0x04010100,0x04000000,0x00010004,0x00000104, - 0x00010000,0x04010100,0x04000100,0x00000000, - 0x00000100,0x00010004,0x04010104,0x04000100, - 0x04000004,0x00000100,0x00000000,0x04010004, - 0x04000104,0x00010000,0x04000000,0x04010104, - 0x00000004,0x00010104,0x00010100,0x04000004, - 0x04010000,0x04000104,0x00000104,0x04010000, - 0x00010104,0x00000004,0x04010004,0x00010100, - },{ - 0x80401000,0x80001040,0x80001040,0x00000040, - 0x00401040,0x80400040,0x80400000,0x80001000, - 0x00000000,0x00401000,0x00401000,0x80401040, - 0x80000040,0x00000000,0x00400040,0x80400000, - 0x80000000,0x00001000,0x00400000,0x80401000, - 0x00000040,0x00400000,0x80001000,0x00001040, - 0x80400040,0x80000000,0x00001040,0x00400040, - 0x00001000,0x00401040,0x80401040,0x80000040, - 0x00400040,0x80400000,0x00401000,0x80401040, - 0x80000040,0x00000000,0x00000000,0x00401000, - 0x00001040,0x00400040,0x80400040,0x80000000, - 0x80401000,0x80001040,0x80001040,0x00000040, - 0x80401040,0x80000040,0x80000000,0x00001000, - 0x80400000,0x80001000,0x00401040,0x80400040, - 0x80001000,0x00001040,0x00400000,0x80401000, - 0x00000040,0x00400000,0x00001000,0x00401040, - },{ - 0x00000080,0x01040080,0x01040000,0x21000080, - 0x00040000,0x00000080,0x20000000,0x01040000, - 0x20040080,0x00040000,0x01000080,0x20040080, - 0x21000080,0x21040000,0x00040080,0x20000000, - 0x01000000,0x20040000,0x20040000,0x00000000, - 0x20000080,0x21040080,0x21040080,0x01000080, - 0x21040000,0x20000080,0x00000000,0x21000000, - 0x01040080,0x01000000,0x21000000,0x00040080, - 0x00040000,0x21000080,0x00000080,0x01000000, - 0x20000000,0x01040000,0x21000080,0x20040080, - 0x01000080,0x20000000,0x21040000,0x01040080, - 0x20040080,0x00000080,0x01000000,0x21040000, - 0x21040080,0x00040080,0x21000000,0x21040080, - 0x01040000,0x00000000,0x20040000,0x21000000, - 0x00040080,0x01000080,0x20000080,0x00040000, - 0x00000000,0x20040000,0x01040080,0x20000080, - },{ - 0x10000008,0x10200000,0x00002000,0x10202008, - 0x10200000,0x00000008,0x10202008,0x00200000, - 0x10002000,0x00202008,0x00200000,0x10000008, - 0x00200008,0x10002000,0x10000000,0x00002008, - 0x00000000,0x00200008,0x10002008,0x00002000, - 0x00202000,0x10002008,0x00000008,0x10200008, - 0x10200008,0x00000000,0x00202008,0x10202000, - 0x00002008,0x00202000,0x10202000,0x10000000, - 0x10002000,0x00000008,0x10200008,0x00202000, - 0x10202008,0x00200000,0x00002008,0x10000008, - 0x00200000,0x10002000,0x10000000,0x00002008, - 0x10000008,0x10202008,0x00202000,0x10200000, - 0x00202008,0x10202000,0x00000000,0x10200008, - 0x00000008,0x00002000,0x10200000,0x00202008, - 0x00002000,0x00200008,0x10002008,0x00000000, - 0x10202000,0x10000000,0x00200008,0x10002008, - },{ - 0x00100000,0x02100001,0x02000401,0x00000000, - 0x00000400,0x02000401,0x00100401,0x02100400, - 0x02100401,0x00100000,0x00000000,0x02000001, - 0x00000001,0x02000000,0x02100001,0x00000401, - 0x02000400,0x00100401,0x00100001,0x02000400, - 0x02000001,0x02100000,0x02100400,0x00100001, - 0x02100000,0x00000400,0x00000401,0x02100401, - 0x00100400,0x00000001,0x02000000,0x00100400, - 0x02000000,0x00100400,0x00100000,0x02000401, - 0x02000401,0x02100001,0x02100001,0x00000001, - 0x00100001,0x02000000,0x02000400,0x00100000, - 0x02100400,0x00000401,0x00100401,0x02100400, - 0x00000401,0x02000001,0x02100401,0x02100000, - 0x00100400,0x00000000,0x00000001,0x02100401, - 0x00000000,0x00100401,0x02100000,0x00000400, - 0x02000001,0x02000400,0x00000400,0x00100001, - },{ - 0x08000820,0x00000800,0x00020000,0x08020820, - 0x08000000,0x08000820,0x00000020,0x08000000, - 0x00020020,0x08020000,0x08020820,0x00020800, - 0x08020800,0x00020820,0x00000800,0x00000020, - 0x08020000,0x08000020,0x08000800,0x00000820, - 0x00020800,0x00020020,0x08020020,0x08020800, - 0x00000820,0x00000000,0x00000000,0x08020020, - 0x08000020,0x08000800,0x00020820,0x00020000, - 0x00020820,0x00020000,0x08020800,0x00000800, - 0x00000020,0x08020020,0x00000800,0x00020820, - 0x08000800,0x00000020,0x08000020,0x08020000, - 0x08020020,0x08000000,0x00020000,0x08000820, - 0x00000000,0x08020820,0x00020020,0x08000020, - 0x08020000,0x08000800,0x08000820,0x00000000, - 0x08020820,0x00020800,0x00020800,0x00000820, - 0x00000820,0x00020020,0x08000000,0x08020800, - }, -}; -static const uint32_t ip_maskl[16][16] = { - { - 0x00000000,0x00010000,0x00000000,0x00010000, - 0x01000000,0x01010000,0x01000000,0x01010000, - 0x00000000,0x00010000,0x00000000,0x00010000, - 0x01000000,0x01010000,0x01000000,0x01010000, - },{ - 0x00000000,0x00000001,0x00000000,0x00000001, - 0x00000100,0x00000101,0x00000100,0x00000101, - 0x00000000,0x00000001,0x00000000,0x00000001, - 0x00000100,0x00000101,0x00000100,0x00000101, - },{ - 0x00000000,0x00020000,0x00000000,0x00020000, - 0x02000000,0x02020000,0x02000000,0x02020000, - 0x00000000,0x00020000,0x00000000,0x00020000, - 0x02000000,0x02020000,0x02000000,0x02020000, - },{ - 0x00000000,0x00000002,0x00000000,0x00000002, - 0x00000200,0x00000202,0x00000200,0x00000202, - 0x00000000,0x00000002,0x00000000,0x00000002, - 0x00000200,0x00000202,0x00000200,0x00000202, - },{ - 0x00000000,0x00040000,0x00000000,0x00040000, - 0x04000000,0x04040000,0x04000000,0x04040000, - 0x00000000,0x00040000,0x00000000,0x00040000, - 0x04000000,0x04040000,0x04000000,0x04040000, - },{ - 0x00000000,0x00000004,0x00000000,0x00000004, - 0x00000400,0x00000404,0x00000400,0x00000404, - 0x00000000,0x00000004,0x00000000,0x00000004, - 0x00000400,0x00000404,0x00000400,0x00000404, - },{ - 0x00000000,0x00080000,0x00000000,0x00080000, - 0x08000000,0x08080000,0x08000000,0x08080000, - 0x00000000,0x00080000,0x00000000,0x00080000, - 0x08000000,0x08080000,0x08000000,0x08080000, - },{ - 0x00000000,0x00000008,0x00000000,0x00000008, - 0x00000800,0x00000808,0x00000800,0x00000808, - 0x00000000,0x00000008,0x00000000,0x00000008, - 0x00000800,0x00000808,0x00000800,0x00000808, - },{ - 0x00000000,0x00100000,0x00000000,0x00100000, - 0x10000000,0x10100000,0x10000000,0x10100000, - 0x00000000,0x00100000,0x00000000,0x00100000, - 0x10000000,0x10100000,0x10000000,0x10100000, - },{ - 0x00000000,0x00000010,0x00000000,0x00000010, - 0x00001000,0x00001010,0x00001000,0x00001010, - 0x00000000,0x00000010,0x00000000,0x00000010, - 0x00001000,0x00001010,0x00001000,0x00001010, - },{ - 0x00000000,0x00200000,0x00000000,0x00200000, - 0x20000000,0x20200000,0x20000000,0x20200000, - 0x00000000,0x00200000,0x00000000,0x00200000, - 0x20000000,0x20200000,0x20000000,0x20200000, - },{ - 0x00000000,0x00000020,0x00000000,0x00000020, - 0x00002000,0x00002020,0x00002000,0x00002020, - 0x00000000,0x00000020,0x00000000,0x00000020, - 0x00002000,0x00002020,0x00002000,0x00002020, - },{ - 0x00000000,0x00400000,0x00000000,0x00400000, - 0x40000000,0x40400000,0x40000000,0x40400000, - 0x00000000,0x00400000,0x00000000,0x00400000, - 0x40000000,0x40400000,0x40000000,0x40400000, - },{ - 0x00000000,0x00000040,0x00000000,0x00000040, - 0x00004000,0x00004040,0x00004000,0x00004040, - 0x00000000,0x00000040,0x00000000,0x00000040, - 0x00004000,0x00004040,0x00004000,0x00004040, - },{ - 0x00000000,0x00800000,0x00000000,0x00800000, - 0x80000000,0x80800000,0x80000000,0x80800000, - 0x00000000,0x00800000,0x00000000,0x00800000, - 0x80000000,0x80800000,0x80000000,0x80800000, - },{ - 0x00000000,0x00000080,0x00000000,0x00000080, - 0x00008000,0x00008080,0x00008000,0x00008080, - 0x00000000,0x00000080,0x00000000,0x00000080, - 0x00008000,0x00008080,0x00008000,0x00008080, - }, -}; -static const uint32_t ip_maskr[16][16] = { - { - 0x00000000,0x00000000,0x00010000,0x00010000, - 0x00000000,0x00000000,0x00010000,0x00010000, - 0x01000000,0x01000000,0x01010000,0x01010000, - 0x01000000,0x01000000,0x01010000,0x01010000, - },{ - 0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000100,0x00000100,0x00000101,0x00000101, - 0x00000100,0x00000100,0x00000101,0x00000101, - },{ - 0x00000000,0x00000000,0x00020000,0x00020000, - 0x00000000,0x00000000,0x00020000,0x00020000, - 0x02000000,0x02000000,0x02020000,0x02020000, - 0x02000000,0x02000000,0x02020000,0x02020000, - },{ - 0x00000000,0x00000000,0x00000002,0x00000002, - 0x00000000,0x00000000,0x00000002,0x00000002, - 0x00000200,0x00000200,0x00000202,0x00000202, - 0x00000200,0x00000200,0x00000202,0x00000202, - },{ - 0x00000000,0x00000000,0x00040000,0x00040000, - 0x00000000,0x00000000,0x00040000,0x00040000, - 0x04000000,0x04000000,0x04040000,0x04040000, - 0x04000000,0x04000000,0x04040000,0x04040000, - },{ - 0x00000000,0x00000000,0x00000004,0x00000004, - 0x00000000,0x00000000,0x00000004,0x00000004, - 0x00000400,0x00000400,0x00000404,0x00000404, - 0x00000400,0x00000400,0x00000404,0x00000404, - },{ - 0x00000000,0x00000000,0x00080000,0x00080000, - 0x00000000,0x00000000,0x00080000,0x00080000, - 0x08000000,0x08000000,0x08080000,0x08080000, - 0x08000000,0x08000000,0x08080000,0x08080000, - },{ - 0x00000000,0x00000000,0x00000008,0x00000008, - 0x00000000,0x00000000,0x00000008,0x00000008, - 0x00000800,0x00000800,0x00000808,0x00000808, - 0x00000800,0x00000800,0x00000808,0x00000808, - },{ - 0x00000000,0x00000000,0x00100000,0x00100000, - 0x00000000,0x00000000,0x00100000,0x00100000, - 0x10000000,0x10000000,0x10100000,0x10100000, - 0x10000000,0x10000000,0x10100000,0x10100000, - },{ - 0x00000000,0x00000000,0x00000010,0x00000010, - 0x00000000,0x00000000,0x00000010,0x00000010, - 0x00001000,0x00001000,0x00001010,0x00001010, - 0x00001000,0x00001000,0x00001010,0x00001010, - },{ - 0x00000000,0x00000000,0x00200000,0x00200000, - 0x00000000,0x00000000,0x00200000,0x00200000, - 0x20000000,0x20000000,0x20200000,0x20200000, - 0x20000000,0x20000000,0x20200000,0x20200000, - },{ - 0x00000000,0x00000000,0x00000020,0x00000020, - 0x00000000,0x00000000,0x00000020,0x00000020, - 0x00002000,0x00002000,0x00002020,0x00002020, - 0x00002000,0x00002000,0x00002020,0x00002020, - },{ - 0x00000000,0x00000000,0x00400000,0x00400000, - 0x00000000,0x00000000,0x00400000,0x00400000, - 0x40000000,0x40000000,0x40400000,0x40400000, - 0x40000000,0x40000000,0x40400000,0x40400000, - },{ - 0x00000000,0x00000000,0x00000040,0x00000040, - 0x00000000,0x00000000,0x00000040,0x00000040, - 0x00004000,0x00004000,0x00004040,0x00004040, - 0x00004000,0x00004000,0x00004040,0x00004040, - },{ - 0x00000000,0x00000000,0x00800000,0x00800000, - 0x00000000,0x00000000,0x00800000,0x00800000, - 0x80000000,0x80000000,0x80800000,0x80800000, - 0x80000000,0x80000000,0x80800000,0x80800000, - },{ - 0x00000000,0x00000000,0x00000080,0x00000080, - 0x00000000,0x00000000,0x00000080,0x00000080, - 0x00008000,0x00008000,0x00008080,0x00008080, - 0x00008000,0x00008000,0x00008080,0x00008080, - }, -}; -static const uint32_t fp_maskl[8][16] = { - { - 0x00000000,0x40000000,0x00400000,0x40400000, - 0x00004000,0x40004000,0x00404000,0x40404000, - 0x00000040,0x40000040,0x00400040,0x40400040, - 0x00004040,0x40004040,0x00404040,0x40404040, - },{ - 0x00000000,0x10000000,0x00100000,0x10100000, - 0x00001000,0x10001000,0x00101000,0x10101000, - 0x00000010,0x10000010,0x00100010,0x10100010, - 0x00001010,0x10001010,0x00101010,0x10101010, - },{ - 0x00000000,0x04000000,0x00040000,0x04040000, - 0x00000400,0x04000400,0x00040400,0x04040400, - 0x00000004,0x04000004,0x00040004,0x04040004, - 0x00000404,0x04000404,0x00040404,0x04040404, - },{ - 0x00000000,0x01000000,0x00010000,0x01010000, - 0x00000100,0x01000100,0x00010100,0x01010100, - 0x00000001,0x01000001,0x00010001,0x01010001, - 0x00000101,0x01000101,0x00010101,0x01010101, - },{ - 0x00000000,0x80000000,0x00800000,0x80800000, - 0x00008000,0x80008000,0x00808000,0x80808000, - 0x00000080,0x80000080,0x00800080,0x80800080, - 0x00008080,0x80008080,0x00808080,0x80808080, - },{ - 0x00000000,0x20000000,0x00200000,0x20200000, - 0x00002000,0x20002000,0x00202000,0x20202000, - 0x00000020,0x20000020,0x00200020,0x20200020, - 0x00002020,0x20002020,0x00202020,0x20202020, - },{ - 0x00000000,0x08000000,0x00080000,0x08080000, - 0x00000800,0x08000800,0x00080800,0x08080800, - 0x00000008,0x08000008,0x00080008,0x08080008, - 0x00000808,0x08000808,0x00080808,0x08080808, - },{ - 0x00000000,0x02000000,0x00020000,0x02020000, - 0x00000200,0x02000200,0x00020200,0x02020200, - 0x00000002,0x02000002,0x00020002,0x02020002, - 0x00000202,0x02000202,0x00020202,0x02020202, - }, -}; -static const uint32_t fp_maskr[8][16] = { - { - 0x00000000,0x40000000,0x00400000,0x40400000, - 0x00004000,0x40004000,0x00404000,0x40404000, - 0x00000040,0x40000040,0x00400040,0x40400040, - 0x00004040,0x40004040,0x00404040,0x40404040, - },{ - 0x00000000,0x10000000,0x00100000,0x10100000, - 0x00001000,0x10001000,0x00101000,0x10101000, - 0x00000010,0x10000010,0x00100010,0x10100010, - 0x00001010,0x10001010,0x00101010,0x10101010, - },{ - 0x00000000,0x04000000,0x00040000,0x04040000, - 0x00000400,0x04000400,0x00040400,0x04040400, - 0x00000004,0x04000004,0x00040004,0x04040004, - 0x00000404,0x04000404,0x00040404,0x04040404, - },{ - 0x00000000,0x01000000,0x00010000,0x01010000, - 0x00000100,0x01000100,0x00010100,0x01010100, - 0x00000001,0x01000001,0x00010001,0x01010001, - 0x00000101,0x01000101,0x00010101,0x01010101, - },{ - 0x00000000,0x80000000,0x00800000,0x80800000, - 0x00008000,0x80008000,0x00808000,0x80808000, - 0x00000080,0x80000080,0x00800080,0x80800080, - 0x00008080,0x80008080,0x00808080,0x80808080, - },{ - 0x00000000,0x20000000,0x00200000,0x20200000, - 0x00002000,0x20002000,0x00202000,0x20202000, - 0x00000020,0x20000020,0x00200020,0x20200020, - 0x00002020,0x20002020,0x00202020,0x20202020, - },{ - 0x00000000,0x08000000,0x00080000,0x08080000, - 0x00000800,0x08000800,0x00080800,0x08080800, - 0x00000008,0x08000008,0x00080008,0x08080008, - 0x00000808,0x08000808,0x00080808,0x08080808, - },{ - 0x00000000,0x02000000,0x00020000,0x02020000, - 0x00000200,0x02000200,0x00020200,0x02020200, - 0x00000002,0x02000002,0x00020002,0x02020002, - 0x00000202,0x02000202,0x00020202,0x02020202, - }, -}; -static const uint32_t key_perm_maskl[8][16] = { - { - 0x00000000,0x00000000,0x00000010,0x00000010, - 0x00001000,0x00001000,0x00001010,0x00001010, - 0x00100000,0x00100000,0x00100010,0x00100010, - 0x00101000,0x00101000,0x00101010,0x00101010, - },{ - 0x00000000,0x00000000,0x00000020,0x00000020, - 0x00002000,0x00002000,0x00002020,0x00002020, - 0x00200000,0x00200000,0x00200020,0x00200020, - 0x00202000,0x00202000,0x00202020,0x00202020, - },{ - 0x00000000,0x00000000,0x00000040,0x00000040, - 0x00004000,0x00004000,0x00004040,0x00004040, - 0x00400000,0x00400000,0x00400040,0x00400040, - 0x00404000,0x00404000,0x00404040,0x00404040, - },{ - 0x00000000,0x00000000,0x00000080,0x00000080, - 0x00008000,0x00008000,0x00008080,0x00008080, - 0x00800000,0x00800000,0x00800080,0x00800080, - 0x00808000,0x00808000,0x00808080,0x00808080, - },{ - 0x00000000,0x00000001,0x00000100,0x00000101, - 0x00010000,0x00010001,0x00010100,0x00010101, - 0x01000000,0x01000001,0x01000100,0x01000101, - 0x01010000,0x01010001,0x01010100,0x01010101, - },{ - 0x00000000,0x00000002,0x00000200,0x00000202, - 0x00020000,0x00020002,0x00020200,0x00020202, - 0x02000000,0x02000002,0x02000200,0x02000202, - 0x02020000,0x02020002,0x02020200,0x02020202, - },{ - 0x00000000,0x00000004,0x00000400,0x00000404, - 0x00040000,0x00040004,0x00040400,0x00040404, - 0x04000000,0x04000004,0x04000400,0x04000404, - 0x04040000,0x04040004,0x04040400,0x04040404, - },{ - 0x00000000,0x00000008,0x00000800,0x00000808, - 0x00080000,0x00080008,0x00080800,0x00080808, - 0x08000000,0x08000008,0x08000800,0x08000808, - 0x08080000,0x08080008,0x08080800,0x08080808, - }, -}; -static const uint32_t key_perm_maskr[12][16] = { - { - 0x00000000,0x00000001,0x00000000,0x00000001, - 0x00000000,0x00000001,0x00000000,0x00000001, - 0x00000000,0x00000001,0x00000000,0x00000001, - 0x00000000,0x00000001,0x00000000,0x00000001, - },{ - 0x00000000,0x00000000,0x00100000,0x00100000, - 0x00001000,0x00001000,0x00101000,0x00101000, - 0x00000010,0x00000010,0x00100010,0x00100010, - 0x00001010,0x00001010,0x00101010,0x00101010, - },{ - 0x00000000,0x00000002,0x00000000,0x00000002, - 0x00000000,0x00000002,0x00000000,0x00000002, - 0x00000000,0x00000002,0x00000000,0x00000002, - 0x00000000,0x00000002,0x00000000,0x00000002, - },{ - 0x00000000,0x00000000,0x00200000,0x00200000, - 0x00002000,0x00002000,0x00202000,0x00202000, - 0x00000020,0x00000020,0x00200020,0x00200020, - 0x00002020,0x00002020,0x00202020,0x00202020, - },{ - 0x00000000,0x00000004,0x00000000,0x00000004, - 0x00000000,0x00000004,0x00000000,0x00000004, - 0x00000000,0x00000004,0x00000000,0x00000004, - 0x00000000,0x00000004,0x00000000,0x00000004, - },{ - 0x00000000,0x00000000,0x00400000,0x00400000, - 0x00004000,0x00004000,0x00404000,0x00404000, - 0x00000040,0x00000040,0x00400040,0x00400040, - 0x00004040,0x00004040,0x00404040,0x00404040, - },{ - 0x00000000,0x00000008,0x00000000,0x00000008, - 0x00000000,0x00000008,0x00000000,0x00000008, - 0x00000000,0x00000008,0x00000000,0x00000008, - 0x00000000,0x00000008,0x00000000,0x00000008, - },{ - 0x00000000,0x00000000,0x00800000,0x00800000, - 0x00008000,0x00008000,0x00808000,0x00808000, - 0x00000080,0x00000080,0x00800080,0x00800080, - 0x00008080,0x00008080,0x00808080,0x00808080, - },{ - 0x00000000,0x00000000,0x01000000,0x01000000, - 0x00010000,0x00010000,0x01010000,0x01010000, - 0x00000100,0x00000100,0x01000100,0x01000100, - 0x00010100,0x00010100,0x01010100,0x01010100, - },{ - 0x00000000,0x00000000,0x02000000,0x02000000, - 0x00020000,0x00020000,0x02020000,0x02020000, - 0x00000200,0x00000200,0x02000200,0x02000200, - 0x00020200,0x00020200,0x02020200,0x02020200, - },{ - 0x00000000,0x00000000,0x04000000,0x04000000, - 0x00040000,0x00040000,0x04040000,0x04040000, - 0x00000400,0x00000400,0x04000400,0x04000400, - 0x00040400,0x00040400,0x04040400,0x04040400, - },{ - 0x00000000,0x00000000,0x08000000,0x08000000, - 0x00080000,0x00080000,0x08080000,0x08080000, - 0x00000800,0x00000800,0x08000800,0x08000800, - 0x00080800,0x00080800,0x08080800,0x08080800, - }, -}; -static const uint32_t comp_maskl0[4][8] = { - { - 0x00000000,0x00020000,0x00000001,0x00020001, - 0x00080000,0x000a0000,0x00080001,0x000a0001, - },{ - 0x00000000,0x00001000,0x00000000,0x00001000, - 0x00000040,0x00001040,0x00000040,0x00001040, - },{ - 0x00000000,0x00400000,0x00000020,0x00400020, - 0x00008000,0x00408000,0x00008020,0x00408020, - },{ - 0x00000000,0x00100000,0x00000800,0x00100800, - 0x00000000,0x00100000,0x00000800,0x00100800, - }, -}; -static const uint32_t comp_maskr0[4][8] = { - { - 0x00000000,0x00200000,0x00020000,0x00220000, - 0x00000002,0x00200002,0x00020002,0x00220002, - },{ - 0x00000000,0x00000000,0x00100000,0x00100000, - 0x00000004,0x00000004,0x00100004,0x00100004, - },{ - 0x00000000,0x00004000,0x00000800,0x00004800, - 0x00000000,0x00004000,0x00000800,0x00004800, - },{ - 0x00000000,0x00400000,0x00008000,0x00408000, - 0x00000008,0x00400008,0x00008008,0x00408008, - }, -}; -static const uint32_t comp_maskl1[4][16] = { - { - 0x00000000,0x00000010,0x00004000,0x00004010, - 0x00040000,0x00040010,0x00044000,0x00044010, - 0x00000100,0x00000110,0x00004100,0x00004110, - 0x00040100,0x00040110,0x00044100,0x00044110, - },{ - 0x00000000,0x00800000,0x00000002,0x00800002, - 0x00000200,0x00800200,0x00000202,0x00800202, - 0x00200000,0x00a00000,0x00200002,0x00a00002, - 0x00200200,0x00a00200,0x00200202,0x00a00202, - },{ - 0x00000000,0x00002000,0x00000004,0x00002004, - 0x00000400,0x00002400,0x00000404,0x00002404, - 0x00000000,0x00002000,0x00000004,0x00002004, - 0x00000400,0x00002400,0x00000404,0x00002404, - },{ - 0x00000000,0x00010000,0x00000008,0x00010008, - 0x00000080,0x00010080,0x00000088,0x00010088, - 0x00000000,0x00010000,0x00000008,0x00010008, - 0x00000080,0x00010080,0x00000088,0x00010088, - }, -}; -static const uint32_t comp_maskr1[4][16] = { - { - 0x00000000,0x00000000,0x00000080,0x00000080, - 0x00002000,0x00002000,0x00002080,0x00002080, - 0x00000001,0x00000001,0x00000081,0x00000081, - 0x00002001,0x00002001,0x00002081,0x00002081, - },{ - 0x00000000,0x00000010,0x00800000,0x00800010, - 0x00010000,0x00010010,0x00810000,0x00810010, - 0x00000200,0x00000210,0x00800200,0x00800210, - 0x00010200,0x00010210,0x00810200,0x00810210, - },{ - 0x00000000,0x00000400,0x00001000,0x00001400, - 0x00080000,0x00080400,0x00081000,0x00081400, - 0x00000020,0x00000420,0x00001020,0x00001420, - 0x00080020,0x00080420,0x00081020,0x00081420, - },{ - 0x00000000,0x00000100,0x00040000,0x00040100, - 0x00000000,0x00000100,0x00040000,0x00040100, - 0x00000040,0x00000140,0x00040040,0x00040140, - 0x00000040,0x00000140,0x00040040,0x00040140, - }, -}; - -static const unsigned char ascii64[] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -/* 0000000000111111111122222222223333333333444444444455555555556666 */ -/* 0123456789012345678901234567890123456789012345678901234567890123 */ - -/* - * We match the behavior of UFC-crypt on systems where "char" is signed by - * default (the majority), regardless of char's signedness on our system. - */ -static uint32_t ascii_to_bin(int ch) -{ - int sch = (ch < 0x80) ? ch : -(0x100 - ch); - int retval; - - retval = sch - '.'; - if (sch >= 'A') { - retval = sch - ('A' - 12); - if (sch >= 'a') - retval = sch - ('a' - 38); - } - retval &= 0x3f; - - return retval; -} - -/* - * When we choose to "support" invalid salts, nevertheless disallow those - * containing characters that would violate the passwd file format. - */ -static inline int ascii_is_unsafe(unsigned char ch) -{ - return !ch || ch == '\n' || ch == ':'; -} - -static uint32_t setup_salt(uint32_t salt) -{ - uint32_t obit, saltbit, saltbits; - unsigned int i; - - saltbits = 0; - saltbit = 1; - obit = 0x800000; - for (i = 0; i < 24; i++) { - if (salt & saltbit) - saltbits |= obit; - saltbit <<= 1; - obit >>= 1; - } - - return saltbits; -} - -static void des_setkey(const unsigned char *key, struct expanded_key *ekey) -{ - uint32_t k0, k1, rawkey0, rawkey1; - unsigned int shifts, round, i, ibit; - - rawkey0 = - (uint32_t)key[3] | - ((uint32_t)key[2] << 8) | - ((uint32_t)key[1] << 16) | - ((uint32_t)key[0] << 24); - rawkey1 = - (uint32_t)key[7] | - ((uint32_t)key[6] << 8) | - ((uint32_t)key[5] << 16) | - ((uint32_t)key[4] << 24); - - /* - * Do key permutation and split into two 28-bit subkeys. - */ - k0 = k1 = 0; - for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) { - unsigned int j = i << 1; - k0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] | - key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf]; - k1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf]; - ibit -= 4; - k1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] | - key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf]; - } - - /* - * Rotate subkeys and do compression permutation. - */ - shifts = 0; - for (round = 0; round < 16; round++) { - uint32_t t0, t1; - uint32_t kl, kr; - - shifts += key_shifts[round]; - - t0 = (k0 << shifts) | (k0 >> (28 - shifts)); - t1 = (k1 << shifts) | (k1 >> (28 - shifts)); - - kl = kr = 0; - ibit = 25; - for (i = 0; i < 4; i++) { - kl |= comp_maskl0[i][(t0 >> ibit) & 7]; - kr |= comp_maskr0[i][(t1 >> ibit) & 7]; - ibit -= 4; - kl |= comp_maskl1[i][(t0 >> ibit) & 0xf]; - kr |= comp_maskr1[i][(t1 >> ibit) & 0xf]; - ibit -= 3; - } - ekey->l[round] = kl; - ekey->r[round] = kr; - } -} - -/* - * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. - */ -static void do_des(uint32_t l_in, uint32_t r_in, - uint32_t *l_out, uint32_t *r_out, - uint32_t count, uint32_t saltbits, const struct expanded_key *ekey) -{ - uint32_t l, r; - - /* - * Do initial permutation (IP). - */ - l = r = 0; - if (l_in | r_in) { - unsigned int i, ibit; - for (i = 0, ibit = 28; i < 8; i++, ibit -= 4) { - l |= ip_maskl[i][(l_in >> ibit) & 0xf] | - ip_maskl[i + 8][(r_in >> ibit) & 0xf]; - r |= ip_maskr[i][(l_in >> ibit) & 0xf] | - ip_maskr[i + 8][(r_in >> ibit) & 0xf]; - } - } - - while (count--) { - /* - * Do each round. - */ - unsigned int round = 16; - const uint32_t *kl = ekey->l; - const uint32_t *kr = ekey->r; - uint32_t f; - while (round--) { - uint32_t r48l, r48r; - /* - * Expand R to 48 bits (simulate the E-box). - */ - r48l = ((r & 0x00000001) << 23) - | ((r & 0xf8000000) >> 9) - | ((r & 0x1f800000) >> 11) - | ((r & 0x01f80000) >> 13) - | ((r & 0x001f8000) >> 15); - - r48r = ((r & 0x0001f800) << 7) - | ((r & 0x00001f80) << 5) - | ((r & 0x000001f8) << 3) - | ((r & 0x0000001f) << 1) - | ((r & 0x80000000) >> 31); - /* - * Do salting for crypt() and friends, and - * XOR with the permuted key. - */ - f = (r48l ^ r48r) & saltbits; - r48l ^= f ^ *kl++; - r48r ^= f ^ *kr++; - /* - * Do S-box lookups (which shrink it back to 32 bits) - * and do the P-box permutation at the same time. - */ - f = psbox[0][r48l >> 18] - | psbox[1][(r48l >> 12) & 0x3f] - | psbox[2][(r48l >> 6) & 0x3f] - | psbox[3][r48l & 0x3f] - | psbox[4][r48r >> 18] - | psbox[5][(r48r >> 12) & 0x3f] - | psbox[6][(r48r >> 6) & 0x3f] - | psbox[7][r48r & 0x3f]; - /* - * Now that we've permuted things, complete f(). - */ - f ^= l; - l = r; - r = f; - } - r = l; - l = f; - } - - /* - * Do final permutation (inverse of IP). - */ - { - unsigned int i, ibit; - uint32_t lo, ro; - lo = ro = 0; - for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) { - ro |= fp_maskr[i][(l >> ibit) & 0xf] | - fp_maskr[i + 4][(r >> ibit) & 0xf]; - ibit -= 4; - lo |= fp_maskl[i][(l >> ibit) & 0xf] | - fp_maskl[i + 4][(r >> ibit) & 0xf]; - } - *l_out = lo; - *r_out = ro; - } -} - -static void des_cipher(const unsigned char *in, unsigned char *out, - uint32_t count, uint32_t saltbits, const struct expanded_key *ekey) -{ - uint32_t l_out, r_out, rawl, rawr; - - rawl = - (uint32_t)in[3] | - ((uint32_t)in[2] << 8) | - ((uint32_t)in[1] << 16) | - ((uint32_t)in[0] << 24); - rawr = - (uint32_t)in[7] | - ((uint32_t)in[6] << 8) | - ((uint32_t)in[5] << 16) | - ((uint32_t)in[4] << 24); - - do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey); - - out[0] = l_out >> 24; - out[1] = l_out >> 16; - out[2] = l_out >> 8; - out[3] = l_out; - out[4] = r_out >> 24; - out[5] = r_out >> 16; - out[6] = r_out >> 8; - out[7] = r_out; -} - -static char *_crypt_extended_r_uut(const char *_key, const char *_setting, char *output) -{ - const unsigned char *key = (const unsigned char *)_key; - const unsigned char *setting = (const unsigned char *)_setting; - struct expanded_key ekey; - union { - unsigned char c[8]; - uint32_t i[2]; - } keybuf; - unsigned char *p, *q; - uint32_t count, salt, l, r0, r1; - unsigned int i; - - /* - * Copy the key, shifting each character left by one bit and padding - * with zeroes. - */ - q = keybuf.c; - while (q <= &keybuf.c[sizeof(keybuf.c) - 1]) { - *q++ = *key << 1; - if (*key) - key++; - } - des_setkey(keybuf.c, &ekey); - - if (*setting == _PASSWORD_EFMT1) { - /* - * "new"-style: - * setting - underscore, 4 chars of count, 4 chars of salt - * key - unlimited characters - */ - for (i = 1, count = 0; i < 5; i++) { - uint32_t value = ascii_to_bin(setting[i]); - if (ascii64[value] != setting[i]) - return NULL; - count |= value << (i - 1) * 6; - } - if (!count || count > 262143) - return NULL; - - for (i = 5, salt = 0; i < 9; i++) { - uint32_t value = ascii_to_bin(setting[i]); - if (ascii64[value] != setting[i]) - return NULL; - salt |= value << (i - 5) * 6; - } - - while (*key) { - /* - * Encrypt the key with itself. - */ - des_cipher(keybuf.c, keybuf.c, 1, 0, &ekey); - /* - * And XOR with the next 8 characters of the key. - */ - q = keybuf.c; - while (q <= &keybuf.c[sizeof(keybuf.c) - 1] && *key) - *q++ ^= *key++ << 1; - des_setkey(keybuf.c, &ekey); - } - - memcpy(output, setting, 9); - output[9] = '\0'; - p = (unsigned char *)output + 9; - } else { - /* - * "old"-style: - * setting - 2 chars of salt - * key - up to 8 characters - */ - count = 25; - - if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1])) - return NULL; - - salt = (ascii_to_bin(setting[1]) << 6) - | ascii_to_bin(setting[0]); - - output[0] = setting[0]; - output[1] = setting[1]; - p = (unsigned char *)output + 2; - } - - /* - * Do it. - */ - do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey); - - /* - * Now encode the result... - */ - l = (r0 >> 8); - *p++ = ascii64[(l >> 18) & 0x3f]; - *p++ = ascii64[(l >> 12) & 0x3f]; - *p++ = ascii64[(l >> 6) & 0x3f]; - *p++ = ascii64[l & 0x3f]; - - l = (r0 << 16) | ((r1 >> 16) & 0xffff); - *p++ = ascii64[(l >> 18) & 0x3f]; - *p++ = ascii64[(l >> 12) & 0x3f]; - *p++ = ascii64[(l >> 6) & 0x3f]; - *p++ = ascii64[l & 0x3f]; - - l = r1 << 2; - *p++ = ascii64[(l >> 12) & 0x3f]; - *p++ = ascii64[(l >> 6) & 0x3f]; - *p++ = ascii64[l & 0x3f]; - *p = 0; - - return output; -} - -char *__crypt_des(const char *key, const char *setting, char *output) -{ - const char *test_key = "\x80\xff\x80\x01 " - "\x7f\x81\x80\x80\x0d\x0a\xff\x7f \x81 test"; - const char *test_setting = "_0.../9Zz"; - const char *test_hash = "_0.../9ZzX7iSJNd21sU"; - char test_buf[21]; - char *retval; - const char *p; - - if (*setting != _PASSWORD_EFMT1) { - test_setting = "\x80x"; - test_hash = "\x80x22/wK52ZKGA"; - } - - /* - * Hash the supplied password. - */ - retval = _crypt_extended_r_uut(key, setting, output); - - /* - * Perform a quick self-test. It is important that we make both calls - * to _crypt_extended_r_uut() from the same scope such that they likely - * use the same stack locations, which makes the second call overwrite - * the first call's sensitive data on the stack and makes it more - * likely that any alignment related issues would be detected. - */ - p = _crypt_extended_r_uut(test_key, test_setting, test_buf); - if (p && !strcmp(p, test_hash) && retval) - return retval; - - return (setting[0]=='*') ? "x" : "*"; -} diff --git a/src/misc/crypt_r.c b/src/misc/crypt_r.c deleted file mode 100644 index 1c7f9cf0..00000000 --- a/src/misc/crypt_r.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include "libc.h" - -struct crypt_data; - -char *__crypt_des(const char *, const char *, char *); -char *__crypt_md5(const char *, const char *, char *); -char *__crypt_blowfish(const char *, const char *, char *); -char *__crypt_sha256(const char *, const char *, char *); -char *__crypt_sha512(const char *, const char *, char *); - -char *__crypt_r(const char *key, const char *salt, struct crypt_data *data) -{ - char *output = (char *)data; - if (salt[0] == '$' && salt[1] && salt[2]) { -#if 0 - if (salt[1] == '1' && salt[2] == '$') - return __crypt_md5(key, salt, output); -#endif - if (salt[1] == '2' && salt[3] == '$') - return __crypt_blowfish(key, salt, output); - if (salt[1] == '5' && salt[2] == '$') - return __crypt_sha256(key, salt, output); - if (salt[1] == '6' && salt[2] == '$') - return __crypt_sha512(key, salt, output); - } - return __crypt_des(key, salt, output); -} - -weak_alias(__crypt_r, crypt_r); diff --git a/src/misc/crypt_sha256.c b/src/misc/crypt_sha256.c deleted file mode 100644 index 2dc27ee7..00000000 --- a/src/misc/crypt_sha256.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * public domain sha256 crypt implementation - * - * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt - * in this implementation at least 32bit int is assumed, - * key length is limited, the $5$ prefix is mandatory, '\n' and ':' is rejected - * in the salt and rounds= setting must contain a valid iteration count, - * on error "*" is returned. - */ -#include -#include -#include -#include -#include - -/* public domain sha256 implementation based on fips180-3 */ - -struct sha256 { - uint64_t len; /* processed message length */ - uint32_t h[8]; /* hash state */ - uint8_t buf[64]; /* message block buffer */ -}; - -static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); } -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) ((x & y) | (z & (x | y))) -#define S0(x) (ror(x,2) ^ ror(x,13) ^ ror(x,22)) -#define S1(x) (ror(x,6) ^ ror(x,11) ^ ror(x,25)) -#define R0(x) (ror(x,7) ^ ror(x,18) ^ (x>>3)) -#define R1(x) (ror(x,17) ^ ror(x,19) ^ (x>>10)) - -static const uint32_t K[64] = { -0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, -0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, -0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, -0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, -0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, -0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, -0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, -0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -static void processblock(struct sha256 *s, const uint8_t *buf) -{ - uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h; - int i; - - for (i = 0; i < 16; i++) { - W[i] = (uint32_t)buf[4*i]<<24; - W[i] |= (uint32_t)buf[4*i+1]<<16; - W[i] |= (uint32_t)buf[4*i+2]<<8; - W[i] |= buf[4*i+3]; - } - for (; i < 64; i++) - W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; - a = s->h[0]; - b = s->h[1]; - c = s->h[2]; - d = s->h[3]; - e = s->h[4]; - f = s->h[5]; - g = s->h[6]; - h = s->h[7]; - for (i = 0; i < 64; i++) { - t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; - t2 = S0(a) + Maj(a,b,c); - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - } - s->h[0] += a; - s->h[1] += b; - s->h[2] += c; - s->h[3] += d; - s->h[4] += e; - s->h[5] += f; - s->h[6] += g; - s->h[7] += h; -} - -static void pad(struct sha256 *s) -{ - unsigned r = s->len % 64; - - s->buf[r++] = 0x80; - if (r > 56) { - memset(s->buf + r, 0, 64 - r); - r = 0; - processblock(s, s->buf); - } - memset(s->buf + r, 0, 56 - r); - s->len *= 8; - s->buf[56] = s->len >> 56; - s->buf[57] = s->len >> 48; - s->buf[58] = s->len >> 40; - s->buf[59] = s->len >> 32; - s->buf[60] = s->len >> 24; - s->buf[61] = s->len >> 16; - s->buf[62] = s->len >> 8; - s->buf[63] = s->len; - processblock(s, s->buf); -} - -static void sha256_init(struct sha256 *s) -{ - s->len = 0; - s->h[0] = 0x6a09e667; - s->h[1] = 0xbb67ae85; - s->h[2] = 0x3c6ef372; - s->h[3] = 0xa54ff53a; - s->h[4] = 0x510e527f; - s->h[5] = 0x9b05688c; - s->h[6] = 0x1f83d9ab; - s->h[7] = 0x5be0cd19; -} - -static void sha256_sum(struct sha256 *s, uint8_t md[20]) -{ - int i; - - pad(s); - for (i = 0; i < 8; i++) { - md[4*i] = s->h[i] >> 24; - md[4*i+1] = s->h[i] >> 16; - md[4*i+2] = s->h[i] >> 8; - md[4*i+3] = s->h[i]; - } -} - -static void sha256_update(struct sha256 *s, const void *m, unsigned long len) -{ - const uint8_t *p = m; - unsigned r = s->len % 64; - - s->len += len; - if (r) { - if (len < 64 - r) { - memcpy(s->buf + r, p, len); - return; - } - memcpy(s->buf + r, p, 64 - r); - len -= 64 - r; - p += 64 - r; - processblock(s, s->buf); - } - for (; len >= 64; len -= 64, p += 64) - processblock(s, p); - memcpy(s->buf, p, len); -} - -static unsigned char b64[] = -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static char *to64(char *s, unsigned int u, int n) -{ - while (--n >= 0) { - *s++ = b64[u % 64]; - u /= 64; - } - return s; -} - -/* key limit is not part of the original design, added for DoS protection. - * rounds limit has been lowered (versus the reference/spec), also for DoS - * protection. runtime is O(klen^2 + klen*rounds) */ -#define KEY_MAX 256 -#define SALT_MAX 16 -#define ROUNDS_DEFAULT 5000 -#define ROUNDS_MIN 1000 -#define ROUNDS_MAX 50000 - -/* hash n bytes of the repeated md message digest */ -static void hashmd(struct sha256 *s, unsigned int n, const void *md) -{ - unsigned int i; - - for (i = n; i > 32; i -= 32) - sha256_update(s, md, 32); - sha256_update(s, md, i); -} - -static char *sha256crypt(const char *key, const char *setting, char *output) -{ - struct sha256 ctx; - unsigned char md[32], kmd[32], smd[32]; - unsigned int i, r, klen, slen; - char rounds[20] = ""; - const char *salt; - char *p; - - /* reject large keys */ - klen = strnlen(key, KEY_MAX+1); - if (klen > KEY_MAX) - return 0; - - /* setting: $5$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ - if (strncmp(setting, "$5$", 3) != 0) - return 0; - salt = setting + 3; - - r = ROUNDS_DEFAULT; - if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { - unsigned long u; - char *end; - - /* - * this is a deviation from the reference: - * bad rounds setting is rejected if it is - * - empty - * - unterminated (missing '$') - * - begins with anything but a decimal digit - * the reference implementation treats these bad - * rounds as part of the salt or parse them with - * strtoul semantics which may cause problems - * including non-portable hashes that depend on - * the host's value of ULONG_MAX. - */ - salt += sizeof "rounds=" - 1; - if (!isdigit(*salt)) - return 0; - u = strtoul(salt, &end, 10); - if (*end != '$') - return 0; - salt = end+1; - if (u < ROUNDS_MIN) - r = ROUNDS_MIN; - else if (u > ROUNDS_MAX) - r = ROUNDS_MAX; - else - r = u; - /* needed when rounds is zero prefixed or out of bounds */ - sprintf(rounds, "rounds=%u$", r); - } - - for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) - /* reject characters that interfere with /etc/shadow parsing */ - if (salt[i] == '\n' || salt[i] == ':') - return 0; - slen = i; - - /* B = sha(key salt key) */ - sha256_init(&ctx); - sha256_update(&ctx, key, klen); - sha256_update(&ctx, salt, slen); - sha256_update(&ctx, key, klen); - sha256_sum(&ctx, md); - - /* A = sha(key salt repeat-B alternate-B-key) */ - sha256_init(&ctx); - sha256_update(&ctx, key, klen); - sha256_update(&ctx, salt, slen); - hashmd(&ctx, klen, md); - for (i = klen; i > 0; i >>= 1) - if (i & 1) - sha256_update(&ctx, md, sizeof md); - else - sha256_update(&ctx, key, klen); - sha256_sum(&ctx, md); - - /* DP = sha(repeat-key), this step takes O(klen^2) time */ - sha256_init(&ctx); - for (i = 0; i < klen; i++) - sha256_update(&ctx, key, klen); - sha256_sum(&ctx, kmd); - - /* DS = sha(repeat-salt) */ - sha256_init(&ctx); - for (i = 0; i < 16 + md[0]; i++) - sha256_update(&ctx, salt, slen); - sha256_sum(&ctx, smd); - - /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ - for (i = 0; i < r; i++) { - sha256_init(&ctx); - if (i % 2) - hashmd(&ctx, klen, kmd); - else - sha256_update(&ctx, md, sizeof md); - if (i % 3) - sha256_update(&ctx, smd, slen); - if (i % 7) - hashmd(&ctx, klen, kmd); - if (i % 2) - sha256_update(&ctx, md, sizeof md); - else - hashmd(&ctx, klen, kmd); - sha256_sum(&ctx, md); - } - - /* output is $5$rounds=n$salt$hash */ - p = output; - p += sprintf(p, "$5$%s%.*s$", rounds, slen, salt); - static const unsigned char perm[][3] = { - 0,10,20,21,1,11,12,22,2,3,13,23,24,4,14, - 15,25,5,6,16,26,27,7,17,18,28,8,9,19,29 }; - for (i=0; i<10; i++) p = to64(p, - (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); - p = to64(p, (md[31]<<8)|md[30], 3); - *p = 0; - return output; -} - -char *__crypt_sha256(const char *key, const char *setting, char *output) -{ - static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; - static const char testsetting[] = "$5$rounds=1234$abc0123456789$"; - static const char testhash[] = "$5$rounds=1234$abc0123456789$3VfDjPt05VHFn47C/ojFZ6KRPYrOjj1lLbH.dkF3bZ6"; - char testbuf[128]; - char *p, *q; - - p = sha256crypt(key, setting, output); - /* self test and stack cleanup */ - q = sha256crypt(testkey, testsetting, testbuf); - if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) - return "*"; - return p; -} diff --git a/src/misc/crypt_sha512.c b/src/misc/crypt_sha512.c deleted file mode 100644 index 2c0de698..00000000 --- a/src/misc/crypt_sha512.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * public domain sha512 crypt implementation - * - * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt - * in this implementation at least 32bit int is assumed, - * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected - * in the salt and rounds= setting must contain a valid iteration count, - * on error "*" is returned. - */ -#include -#include -#include -#include -#include - -/* public domain sha512 implementation based on fips180-3 */ -/* >=2^64 bits messages are not supported (about 2000 peta bytes) */ - -struct sha512 { - uint64_t len; /* processed message length */ - uint64_t h[8]; /* hash state */ - uint8_t buf[128]; /* message block buffer */ -}; - -static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) ((x & y) | (z & (x | y))) -#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) -#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) -#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) -#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) - -static const uint64_t K[80] = { -0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, -0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, -0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, -0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, -0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, -0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, -0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, -0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, -0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, -0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, -0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, -0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, -0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, -0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, -0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, -0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, -0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, -0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, -0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, -0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -static void processblock(struct sha512 *s, const uint8_t *buf) -{ - uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; - int i; - - for (i = 0; i < 16; i++) { - W[i] = (uint64_t)buf[8*i]<<56; - W[i] |= (uint64_t)buf[8*i+1]<<48; - W[i] |= (uint64_t)buf[8*i+2]<<40; - W[i] |= (uint64_t)buf[8*i+3]<<32; - W[i] |= (uint64_t)buf[8*i+4]<<24; - W[i] |= (uint64_t)buf[8*i+5]<<16; - W[i] |= (uint64_t)buf[8*i+6]<<8; - W[i] |= buf[8*i+7]; - } - for (; i < 80; i++) - W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; - a = s->h[0]; - b = s->h[1]; - c = s->h[2]; - d = s->h[3]; - e = s->h[4]; - f = s->h[5]; - g = s->h[6]; - h = s->h[7]; - for (i = 0; i < 80; i++) { - t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; - t2 = S0(a) + Maj(a,b,c); - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - } - s->h[0] += a; - s->h[1] += b; - s->h[2] += c; - s->h[3] += d; - s->h[4] += e; - s->h[5] += f; - s->h[6] += g; - s->h[7] += h; -} - -static void pad(struct sha512 *s) -{ - unsigned r = s->len % 128; - - s->buf[r++] = 0x80; - if (r > 112) { - memset(s->buf + r, 0, 128 - r); - r = 0; - processblock(s, s->buf); - } - memset(s->buf + r, 0, 120 - r); - s->len *= 8; - s->buf[120] = s->len >> 56; - s->buf[121] = s->len >> 48; - s->buf[122] = s->len >> 40; - s->buf[123] = s->len >> 32; - s->buf[124] = s->len >> 24; - s->buf[125] = s->len >> 16; - s->buf[126] = s->len >> 8; - s->buf[127] = s->len; - processblock(s, s->buf); -} - -static void sha512_init(struct sha512 *s) -{ - s->len = 0; - s->h[0] = 0x6a09e667f3bcc908ULL; - s->h[1] = 0xbb67ae8584caa73bULL; - s->h[2] = 0x3c6ef372fe94f82bULL; - s->h[3] = 0xa54ff53a5f1d36f1ULL; - s->h[4] = 0x510e527fade682d1ULL; - s->h[5] = 0x9b05688c2b3e6c1fULL; - s->h[6] = 0x1f83d9abfb41bd6bULL; - s->h[7] = 0x5be0cd19137e2179ULL; -} - -static void sha512_sum(struct sha512 *s, uint8_t md[20]) -{ - int i; - - pad(s); - for (i = 0; i < 8; i++) { - md[8*i] = s->h[i] >> 56; - md[8*i+1] = s->h[i] >> 48; - md[8*i+2] = s->h[i] >> 40; - md[8*i+3] = s->h[i] >> 32; - md[8*i+4] = s->h[i] >> 24; - md[8*i+5] = s->h[i] >> 16; - md[8*i+6] = s->h[i] >> 8; - md[8*i+7] = s->h[i]; - } -} - -static void sha512_update(struct sha512 *s, const void *m, unsigned long len) -{ - const uint8_t *p = m; - unsigned r = s->len % 128; - - s->len += len; - if (r) { - if (len < 128 - r) { - memcpy(s->buf + r, p, len); - return; - } - memcpy(s->buf + r, p, 128 - r); - len -= 128 - r; - p += 128 - r; - processblock(s, s->buf); - } - for (; len >= 128; len -= 128, p += 128) - processblock(s, p); - memcpy(s->buf, p, len); -} - -static unsigned char b64[] = -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static char *to64(char *s, unsigned int u, int n) -{ - while (--n >= 0) { - *s++ = b64[u % 64]; - u /= 64; - } - return s; -} - -/* key limit is not part of the original design, added for DoS protection. - * rounds limit has been lowered (versus the reference/spec), also for DoS - * protection. runtime is O(klen^2 + klen*rounds) */ -#define KEY_MAX 256 -#define SALT_MAX 16 -#define ROUNDS_DEFAULT 5000 -#define ROUNDS_MIN 1000 -#define ROUNDS_MAX 20000 - -/* hash n bytes of the repeated md message digest */ -static void hashmd(struct sha512 *s, unsigned int n, const void *md) -{ - unsigned int i; - - for (i = n; i > 64; i -= 64) - sha512_update(s, md, 64); - sha512_update(s, md, i); -} - -static char *sha512crypt(const char *key, const char *setting, char *output) -{ - struct sha512 ctx; - unsigned char md[64], kmd[64], smd[64]; - unsigned int i, r, klen, slen; - char rounds[20] = ""; - const char *salt; - char *p; - - /* reject large keys */ - for (i = 0; i <= KEY_MAX && key[i]; i++); - if (i > KEY_MAX) - return 0; - klen = i; - - /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ - if (strncmp(setting, "$6$", 3) != 0) - return 0; - salt = setting + 3; - - r = ROUNDS_DEFAULT; - if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { - unsigned long u; - char *end; - - /* - * this is a deviation from the reference: - * bad rounds setting is rejected if it is - * - empty - * - unterminated (missing '$') - * - begins with anything but a decimal digit - * the reference implementation treats these bad - * rounds as part of the salt or parse them with - * strtoul semantics which may cause problems - * including non-portable hashes that depend on - * the host's value of ULONG_MAX. - */ - salt += sizeof "rounds=" - 1; - if (!isdigit(*salt)) - return 0; - u = strtoul(salt, &end, 10); - if (*end != '$') - return 0; - salt = end+1; - if (u < ROUNDS_MIN) - r = ROUNDS_MIN; - else if (u > ROUNDS_MAX) - r = ROUNDS_MAX; - else - r = u; - /* needed when rounds is zero prefixed or out of bounds */ - sprintf(rounds, "rounds=%u$", r); - } - - for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) - /* reject characters that interfere with /etc/shadow parsing */ - if (salt[i] == '\n' || salt[i] == ':') - return 0; - slen = i; - - /* B = sha(key salt key) */ - sha512_init(&ctx); - sha512_update(&ctx, key, klen); - sha512_update(&ctx, salt, slen); - sha512_update(&ctx, key, klen); - sha512_sum(&ctx, md); - - /* A = sha(key salt repeat-B alternate-B-key) */ - sha512_init(&ctx); - sha512_update(&ctx, key, klen); - sha512_update(&ctx, salt, slen); - hashmd(&ctx, klen, md); - for (i = klen; i > 0; i >>= 1) - if (i & 1) - sha512_update(&ctx, md, sizeof md); - else - sha512_update(&ctx, key, klen); - sha512_sum(&ctx, md); - - /* DP = sha(repeat-key), this step takes O(klen^2) time */ - sha512_init(&ctx); - for (i = 0; i < klen; i++) - sha512_update(&ctx, key, klen); - sha512_sum(&ctx, kmd); - - /* DS = sha(repeat-salt) */ - sha512_init(&ctx); - for (i = 0; i < 16 + md[0]; i++) - sha512_update(&ctx, salt, slen); - sha512_sum(&ctx, smd); - - /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ - for (i = 0; i < r; i++) { - sha512_init(&ctx); - if (i % 2) - hashmd(&ctx, klen, kmd); - else - sha512_update(&ctx, md, sizeof md); - if (i % 3) - sha512_update(&ctx, smd, slen); - if (i % 7) - hashmd(&ctx, klen, kmd); - if (i % 2) - sha512_update(&ctx, md, sizeof md); - else - hashmd(&ctx, klen, kmd); - sha512_sum(&ctx, md); - } - - /* output is $6$rounds=n$salt$hash */ - p = output; - p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); -#if 1 - static const unsigned char perm[][3] = { - 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, - 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, - 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, - 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, - 62,20,41 }; - for (i=0; i<21; i++) p = to64(p, - (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); -#else - p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); - p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); - p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); - p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); - p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); - p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); - p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); - p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); - p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); - p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); - p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); - p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); - p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); - p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); - p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); - p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); - p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); - p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); - p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); - p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); - p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); -#endif - p = to64(p, md[63], 2); - *p = 0; - return output; -} - -char *__crypt_sha512(const char *key, const char *setting, char *output) -{ - static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; - static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; - static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; - char testbuf[128]; - char *p, *q; - - p = sha512crypt(key, setting, output); - /* self test and stack cleanup */ - q = sha512crypt(testkey, testsetting, testbuf); - if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) - return "*"; - return p; -} diff --git a/src/misc/cuserid.c b/src/misc/cuserid.c deleted file mode 100644 index 4e78798d..00000000 --- a/src/misc/cuserid.c +++ /dev/null @@ -1,14 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include - -char *cuserid(char *buf) -{ - struct passwd pw, *ppw; - long pwb[256]; - if (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw)) - return 0; - snprintf(buf, L_cuserid, "%s", pw.pw_name); - return buf; -} diff --git a/src/misc/ftw.c b/src/misc/ftw.c deleted file mode 100644 index 0429aba4..00000000 --- a/src/misc/ftw.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "libc.h" - -int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit) -{ - /* The following cast assumes that calling a function with one - * argument more than it needs behaves as expected. This is - * actually undefined, but works on all real-world machines. */ - return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS); -} - -LFS64(ftw); diff --git a/src/misc/futimes.c b/src/misc/futimes.c deleted file mode 100644 index f8fd1cde..00000000 --- a/src/misc/futimes.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -int futimes(int fd, const struct timeval tv[2]) -{ - struct timespec times[2]; - times[0].tv_sec = tv[0].tv_sec; - times[0].tv_nsec = tv[0].tv_usec * 1000; - times[1].tv_sec = tv[1].tv_sec; - times[1].tv_nsec = tv[1].tv_usec * 1000; - return futimens(fd, times); -} diff --git a/src/misc/gethostid.c b/src/misc/gethostid.c new file mode 100644 index 00000000..ea65611a --- /dev/null +++ b/src/misc/gethostid.c @@ -0,0 +1,4 @@ +long gethostid() +{ + return 0; +} diff --git a/src/misc/getopt_long.c b/src/misc/getopt_long.c new file mode 100644 index 00000000..6d3a4a6e --- /dev/null +++ b/src/misc/getopt_long.c @@ -0,0 +1,52 @@ +#define _GNU_SOURCE +#include +#include +#include + +static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) +{ + if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1; + if ((longonly && argv[optind][1]) || + (argv[optind][1] == '-' && argv[optind][2])) + { + int i; + for (i=0; longopts[i].name; i++) { + const char *name = longopts[i].name; + char *opt = argv[optind]+1; + if (*opt == '-') opt++; + for (; *name && *name == *opt; name++, opt++); + if (*name || (*opt && *opt != '=')) continue; + if (*opt == '=') { + if (!longopts[i].has_arg) continue; + optarg = opt+1; + } else { + if (longopts[i].has_arg == required_argument) { + if (!(optarg = argv[++optind])) + return ':'; + } else optarg = NULL; + } + optind++; + if (idx) *idx = i; + if (longopts[i].flag) { + *longopts[i].flag = longopts[i].val; + return 0; + } + return longopts[i].val; + } + if (argv[optind][1] == '-') { + optind++; + return '?'; + } + } + return getopt(argc, argv, optstring); +} + +int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) +{ + return __getopt_long(argc, argv, optstring, longopts, idx, 0); +} + +int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) +{ + return __getopt_long(argc, argv, optstring, longopts, idx, 1); +} diff --git a/src/misc/getusershell.c b/src/misc/getusershell.c deleted file mode 100644 index 683158c8..00000000 --- a/src/misc/getusershell.c +++ /dev/null @@ -1,33 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include - -static const char defshells[] = "/bin/sh\n/bin/csh\n"; - -static char *line; -static size_t linesize; -static FILE *f; - -void endusershell(void) -{ - if (f) fclose(f); - f = 0; -} - -void setusershell(void) -{ - if (!f) f = fopen("/etc/shells", "rb"); - if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb"); -} - -char *getusershell(void) -{ - ssize_t l; - if (!f) setusershell(); - if (!f) return 0; - l = getline(&line, &linesize, f); - if (l <= 0) return 0; - if (line[l-1]=='\n') line[l-1]=0; - return line; -} diff --git a/src/misc/initgroups.c b/src/misc/initgroups.c new file mode 100644 index 00000000..545d1859 --- /dev/null +++ b/src/misc/initgroups.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +int getgrouplist(const char *, gid_t, gid_t *, int *); +int setgroups(size_t, const gid_t *); + +int initgroups(const char *user, gid_t gid) +{ + gid_t groups[NGROUPS_MAX]; + int count = NGROUPS_MAX; + if (getgrouplist(user, gid, groups, &count) < 0) return -1; + return setgroups(count, groups); +} diff --git a/src/misc/isastream.c b/src/misc/isastream.c deleted file mode 100644 index 4dafdb08..00000000 --- a/src/misc/isastream.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int isastream(int fd) -{ - return fcntl(fd, F_GETFD) < 0 ? -1 : 0; -} diff --git a/src/misc/lutimes.c b/src/misc/lutimes.c deleted file mode 100644 index 13dfe4ef..00000000 --- a/src/misc/lutimes.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -int lutimes(const char *filename, const struct timeval tv[2]) -{ - struct timespec times[2]; - times[0].tv_sec = tv[0].tv_sec; - times[0].tv_nsec = tv[0].tv_usec * 1000; - times[1].tv_sec = tv[1].tv_sec; - times[1].tv_nsec = tv[1].tv_usec * 1000; - return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW); -} diff --git a/src/misc/mntent.c b/src/misc/mntent.c new file mode 100644 index 00000000..3eafba5e --- /dev/null +++ b/src/misc/mntent.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +FILE *setmntent(const char *name, const char *mode) +{ + return fopen(name, mode); +} + +int endmntent(FILE *f) +{ + fclose(f); + return 1; +} + +struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen) +{ + int cnt, n[8]; + + mnt->mnt_freq = 0; + mnt->mnt_passno = 0; + + do { + fgets(linebuf, buflen, f); + if (feof(f) || ferror(f)) return 0; + if (!strchr(linebuf, '\n')) { + fscanf(f, "%*[^\n]%*[\n]"); + errno = ERANGE; + return 0; + } + cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", + n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, + &mnt->mnt_freq, &mnt->mnt_passno); + } while (cnt < 2 || linebuf[n[0]] == '#'); + + linebuf[n[1]] = 0; + linebuf[n[3]] = 0; + linebuf[n[5]] = 0; + linebuf[n[7]] = 0; + + mnt->mnt_fsname = linebuf+n[0]; + mnt->mnt_dir = linebuf+n[2]; + mnt->mnt_type = linebuf+n[4]; + mnt->mnt_opts = linebuf+n[6]; + + return mnt; +} + +struct mntent *getmntent(FILE *f) +{ + static char linebuf[256]; + static struct mntent mnt; + return getmntent_r(f, &mnt, linebuf, sizeof linebuf); +} + +int addmntent(FILE *f, const struct mntent *mnt) +{ + if (fseek(f, 0, SEEK_END)) return 1; + return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n", + mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts, + mnt->mnt_freq, mnt->mnt_passno) < 0; +} + +char *hasmntopt(const struct mntent *mnt, const char *opt) +{ + return strstr(mnt->mnt_opts, opt); +} diff --git a/src/misc/prlimit.c b/src/misc/prlimit.c deleted file mode 100644 index b9dbb446..00000000 --- a/src/misc/prlimit.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include "syscall.h" - -int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit) -{ - return syscall(SYS_prlimit64, pid, resource, new_limit, old_limit); -} diff --git a/src/misc/ptrace.c b/src/misc/ptrace.c deleted file mode 100644 index 83b8022b..00000000 --- a/src/misc/ptrace.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include "syscall.h" - -long ptrace(int req, ...) -{ - va_list ap; - pid_t pid; - void *addr, *data, *addr2; - long ret, result; - - va_start(ap, req); - pid = va_arg(ap, pid_t); - addr = va_arg(ap, void *); - data = va_arg(ap, void *); - addr2 = va_arg(ap, void *); - va_end(ap); - - if (req-1U < 3) data = &result; - ret = syscall(SYS_ptrace, req, pid, addr, data, addr2); - - if (ret < 0 || req-1U >= 3) return ret; - return result; -} diff --git a/src/misc/syscall.c b/src/misc/syscall.c new file mode 100644 index 00000000..15355609 --- /dev/null +++ b/src/misc/syscall.c @@ -0,0 +1,19 @@ +#include "syscall.h" +#include + +#undef syscall + +long syscall(long n, ...) +{ + va_list ap; + long a,b,c,d,e,f; + va_start(ap, n); + a=va_arg(ap, long); + b=va_arg(ap, long); + c=va_arg(ap, long); + d=va_arg(ap, long); + e=va_arg(ap, long); + f=va_arg(ap, long); + va_end(ap); + return __syscall_ret(__syscall(n,a,b,c,d,e,f)); +} diff --git a/src/misc/ulimit.c b/src/misc/ulimit.c deleted file mode 100644 index 1f59e8e6..00000000 --- a/src/misc/ulimit.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - -long ulimit(int cmd, ...) -{ - struct rlimit rl; - getrlimit(RLIMIT_FSIZE, &rl); - if (cmd == UL_SETFSIZE) { - long val; - va_list ap; - va_start(ap, cmd); - val = va_arg(ap, long); - va_end(ap); - rl.rlim_cur = 512ULL * val; - if (setrlimit(RLIMIT_FSIZE, &rl)) return -1; - } - return rl.rlim_cur / 512; -} diff --git a/src/stub/utmpx.c b/src/stub/utmpx.c deleted file mode 100644 index c483e4ed..00000000 --- a/src/stub/utmpx.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include "libc.h" - -void endutxent(void) -{ -} - -void setutxent(void) -{ -} - -struct utmpx *getutxent(void) -{ - return NULL; -} - -struct utmpx *getutxid(const struct utmpx *ut) -{ - return NULL; -} - -struct utmpx *getutxline(const struct utmpx *ut) -{ - return NULL; -} - -struct utmpx *pututxline(const struct utmpx *ut) -{ - return NULL; -} - -void updwtmpx(const char *f, const struct utmpx *u) -{ -} - -weak_alias(endutxent, endutent); -weak_alias(setutxent, setutent); -weak_alias(getutxent, getutent); -weak_alias(getutxid, getutid); -weak_alias(getutxline, getutline); -weak_alias(pututxline, pututline); -weak_alias(updwtmpx, updwtmp); -- cgit v1.2.1