Ticket #12365: scrypt_v5.patch
File scrypt_v5.patch, 105.9 KB (added by , 8 years ago) |
---|
-
headers/posix/unistd.h
From 77f1d3fd16ec2f762ca69934f83c8d5cfd90bd27 Mon Sep 17 00:00:00 2001 From: Andrew Aldridge <i80and@foxquill.com> Date: Mon, 16 Jan 2017 22:04:23 +0000 Subject: [PATCH] Implement scrypt-based password hashing --- headers/posix/unistd.h | 1 + src/apps/aboutsystem/AboutSystem.cpp | 9 + src/bin/multiuser/passwd.cpp | 10 +- src/preferences/screensaver/PasswordWindow.cpp | 38 +- src/preferences/screensaver/PasswordWindow.h | 1 - src/system/libroot/Jamfile | 2 + src/system/libroot/posix/crypt/Jamfile | 11 +- src/system/libroot/posix/crypt/crypt.c | 123 --- src/system/libroot/posix/crypt/crypt.cpp | 197 +++++ src/system/libroot/posix/crypt/crypt_legacy.c | 123 +++ src/system/libroot/posix/crypt/crypt_legacy.h | 14 + src/system/libroot/posix/crypt/crypt_legacy_util.c | 967 ++++++++++++++++++++ src/system/libroot/posix/crypt/crypt_util.c | 977 --------------------- src/system/libroot/posix/crypt/crypto_scrypt.cpp | 233 +++++ src/system/libroot/posix/crypt/crypto_scrypt.h | 47 + .../libroot/posix/crypt/crypto_scrypt_smix.cpp | 217 +++++ .../libroot/posix/crypt/crypto_scrypt_smix.h | 43 + src/system/libroot/posix/crypt/pbkdf2.cpp | 183 ++++ src/system/libroot/posix/crypt/pbkdf2.h | 107 +++ src/tests/system/libroot/posix/CryptTest.cpp | 110 +++ src/tests/system/libroot/posix/CryptTest.h | 35 + src/tests/system/libroot/posix/Jamfile | 7 + src/tests/system/libroot/posix/LibRootPosix.cpp | 22 + 23 files changed, 2335 insertions(+), 1142 deletions(-) delete mode 100644 src/system/libroot/posix/crypt/crypt.c create mode 100644 src/system/libroot/posix/crypt/crypt.cpp create mode 100644 src/system/libroot/posix/crypt/crypt_legacy.c create mode 100644 src/system/libroot/posix/crypt/crypt_legacy.h create mode 100644 src/system/libroot/posix/crypt/crypt_legacy_util.c delete mode 100644 src/system/libroot/posix/crypt/crypt_util.c create mode 100644 src/system/libroot/posix/crypt/crypto_scrypt.cpp create mode 100644 src/system/libroot/posix/crypt/crypto_scrypt.h create mode 100644 src/system/libroot/posix/crypt/crypto_scrypt_smix.cpp create mode 100644 src/system/libroot/posix/crypt/crypto_scrypt_smix.h create mode 100644 src/system/libroot/posix/crypt/pbkdf2.cpp create mode 100644 src/system/libroot/posix/crypt/pbkdf2.h create mode 100644 src/tests/system/libroot/posix/CryptTest.cpp create mode 100644 src/tests/system/libroot/posix/CryptTest.h create mode 100644 src/tests/system/libroot/posix/LibRootPosix.cpp diff --git a/headers/posix/unistd.h b/headers/posix/unistd.h index 9c8fc77..0fb3349 100644
a b extern char *ttyname(int fd); 277 277 extern int ttyname_r(int fd, char *buffer, size_t bufferSize); 278 278 279 279 /* misc */ 280 extern char *crypt_gensalt(int hardness); 280 281 extern char *crypt(const char *key, const char *salt); 281 282 extern void encrypt(char block[64], int edflag); 282 283 extern int getopt(int argc, char *const *argv, const char *shortOpts); -
src/apps/aboutsystem/AboutSystem.cpp
diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index 4aea876..ee80b19 100644
a b AboutView::_CreateCreditsView() 1420 1420 _AddCopyrightsFromAttribute(); 1421 1421 _AddPackageCreditEntries(); 1422 1422 1423 // scrypt 1424 _AddPackageCredit(PackageCredit("scrypt") 1425 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2009 Colin Percival")) 1426 .SetLicense(kBSDTwoClause) 1427 .SetURL("https://tarsnap.com/scrypt.html")); 1428 1429 _AddCopyrightsFromAttribute(); 1430 _AddPackageCreditEntries(); 1431 1423 1432 return new CropView(creditsScroller, 0, 1, 1, 1); 1424 1433 } 1425 1434 -
src/bin/multiuser/passwd.cpp
diff --git a/src/bin/multiuser/passwd.cpp b/src/bin/multiuser/passwd.cpp index 44beda2..5cd0ef6 100644
a b main(int argc, const char* const* argv) 172 172 memset(repeatedPassword, 0, sizeof(repeatedPassword)); 173 173 174 174 // crypt it 175 encryptedPassword = crypt(password, user); 175 char* salt = crypt_gensalt(-1); 176 if (salt == NULL) { 177 fprintf(stderr, "Error: Failed to generate salt: %s\n", 178 strerror(errno)); 179 exit(1); 180 } 181 encryptedPassword = crypt(password, salt); 176 182 memset(password, 0, sizeof(password)); 177 183 } 178 184 … … main(int argc, const char* const* argv) 182 188 || message.AddInt32("last changed", time(NULL)) != B_OK 183 189 || message.AddString("password", "x") != B_OK 184 190 || message.AddString("shadow password", encryptedPassword) != B_OK) { 185 fprintf(stderr, "Error: Out of memory!\n");191 fprintf(stderr, "Error: Failed to construct message!\n"); 186 192 exit(1); 187 193 } 188 194 -
src/preferences/screensaver/PasswordWindow.cpp
diff --git a/src/preferences/screensaver/PasswordWindow.cpp b/src/preferences/screensaver/PasswordWindow.cpp index 51c72b5..44cbd50 100644
a b PasswordWindow::Update() 145 145 } 146 146 147 147 148 char*149 PasswordWindow::_SanitizeSalt(const char* password)150 {151 char* salt;152 153 uint8 length = strlen(password);154 155 if (length < 2)156 salt = new char[3];157 else158 salt = new char[length + 1];159 160 uint8 i = 0;161 uint8 j = 0;162 for (; i < length; i++) {163 if (isalnum(password[i]) || password[i] == '.' || password[i] == '/') {164 salt[j] = password[i];165 j++;166 }167 }168 169 /*170 * We need to pad the salt.171 */172 while (j < 2) {173 salt[j] = '.';174 j++;175 }176 177 salt[j] = '\0';178 179 return salt;180 }181 182 183 148 void 184 149 PasswordWindow::MessageReceived(BMessage* message) 185 150 { … … PasswordWindow::MessageReceived(BMessage* message) 196 161 alert->Go(); 197 162 break; 198 163 } 199 c onst char* salt = _SanitizeSalt(fPasswordControl->Text());164 char* salt = crypt_gensalt(-1); 200 165 fSettings.SetPassword(crypt(fPasswordControl->Text(), salt)); 201 delete[] salt;202 166 } else 203 167 fSettings.SetPassword(""); 204 168 -
src/preferences/screensaver/PasswordWindow.h
diff --git a/src/preferences/screensaver/PasswordWindow.h b/src/preferences/screensaver/PasswordWindow.h index 0bf11c5..eee2621 100644
a b public: 29 29 30 30 private: 31 31 void _Setup(); 32 char* _SanitizeSalt(const char* password);33 32 34 33 BRadioButton* fUseCustom; 35 34 BRadioButton* fUseNetwork; -
src/system/libroot/Jamfile
diff --git a/src/system/libroot/Jamfile b/src/system/libroot/Jamfile index 2d988cd..210b92b 100644
a b for architectureObject in [ MultiArchSubDirSetup ] { 85 85 $(librootNoDebugObjects) 86 86 [ TargetStaticLibsupc++ ] 87 87 [ TargetLibgcc ] 88 shared 88 89 ; 89 90 90 91 # Use the standard libroot.so soname, so when the debug version is … … for architectureObject in [ MultiArchSubDirSetup ] { 99 100 $(librootDebugObjects) 100 101 [ TargetStaticLibsupc++ ] 101 102 [ TargetLibgcc ] 103 shared 102 104 ; 103 105 104 106 StaticLibrary [ MultiArchDefaultGristFiles libm.a ] : empty.c ; -
src/system/libroot/posix/crypt/Jamfile
diff --git a/src/system/libroot/posix/crypt/Jamfile b/src/system/libroot/posix/crypt/Jamfile index db3bb04..d0e6670 100644
a b 1 1 SubDir HAIKU_TOP src system libroot posix crypt ; 2 2 3 UsePrivateHeaders shared ; 4 UsePrivateSystemHeaders ; 5 3 6 local architectureObject ; 4 7 for architectureObject in [ MultiArchSubDirSetup ] { 5 8 on $(architectureObject) { … … for architectureObject in [ MultiArchSubDirSetup ] { 11 14 : -Wall -Wmissing-prototypes -Wsign-compare ] ; 12 15 13 16 MergeObject <$(architecture)>posix_crypt.o : 14 crypt.c 15 crypt_util.c 17 crypt_legacy.c 18 crypt_legacy_util.c 19 crypto_scrypt_smix.cpp 20 crypto_scrypt.cpp 21 crypt.cpp 22 pbkdf2.cpp 16 23 ; 17 24 } 18 25 } -
deleted file src/system/libroot/posix/crypt/crypt.c
diff --git a/src/system/libroot/posix/crypt/crypt.c b/src/system/libroot/posix/crypt/crypt.c deleted file mode 100644 index c647e37..0000000
+ - 1 /*2 * UFC-crypt: ultra fast crypt(3) implementation3 *4 * Copyright (C) 1991, 1992, Free Software Foundation, Inc.5 *6 * This library is free software; you can redistribute it and/or7 * modify it under the terms of the GNU Library General Public8 * License as published by the Free Software Foundation; either9 * version 2 of the License, or (at your option) any later version.10 *11 * This library is distributed in the hope that it will be useful,12 * but WITHOUT ANY WARRANTY; without even the implied warranty of13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU14 * Library General Public License for more details.15 *16 * You should have received a copy of the GNU Library General Public17 * License along with this library; if not, write to the Free18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19 *20 * @(#)crypt.c 2.19 5/28/9221 *22 * Semiportable C version23 *24 */25 26 #include "ufc-crypt.h"27 28 #ifdef _UFC_32_29 30 /*31 * 32 bit version32 */33 34 extern long32 _ufc_keytab[16][2];35 extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];36 37 #define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))38 39 static ufc_long ary[4];40 41 ufc_long *_ufc_doit(l1, l2, r1, r2, itr)42 ufc_long l1, l2, r1, r2, itr;43 { int i;44 long32 s, *k;45 register long32 *sb0 = _ufc_sb0;46 register long32 *sb1 = _ufc_sb1;47 register long32 *sb2 = _ufc_sb2;48 register long32 *sb3 = _ufc_sb3;49 50 while(itr--) {51 k = &_ufc_keytab[0][0];52 for(i=8; i--; ) {53 s = *k++ ^ r1;54 l1 ^= SBA(sb1, s & 0xffff); l2 ^= SBA(sb1, (s & 0xffff)+4);55 l1 ^= SBA(sb0, s >>= 16); l2 ^= SBA(sb0, (s) +4);56 s = *k++ ^ r2;57 l1 ^= SBA(sb3, s & 0xffff); l2 ^= SBA(sb3, (s & 0xffff)+4);58 l1 ^= SBA(sb2, s >>= 16); l2 ^= SBA(sb2, (s) +4);59 60 s = *k++ ^ l1;61 r1 ^= SBA(sb1, s & 0xffff); r2 ^= SBA(sb1, (s & 0xffff)+4);62 r1 ^= SBA(sb0, s >>= 16); r2 ^= SBA(sb0, (s) +4);63 s = *k++ ^ l2;64 r1 ^= SBA(sb3, s & 0xffff); r2 ^= SBA(sb3, (s & 0xffff)+4);65 r1 ^= SBA(sb2, s >>= 16); r2 ^= SBA(sb2, (s) +4);66 }67 s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;68 }69 ary[0] = l1; ary[1] = l2; ary[2] = r1; ary[3] = r2;70 return ary;71 }72 73 #endif74 75 #ifdef _UFC_64_76 77 /*78 * 64 bit version79 */80 81 extern long64 _ufc_keytab[16];82 extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];83 84 #define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))85 86 static ufc_long ary[4];87 88 ufc_long *_ufc_doit(l1, l2, r1, r2, itr)89 ufc_long l1, l2, r1, r2, itr;90 { int i;91 long64 l, r, s, *k;92 register long64 *sb0 = _ufc_sb0;93 register long64 *sb1 = _ufc_sb1;94 register long64 *sb2 = _ufc_sb2;95 register long64 *sb3 = _ufc_sb3;96 97 l = (((long64)l1) << 32) | ((long64)l2);98 r = (((long64)r1) << 32) | ((long64)r2);99 100 while(itr--) {101 k = &_ufc_keytab[0];102 for(i=8; i--; ) {103 s = *k++ ^ r;104 l ^= SBA(sb3, (s >> 0) & 0xffff);105 l ^= SBA(sb2, (s >> 16) & 0xffff);106 l ^= SBA(sb1, (s >> 32) & 0xffff);107 l ^= SBA(sb0, (s >> 48) & 0xffff);108 109 s = *k++ ^ l;110 r ^= SBA(sb3, (s >> 0) & 0xffff);111 r ^= SBA(sb2, (s >> 16) & 0xffff);112 r ^= SBA(sb1, (s >> 32) & 0xffff);113 r ^= SBA(sb0, (s >> 48) & 0xffff);114 }115 s=l; l=r; r=s;116 }117 118 ary[0] = l >> 32; ary[1] = l & 0xffffffff;119 ary[2] = r >> 32; ary[3] = r & 0xffffffff;120 return ary;121 }122 123 #endif -
new file src/system/libroot/posix/crypt/crypt.cpp
diff --git a/src/system/libroot/posix/crypt/crypt.cpp b/src/system/libroot/posix/crypt/crypt.cpp new file mode 100644 index 0000000..bf62ffc
- + 1 /* 2 * Copyright 2017, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Andrew Aldridge, i80and@foxquill.com 7 */ 8 9 #include <assert.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <inttypes.h> 13 #include <math.h> 14 #include <stdio.h> 15 #include <string.h> 16 17 #include <SupportDefs.h> 18 19 #include "crypt_legacy.h" 20 #include "crypto_scrypt.h" 21 22 #define SALT_BYTES 32 23 #define SALT_STR_BYTES (SALT_BYTES * 2 + 1) 24 #define DEFAULT_N_LOG2 14 25 #define MINIMUM_N_LOG2 12 26 27 // $s$99$ salt $ hash \0 28 #define CRYPT_OUTPUT_BYTES (6 + 64 + 1 + 64 + 1) 29 30 static const char* kHexAlphabet = "0123456789abcdef"; 31 static const char kHexLookup[] = { 32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 35 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15}; 38 39 40 static int 41 toHex(const uint8* buffer, size_t bufferLength, char* outBuffer, 42 size_t outBufferLength) 43 { 44 size_t i; 45 size_t outIndex = 0; 46 47 if (outBufferLength <= bufferLength * 2) { 48 outBuffer[0] = '\0'; 49 return 1; 50 } 51 52 for (i = 0; i < bufferLength; i += 1) { 53 const uint8 n = buffer[i]; 54 const uint8 upper = n >> 4; 55 const uint8 lower = n & 0x0f; 56 57 assert(lower < 16 && upper < 16); 58 outBuffer[outIndex++] = kHexAlphabet[upper]; 59 outBuffer[outIndex++] = kHexAlphabet[lower]; 60 outBuffer[outIndex] = '\0'; 61 } 62 63 outBuffer[outIndex] = '\0'; 64 65 return 0; 66 } 67 68 69 static size_t 70 fromHex(const char* hex, uint8* outBuffer, size_t outBufferLength) 71 { 72 size_t i = 0; 73 size_t outIndex = 0; 74 75 if (hex[0] == '\0' || outBufferLength == 0) 76 return 0; 77 78 while (hex[i] != '\0' && hex[i + 1] != '\0') { 79 const uint8 char1 = hex[i]; 80 const uint8 char2 = hex[i + 1]; 81 82 if (char1 >= sizeof(kHexLookup) || char2 >= sizeof(kHexLookup)) 83 return outIndex; 84 85 const char index1 = kHexLookup[char1]; 86 const char index2 = kHexLookup[char2]; 87 88 if (outIndex >= outBufferLength) 89 return 0; 90 91 outBuffer[outIndex++] = (index1 << 4) | index2; 92 i += 2; 93 } 94 95 return outIndex; 96 } 97 98 99 //! Generate a new salt appropriate for crypt(). 100 char* 101 crypt_gensalt(int hardness) 102 { 103 static char result[CRYPT_OUTPUT_BYTES]; 104 uint8 salt[SALT_BYTES]; 105 char saltString[SALT_STR_BYTES]; 106 size_t totalBytesRead = 0; 107 108 int fd = open("/dev/random", O_RDONLY, 0); 109 if (fd < 0) 110 return NULL; 111 112 if (hardness < 0) 113 hardness = DEFAULT_N_LOG2; 114 else if (hardness < MINIMUM_N_LOG2) { 115 errno = EINVAL; 116 return NULL; 117 } 118 119 while (totalBytesRead < sizeof(salt)) { 120 const ssize_t bytesRead = read(fd, 121 static_cast<void*>(salt + totalBytesRead), 122 sizeof(salt) - totalBytesRead); 123 if (bytesRead <= 0) { 124 close(fd); 125 return NULL; 126 } 127 128 totalBytesRead += bytesRead; 129 } 130 close(fd); 131 132 assert(toHex(salt, sizeof(salt), saltString, sizeof(saltString)) == 0); 133 snprintf(result, sizeof(result), "$s$%d$%s$", hardness, saltString); 134 return result; 135 } 136 137 138 char * 139 crypt(const char* key, const char* setting) 140 { 141 static char outBuffer[CRYPT_OUTPUT_BYTES]; 142 uint8 saltBinary[SALT_BYTES]; 143 char saltString[SALT_STR_BYTES]; 144 uint8 resultBuffer[32]; 145 char hexResultBuffer[64 + 1]; 146 int nLog2 = DEFAULT_N_LOG2; 147 148 // Some idioms existed where the password was also used as the salt. 149 // As a crude heuristic, use the old crypt algorithm if the salt is 150 // shortish. 151 if (strlen(setting) < 16) 152 return crypt_legacy(key, setting); 153 154 // We don't want to fall into the old algorithm by accident somehow, so 155 // if our salt is kind of like our salt, but not exactly, return an 156 // error. 157 if (sscanf(setting, "$s$%2d$%64s$", &nLog2, saltString) != 2) { 158 errno = EINVAL; 159 return NULL; 160 } 161 162 // Set a lower bound on N_log2: below 12 scrypt is weaker than bcrypt. 163 if (nLog2 < MINIMUM_N_LOG2) { 164 errno = EINVAL; 165 return NULL; 166 } 167 168 size_t saltBinaryLength = fromHex(saltString, saltBinary, 169 sizeof(saltBinary)); 170 if (saltBinaryLength != sizeof(saltBinary)) { 171 errno = EINVAL; 172 return NULL; 173 } 174 175 long n = static_cast<long>(pow(2, nLog2)); 176 if (crypto_scrypt(reinterpret_cast<const uint8*>(key), strlen(key), 177 saltBinary, saltBinaryLength, n, 8, 1, resultBuffer, 178 sizeof(resultBuffer)) != 0) { 179 // crypto_scrypt sets errno itself 180 return NULL; 181 } 182 183 assert(toHex(resultBuffer, sizeof(resultBuffer), hexResultBuffer, 184 sizeof(hexResultBuffer)) == 0); 185 snprintf(outBuffer, sizeof(outBuffer), "$s$%d$%s$%s", nLog2, saltString, 186 hexResultBuffer); 187 188 return outBuffer; 189 } 190 191 192 //! To make fcrypt users happy. They don't need to call init_des. 193 char* 194 fcrypt(const char* key, const char* salt) 195 { 196 return crypt(key, salt); 197 } -
new file src/system/libroot/posix/crypt/crypt_legacy.c
diff --git a/src/system/libroot/posix/crypt/crypt_legacy.c b/src/system/libroot/posix/crypt/crypt_legacy.c new file mode 100644 index 0000000..c647e37
- + 1 /* 2 * UFC-crypt: ultra fast crypt(3) implementation 3 * 4 * Copyright (C) 1991, 1992, Free Software Foundation, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public 17 * License along with this library; if not, write to the Free 18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 * @(#)crypt.c 2.19 5/28/92 21 * 22 * Semiportable C version 23 * 24 */ 25 26 #include "ufc-crypt.h" 27 28 #ifdef _UFC_32_ 29 30 /* 31 * 32 bit version 32 */ 33 34 extern long32 _ufc_keytab[16][2]; 35 extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; 36 37 #define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) 38 39 static ufc_long ary[4]; 40 41 ufc_long *_ufc_doit(l1, l2, r1, r2, itr) 42 ufc_long l1, l2, r1, r2, itr; 43 { int i; 44 long32 s, *k; 45 register long32 *sb0 = _ufc_sb0; 46 register long32 *sb1 = _ufc_sb1; 47 register long32 *sb2 = _ufc_sb2; 48 register long32 *sb3 = _ufc_sb3; 49 50 while(itr--) { 51 k = &_ufc_keytab[0][0]; 52 for(i=8; i--; ) { 53 s = *k++ ^ r1; 54 l1 ^= SBA(sb1, s & 0xffff); l2 ^= SBA(sb1, (s & 0xffff)+4); 55 l1 ^= SBA(sb0, s >>= 16); l2 ^= SBA(sb0, (s) +4); 56 s = *k++ ^ r2; 57 l1 ^= SBA(sb3, s & 0xffff); l2 ^= SBA(sb3, (s & 0xffff)+4); 58 l1 ^= SBA(sb2, s >>= 16); l2 ^= SBA(sb2, (s) +4); 59 60 s = *k++ ^ l1; 61 r1 ^= SBA(sb1, s & 0xffff); r2 ^= SBA(sb1, (s & 0xffff)+4); 62 r1 ^= SBA(sb0, s >>= 16); r2 ^= SBA(sb0, (s) +4); 63 s = *k++ ^ l2; 64 r1 ^= SBA(sb3, s & 0xffff); r2 ^= SBA(sb3, (s & 0xffff)+4); 65 r1 ^= SBA(sb2, s >>= 16); r2 ^= SBA(sb2, (s) +4); 66 } 67 s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; 68 } 69 ary[0] = l1; ary[1] = l2; ary[2] = r1; ary[3] = r2; 70 return ary; 71 } 72 73 #endif 74 75 #ifdef _UFC_64_ 76 77 /* 78 * 64 bit version 79 */ 80 81 extern long64 _ufc_keytab[16]; 82 extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; 83 84 #define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) 85 86 static ufc_long ary[4]; 87 88 ufc_long *_ufc_doit(l1, l2, r1, r2, itr) 89 ufc_long l1, l2, r1, r2, itr; 90 { int i; 91 long64 l, r, s, *k; 92 register long64 *sb0 = _ufc_sb0; 93 register long64 *sb1 = _ufc_sb1; 94 register long64 *sb2 = _ufc_sb2; 95 register long64 *sb3 = _ufc_sb3; 96 97 l = (((long64)l1) << 32) | ((long64)l2); 98 r = (((long64)r1) << 32) | ((long64)r2); 99 100 while(itr--) { 101 k = &_ufc_keytab[0]; 102 for(i=8; i--; ) { 103 s = *k++ ^ r; 104 l ^= SBA(sb3, (s >> 0) & 0xffff); 105 l ^= SBA(sb2, (s >> 16) & 0xffff); 106 l ^= SBA(sb1, (s >> 32) & 0xffff); 107 l ^= SBA(sb0, (s >> 48) & 0xffff); 108 109 s = *k++ ^ l; 110 r ^= SBA(sb3, (s >> 0) & 0xffff); 111 r ^= SBA(sb2, (s >> 16) & 0xffff); 112 r ^= SBA(sb1, (s >> 32) & 0xffff); 113 r ^= SBA(sb0, (s >> 48) & 0xffff); 114 } 115 s=l; l=r; r=s; 116 } 117 118 ary[0] = l >> 32; ary[1] = l & 0xffffffff; 119 ary[2] = r >> 32; ary[3] = r & 0xffffffff; 120 return ary; 121 } 122 123 #endif -
new file src/system/libroot/posix/crypt/crypt_legacy.h
diff --git a/src/system/libroot/posix/crypt/crypt_legacy.h b/src/system/libroot/posix/crypt/crypt_legacy.h new file mode 100644 index 0000000..62774a4
- + 1 #ifndef CRYPT_LEGACY_H 2 #define CRYPT_LEGACY_H 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 char *crypt_legacy(const char *key, const char *salt); 9 10 #ifdef __cplusplus 11 } 12 #endif 13 14 #endif // CRYPT_LEGACY_H -
new file src/system/libroot/posix/crypt/crypt_legacy_util.c
diff --git a/src/system/libroot/posix/crypt/crypt_legacy_util.c b/src/system/libroot/posix/crypt/crypt_legacy_util.c new file mode 100644 index 0000000..9c44fc6
- + 1 /* 2 * UFC-crypt: ultra fast crypt(3) implementation 3 * 4 * Copyright (C) 1991, 1992, Free Software Foundation, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public 17 * License along with this library; if not, write to the Free 18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 * @(#)crypt_util.c 2.40 09/21/92 21 * 22 * Support routines 23 * 24 */ 25 26 #include <string.h> 27 #include "crypt_legacy.h" 28 29 #ifdef DEBUG 30 #include <stdio.h> 31 #endif 32 33 #ifndef STATIC 34 #define STATIC static 35 #endif 36 37 #ifndef DOS 38 #include "patchlevel.h" 39 #include "ufc-crypt.h" 40 #else 41 /* 42 * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein) 43 * for DOS patches 44 */ 45 #include "pl.h" 46 #include "ufc.h" 47 #endif 48 49 static char patchlevel_str[] = PATCHLEVEL; 50 51 /* 52 * Permutation done once on the 56 bit 53 * key derived from the original 8 byte ASCII key. 54 */ 55 static int pc1[56] = { 56 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 57 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 58 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 59 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 60 }; 61 62 /* 63 * How much to rotate each 28 bit half of the pc1 permutated 64 * 56 bit key before using pc2 to give the i' key 65 */ 66 static int rots[16] = { 67 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 68 }; 69 70 /* 71 * Permutation giving the key 72 * of the i' DES round 73 */ 74 static int pc2[48] = { 75 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 76 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 77 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 78 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 79 }; 80 81 /* 82 * The E expansion table which selects 83 * bits from the 32 bit intermediate result. 84 */ 85 static int esel[48] = { 86 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 87 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 88 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 89 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 90 }; 91 static int e_inverse[64]; 92 93 /* 94 * Permutation done on the 95 * result of sbox lookups 96 */ 97 static int perm32[32] = { 98 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 99 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 100 }; 101 102 /* 103 * The sboxes 104 */ 105 static int sbox[8][4][16]= { 106 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, 107 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, 108 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, 109 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } 110 }, 111 112 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, 113 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, 114 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, 115 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } 116 }, 117 118 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, 119 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, 120 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, 121 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } 122 }, 123 124 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, 125 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, 126 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, 127 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } 128 }, 129 130 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, 131 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, 132 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, 133 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } 134 }, 135 136 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, 137 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, 138 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, 139 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } 140 }, 141 142 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, 143 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, 144 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, 145 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } 146 }, 147 148 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, 149 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, 150 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, 151 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } 152 } 153 }; 154 155 /* 156 * This is the initial 157 * permutation matrix 158 */ 159 static int initial_perm[64] = { 160 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 161 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 162 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 163 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 164 }; 165 166 /* 167 * This is the final 168 * permutation matrix 169 */ 170 static int final_perm[64] = { 171 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 172 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 173 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 174 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 175 }; 176 177 /* 178 * The 16 DES keys in BITMASK format 179 */ 180 #ifdef _UFC_32_ 181 long32 _ufc_keytab[16][2]; 182 #endif 183 #ifdef _UFC_64_ 184 long64 _ufc_keytab[16]; 185 #endif 186 187 #define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') 188 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') 189 190 /* Macro to set a bit (0..23) */ 191 #define BITMASK(i) ( (1L<<(11L-(i)%12L+3L)) << ((i)<12L?16L:0L) ) 192 193 /* 194 * sb arrays: 195 * 196 * Workhorses of the inner loop of the DES implementation. 197 * They do sbox lookup, shifting of this value, 32 bit 198 * permutation and E permutation for the next round. 199 * 200 * Kept in 'BITMASK' format. 201 */ 202 203 #ifdef _UFC_32_ 204 long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192]; 205 static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; 206 #endif 207 208 #ifdef _UFC_64_ 209 long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096]; 210 static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; 211 #endif 212 213 /* 214 * eperm32tab: do 32 bit permutation and E selection 215 * 216 * The first index is the byte number in the 32 bit value to be permuted 217 * - second - is the value of this byte 218 * - third - selects the two 32 bit values 219 * 220 * The table is used and generated internally in init_des to speed it up 221 */ 222 static ufc_long eperm32tab[4][256][2]; 223 224 /* 225 * do_pc1: permform pc1 permutation in the key schedule generation. 226 * 227 * The first index is the byte number in the 8 byte ASCII key 228 * - second - - the two 28 bits halfs of the result 229 * - third - selects the 7 bits actually used of each byte 230 * 231 * The result is kept with 28 bit per 32 bit with the 4 most significant 232 * bits zero. 233 */ 234 static ufc_long do_pc1[8][2][128]; 235 236 /* 237 * do_pc2: permform pc2 permutation in the key schedule generation. 238 * 239 * The first index is the septet number in the two 28 bit intermediate values 240 * - second - - - septet values 241 * 242 * Knowledge of the structure of the pc2 permutation is used. 243 * 244 * The result is kept with 28 bit per 32 bit with the 4 most significant 245 * bits zero. 246 */ 247 static ufc_long do_pc2[8][128]; 248 249 /* 250 * efp: undo an extra e selection and do final 251 * permutation giving the DES result. 252 * 253 * Invoked 6 bit a time on two 48 bit values 254 * giving two 32 bit longs. 255 */ 256 static ufc_long efp[16][64][2]; 257 258 /* 259 * revfinal: undo final permutation and do E expension. 260 * 261 * Invoked 6 bit a time on DES output 262 * giving 4 32 bit longs. 263 */ 264 static ufc_long revfinal[11][64][4]; 265 266 267 static unsigned char bytemask[8] = { 268 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 269 }; 270 271 static ufc_long longmask[32] = { 272 0x80000000, 0x40000000, 0x20000000, 0x10000000, 273 0x08000000, 0x04000000, 0x02000000, 0x01000000, 274 0x00800000, 0x00400000, 0x00200000, 0x00100000, 275 0x00080000, 0x00040000, 0x00020000, 0x00010000, 276 0x00008000, 0x00004000, 0x00002000, 0x00001000, 277 0x00000800, 0x00000400, 0x00000200, 0x00000100, 278 0x00000080, 0x00000040, 0x00000020, 0x00000010, 279 0x00000008, 0x00000004, 0x00000002, 0x00000001 280 }; 281 282 #ifdef DEBUG 283 284 pr_bits(a, n) 285 ufc_long *a; 286 int n; 287 { ufc_long i, j, t, tmp; 288 n /= 8; 289 for(i = 0; i < n; i++) { 290 tmp=0; 291 for(j = 0; j < 8; j++) { 292 t=8*i+j; 293 tmp|=(a[t/24] & BITMASK(t % 24))?bytemask[j]:0; 294 } 295 (void)printf("%02x ",tmp); 296 } 297 printf(" "); 298 } 299 300 static set_bits(v, b) 301 ufc_long v; 302 ufc_long *b; 303 { ufc_long i; 304 *b = 0; 305 for(i = 0; i < 24; i++) { 306 if(v & longmask[8 + i]) 307 *b |= BITMASK(i); 308 } 309 } 310 311 #endif 312 313 /* 314 * Silly rewrite of 'bzero'. I do so 315 * because some machines don't have 316 * bzero and some don't have memset. 317 */ 318 319 STATIC void clearmem(start, cnt) 320 char *start; 321 int cnt; 322 { while(cnt--) 323 *start++ = '\0'; 324 } 325 326 static int initialized = 0; 327 328 /* lookup a 6 bit value in sbox */ 329 330 #define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf]; 331 332 /* 333 * Initialize unit - may be invoked directly 334 * by fcrypt users. 335 */ 336 337 void init_des() 338 { int comes_from_bit; 339 int bit, sg; 340 ufc_long j; 341 ufc_long mask1, mask2; 342 343 /* 344 * Create the do_pc1 table used 345 * to affect pc1 permutation 346 * when generating keys 347 */ 348 for(bit = 0; bit < 56; bit++) { 349 comes_from_bit = pc1[bit] - 1; 350 mask1 = bytemask[comes_from_bit % 8 + 1]; 351 mask2 = longmask[bit % 28 + 4]; 352 for(j = 0; j < 128; j++) { 353 if(j & mask1) 354 do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2; 355 } 356 } 357 358 /* 359 * Create the do_pc2 table used 360 * to affect pc2 permutation when 361 * generating keys 362 */ 363 for(bit = 0; bit < 48; bit++) { 364 comes_from_bit = pc2[bit] - 1; 365 mask1 = bytemask[comes_from_bit % 7 + 1]; 366 mask2 = BITMASK(bit % 24); 367 for(j = 0; j < 128; j++) { 368 if(j & mask1) 369 do_pc2[comes_from_bit / 7][j] |= mask2; 370 } 371 } 372 373 /* 374 * Now generate the table used to do combined 375 * 32 bit permutation and e expansion 376 * 377 * We use it because we have to permute 16384 32 bit 378 * longs into 48 bit in order to initialize sb. 379 * 380 * Looping 48 rounds per permutation becomes 381 * just too slow... 382 * 383 */ 384 385 clearmem((char*)eperm32tab, sizeof(eperm32tab)); 386 387 for(bit = 0; bit < 48; bit++) { 388 ufc_long mask1,comes_from; 389 390 comes_from = perm32[esel[bit]-1]-1; 391 mask1 = bytemask[comes_from % 8]; 392 393 for(j = 256; j--;) { 394 if(j & mask1) 395 eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); 396 } 397 } 398 399 /* 400 * Create the sb tables: 401 * 402 * For each 12 bit segment of an 48 bit intermediate 403 * result, the sb table precomputes the two 4 bit 404 * values of the sbox lookups done with the two 6 405 * bit halves, shifts them to their proper place, 406 * sends them through perm32 and finally E expands 407 * them so that they are ready for the next 408 * DES round. 409 * 410 */ 411 for(sg = 0; sg < 4; sg++) { 412 int j1, j2; 413 int s1, s2; 414 415 for(j1 = 0; j1 < 64; j1++) { 416 s1 = s_lookup(2 * sg, j1); 417 for(j2 = 0; j2 < 64; j2++) { 418 ufc_long to_permute, inx; 419 420 s2 = s_lookup(2 * sg + 1, j2); 421 to_permute = (((ufc_long)s1 << 4) | 422 (ufc_long)s2) << (24 - 8 * (ufc_long)sg); 423 424 #ifdef _UFC_32_ 425 inx = ((j1 << 6) | j2) << 1; 426 sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0]; 427 sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1]; 428 sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0]; 429 sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1]; 430 sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0]; 431 sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1]; 432 sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0]; 433 sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1]; 434 #endif 435 #ifdef _UFC_64_ 436 inx = ((j1 << 6) | j2); 437 sb[sg][inx] = 438 ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) | 439 (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1]; 440 sb[sg][inx] |= 441 ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) | 442 (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1]; 443 sb[sg][inx] |= 444 ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) | 445 (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1]; 446 sb[sg][inx] |= 447 ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) | 448 (long64)eperm32tab[3][(to_permute) & 0xff][1]; 449 #endif 450 } 451 } 452 } 453 454 /* 455 * Create an inverse matrix for esel telling 456 * where to plug out bits if undoing it 457 */ 458 for(bit=48; bit--;) { 459 e_inverse[esel[bit] - 1 ] = bit; 460 e_inverse[esel[bit] - 1 + 32] = bit + 48; 461 } 462 463 /* 464 * create efp: the matrix used to 465 * undo the E expansion and effect final permutation 466 */ 467 clearmem((char*)efp, sizeof efp); 468 for(bit = 0; bit < 64; bit++) { 469 int o_bit, o_long; 470 ufc_long word_value, mask1, mask2; 471 int comes_from_f_bit, comes_from_e_bit; 472 int comes_from_word, bit_within_word; 473 474 /* See where bit i belongs in the two 32 bit long's */ 475 o_long = bit / 32; /* 0..1 */ 476 o_bit = bit % 32; /* 0..31 */ 477 478 /* 479 * And find a bit in the e permutated value setting this bit. 480 * 481 * Note: the e selection may have selected the same bit several 482 * times. By the initialization of e_inverse, we only look 483 * for one specific instance. 484 */ 485 comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */ 486 comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */ 487 comes_from_word = comes_from_e_bit / 6; /* 0..15 */ 488 bit_within_word = comes_from_e_bit % 6; /* 0..5 */ 489 490 mask1 = longmask[bit_within_word + 26]; 491 mask2 = longmask[o_bit]; 492 493 for(word_value = 64; word_value--;) { 494 if(word_value & mask1) 495 efp[comes_from_word][word_value][o_long] |= mask2; 496 } 497 } 498 499 500 /* 501 * Create revfinal: an array to undo final 502 * the effects of efp 503 */ 504 clearmem((char*)revfinal, sizeof(revfinal)); 505 for(bit = 0; bit < 96; bit++) { 506 int ibit = initial_perm[esel[bit % 48] - 1 + ((bit >= 48) ? 32 : 0)] - 1; 507 mask1 = bytemask[ibit % 6 + 2]; 508 mask2 = BITMASK(bit % 24); 509 for(j = 64; j--;) { 510 if(j & mask1) { 511 revfinal[ibit / 6][j][bit / 24] |= mask2; 512 } 513 } 514 } 515 516 initialized++; 517 } 518 519 /* 520 * Process the elements of the sb table permuting the 521 * bits swapped in the expansion by the current salt. 522 */ 523 524 #ifdef _UFC_32_ 525 STATIC void shuffle_sb(k, saltbits) 526 long32 *k; 527 ufc_long saltbits; 528 { ufc_long j; 529 long32 x; 530 for(j=4096; j--;) { 531 x = (k[0] ^ k[1]) & (long32)saltbits; 532 *k++ ^= x; 533 *k++ ^= x; 534 } 535 } 536 #endif 537 538 #ifdef _UFC_64_ 539 STATIC void shuffle_sb(k, saltbits) 540 long64 *k; 541 ufc_long saltbits; 542 { ufc_long j; 543 long64 x; 544 for(j=4096; j--;) { 545 x = ((*k >> 32) ^ *k) & (long64)saltbits; 546 *k++ ^= (x << 32) | x; 547 } 548 } 549 #endif 550 551 /* 552 * Setup the unit for a new salt 553 * Hopefully we'll not see a new salt in each crypt call. 554 */ 555 556 static unsigned char current_salt[3] = "&&"; /* invalid value */ 557 static ufc_long current_saltbits = 0; 558 static int direction = 0; 559 560 STATIC void setup_salt(s) 561 char *s; 562 { ufc_long i, j, saltbits; 563 564 if(!initialized) 565 init_des(); 566 567 if(s[0] == current_salt[0] && s[1] == current_salt[1]) 568 return; 569 current_salt[0] = s[0]; current_salt[1] = s[1]; 570 571 /* 572 * This is the only crypt change to DES: 573 * entries are swapped in the expansion table 574 * according to the bits set in the salt. 575 */ 576 saltbits = 0; 577 for(i = 0; i < 2; i++) { 578 long c=ascii_to_bin(s[i]); 579 #ifdef notdef 580 /* 581 * Some applications do rely on illegal 582 * salts. It seems that UFC-crypt behaves 583 * identically to standard crypt 584 * implementations on illegal salts -- glad 585 */ 586 if(c < 0 || c > 63) 587 c = 0; 588 #endif 589 for(j = 0; j < 6; j++) { 590 if((c >> j) & 0x1) 591 saltbits |= BITMASK(6 * i + j); 592 } 593 } 594 595 /* 596 * Permute the sb table values 597 * to reflect the changed e 598 * selection table 599 */ 600 shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits); 601 shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits); 602 shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits); 603 shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits); 604 605 current_saltbits = saltbits; 606 } 607 608 STATIC void ufc_mk_keytab(key) 609 char *key; 610 { ufc_long v1, v2, *k1; 611 int i; 612 #ifdef _UFC_32_ 613 long32 v, *k2 = &_ufc_keytab[0][0]; 614 #endif 615 #ifdef _UFC_64_ 616 long64 v, *k2 = &_ufc_keytab[0]; 617 #endif 618 619 v1 = v2 = 0; k1 = &do_pc1[0][0][0]; 620 for(i = 8; i--;) { 621 v1 |= k1[*key & 0x7f]; k1 += 128; 622 v2 |= k1[*key++ & 0x7f]; k1 += 128; 623 } 624 625 for(i = 0; i < 16; i++) { 626 k1 = &do_pc2[0][0]; 627 628 v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i])); 629 v = k1[(v1 >> 21) & 0x7f]; k1 += 128; 630 v |= k1[(v1 >> 14) & 0x7f]; k1 += 128; 631 v |= k1[(v1 >> 7) & 0x7f]; k1 += 128; 632 v |= k1[(v1 ) & 0x7f]; k1 += 128; 633 634 #ifdef _UFC_32_ 635 *k2++ = v; 636 v = 0; 637 #endif 638 #ifdef _UFC_64_ 639 v <<= 32; 640 #endif 641 642 v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i])); 643 v |= k1[(v2 >> 21) & 0x7f]; k1 += 128; 644 v |= k1[(v2 >> 14) & 0x7f]; k1 += 128; 645 v |= k1[(v2 >> 7) & 0x7f]; k1 += 128; 646 v |= k1[(v2 ) & 0x7f]; 647 648 *k2++ = v; 649 } 650 651 direction = 0; 652 } 653 654 /* 655 * Undo an extra E selection and do final permutations 656 */ 657 658 ufc_long *_ufc_dofinalperm(l1, l2, r1, r2) 659 ufc_long l1,l2,r1,r2; 660 { ufc_long v1, v2, x; 661 static ufc_long ary[2]; 662 663 x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x; 664 x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x; 665 666 v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3; 667 668 v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1]; 669 v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1]; 670 v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1]; 671 v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1]; 672 673 v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1]; 674 v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1]; 675 v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1]; 676 v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1]; 677 678 v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1]; 679 v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1]; 680 v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1]; 681 v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1]; 682 683 v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1]; 684 v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1]; 685 v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1]; 686 v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1]; 687 688 ary[0] = v1; ary[1] = v2; 689 return ary; 690 } 691 692 /* 693 * crypt only: convert from 64 bit to 11 bit ASCII 694 * prefixing with the salt 695 */ 696 697 STATIC char *output_conversion(v1, v2, salt) 698 ufc_long v1, v2; 699 char *salt; 700 { static char outbuf[14]; 701 int i, s, shf; 702 703 outbuf[0] = salt[0]; 704 outbuf[1] = salt[1] ? salt[1] : salt[0]; 705 706 for(i = 0; i < 5; i++) { 707 shf = (26 - 6 * i); /* to cope with MSC compiler bug */ 708 outbuf[i + 2] = bin_to_ascii((v1 >> shf) & 0x3f); 709 } 710 711 s = (v2 & 0xf) << 2; 712 v2 = (v2 >> 2) | ((v1 & 0x3) << 30); 713 714 for(i = 5; i < 10; i++) { 715 shf = (56 - 6 * i); 716 outbuf[i + 2] = bin_to_ascii((v2 >> shf) & 0x3f); 717 } 718 719 outbuf[12] = bin_to_ascii(s); 720 outbuf[13] = 0; 721 722 return outbuf; 723 } 724 725 ufc_long *_ufc_doit(); 726 727 /* 728 * UNIX crypt function 729 */ 730 731 char *crypt_legacy(key, salt) 732 const char *key, *salt; 733 { ufc_long *s; 734 char ktab[9]; 735 736 /* 737 * Hack DES tables according to salt 738 */ 739 setup_salt(salt); 740 741 /* 742 * Setup key schedule 743 */ 744 clearmem(ktab, sizeof ktab); 745 (void)strncpy(ktab, key, 8); 746 ufc_mk_keytab(ktab); 747 748 /* 749 * Go for the 25 DES encryptions 750 */ 751 s = _ufc_doit((ufc_long)0, (ufc_long)0, 752 (ufc_long)0, (ufc_long)0, (ufc_long)25); 753 /* 754 * Do final permutations 755 */ 756 s = _ufc_dofinalperm(s[0], s[1], s[2], s[3]); 757 758 /* 759 * And convert back to 6 bit ASCII 760 */ 761 return output_conversion(s[0], s[1], salt); 762 } 763 764 /* 765 * UNIX encrypt function. Takes a bitvector 766 * represented by one byte per bit and 767 * encrypt/decrypt according to edflag 768 */ 769 770 void encrypt(block, edflag) 771 char *block; 772 int edflag; 773 { ufc_long l1, l2, r1, r2, *s; 774 int i; 775 776 /* 777 * Undo any salt changes to E expansion 778 */ 779 setup_salt(".."); 780 781 /* 782 * Reverse key table if 783 * changing operation (encrypt/decrypt) 784 */ 785 if((edflag == 0) != (direction == 0)) { 786 for(i = 0; i < 8; i++) { 787 #ifdef _UFC_32_ 788 long32 x; 789 x = _ufc_keytab[15-i][0]; 790 _ufc_keytab[15-i][0] = _ufc_keytab[i][0]; 791 _ufc_keytab[i][0] = x; 792 793 x = _ufc_keytab[15-i][1]; 794 _ufc_keytab[15-i][1] = _ufc_keytab[i][1]; 795 _ufc_keytab[i][1] = x; 796 #endif 797 #ifdef _UFC_64_ 798 long64 x; 799 x = _ufc_keytab[15-i]; 800 _ufc_keytab[15-i] = _ufc_keytab[i]; 801 _ufc_keytab[i] = x; 802 #endif 803 } 804 direction = edflag; 805 } 806 807 /* 808 * Do initial permutation + E expansion 809 */ 810 i = 0; 811 for(l1 = 0; i < 24; i++) { 812 if(block[initial_perm[esel[i]-1]-1]) 813 l1 |= BITMASK(i); 814 } 815 for(l2 = 0; i < 48; i++) { 816 if(block[initial_perm[esel[i]-1]-1]) 817 l2 |= BITMASK(i-24); 818 } 819 820 i = 0; 821 for(r1 = 0; i < 24; i++) { 822 if(block[initial_perm[esel[i]-1+32]-1]) 823 r1 |= BITMASK(i); 824 } 825 for(r2 = 0; i < 48; i++) { 826 if(block[initial_perm[esel[i]-1+32]-1]) 827 r2 |= BITMASK(i-24); 828 } 829 830 /* 831 * Do DES inner loops + final conversion 832 */ 833 s = _ufc_doit(l1, l2, r1, r2, (ufc_long)1); 834 /* 835 * Do final permutations 836 */ 837 s = _ufc_dofinalperm(s[0], s[1], s[2], s[3]); 838 839 /* 840 * And convert to bit array 841 */ 842 l1 = s[0]; r1 = s[1]; 843 for(i = 0; i < 32; i++) { 844 *block++ = (l1 & longmask[i]) != 0; 845 } 846 for(i = 0; i < 32; i++) { 847 *block++ = (r1 & longmask[i]) != 0; 848 } 849 850 } 851 852 /* 853 * UNIX setkey function. Take a 64 bit DES 854 * key and setup the machinery. 855 */ 856 857 void setkey(key) 858 char *key; 859 { int i,j; 860 unsigned char c; 861 unsigned char ktab[8]; 862 863 setup_salt(".."); /* be sure we're initialized */ 864 865 for(i = 0; i < 8; i++) { 866 for(j = 0, c = 0; j < 8; j++) 867 c = c << 1 | *key++; 868 ktab[i] = c >> 1; 869 } 870 871 ufc_mk_keytab(ktab); 872 } 873 874 /* 875 * Ultrix crypt16 function, thanks to pcl@convex.oxford.ac.uk (Paul Leyland) 876 */ 877 878 char *crypt16(key, salt) 879 char *key, *salt; 880 { ufc_long *s, *t; 881 char ktab[9], ttab[9]; 882 static char q[14], res[25]; 883 /* 884 * Hack DES tables according to salt 885 */ 886 setup_salt(salt); 887 888 /* 889 * Setup key schedule 890 */ 891 clearmem(ktab, sizeof ktab); 892 (void)strncpy(ktab, key, 8); 893 ufc_mk_keytab(ktab); 894 895 /* 896 * Go for first 20 DES encryptions 897 */ 898 s = _ufc_doit((ufc_long)0, (ufc_long)0, 899 (ufc_long)0, (ufc_long)0, (ufc_long)20); 900 901 /* 902 * And convert back to 6 bit ASCII 903 */ 904 strcpy (res, output_conversion(s[0], s[1], salt)); 905 906 clearmem(ttab, sizeof ttab); 907 if (strlen (key) > 8) (void)strncpy(ttab, key+8, 8); 908 ufc_mk_keytab(ttab); 909 910 /* 911 * Go for second 5 DES encryptions 912 */ 913 t = _ufc_doit((ufc_long)0, (ufc_long)0, 914 (ufc_long)0, (ufc_long)0, (ufc_long)5); 915 /* 916 * And convert back to 6 bit ASCII 917 */ 918 strcpy (q, output_conversion(t[0], t[1], salt)); 919 strcpy (res+13, q+2); 920 921 clearmem(ktab, sizeof ktab); 922 (void)strncpy(ktab, key, 8); 923 ufc_mk_keytab(ktab); 924 925 return res; 926 } 927 928 /* 929 * Experimental -- not supported -- may choke your dog 930 */ 931 932 void ufc_setup_password(cookie, s) 933 long *cookie; 934 char *s; 935 { char c; 936 int i; 937 ufc_long x; 938 ufc_long dl1, dl2, dr1, dr2; 939 940 setup_salt(s); 941 dl1 = dl2 = dr1 = dr2 = 0; 942 for(i = 0, s += 2; c = *s++; i++) { 943 int x = ascii_to_bin(c); 944 dl1 |= revfinal[i][x][0]; 945 dl2 |= revfinal[i][x][1]; 946 dr1 |= revfinal[i][x][2]; 947 dr2 |= revfinal[i][x][3]; 948 } 949 x = (dl1 ^ dl2) & current_saltbits; 950 x = (dr1 ^ dr2) & current_saltbits; 951 cookie[0] = dl1 ^ x; cookie[1] = dl2 ^ x; 952 cookie[2] = dr1 ^ x; cookie[3] = dr2 ^ x; 953 } 954 955 void ufc_do_pw(cookie, guess) 956 long *cookie; 957 char *guess; 958 { char ktab[9]; 959 ufc_long *s; 960 clearmem(ktab, sizeof ktab); 961 (void)strncpy(ktab, guess, 8); 962 ufc_mk_keytab(ktab); 963 s = _ufc_doit((ufc_long)0, (ufc_long)0, 964 (ufc_long)0, (ufc_long)0, (ufc_long)25); 965 cookie[0] = s[0]; cookie[1] = s[1]; 966 cookie[2] = s[2]; cookie[3] = s[3]; 967 } -
deleted file src/system/libroot/posix/crypt/crypt_util.c
diff --git a/src/system/libroot/posix/crypt/crypt_util.c b/src/system/libroot/posix/crypt/crypt_util.c deleted file mode 100644 index c72a55f..0000000
+ - 1 /*2 * UFC-crypt: ultra fast crypt(3) implementation3 *4 * Copyright (C) 1991, 1992, Free Software Foundation, Inc.5 *6 * This library is free software; you can redistribute it and/or7 * modify it under the terms of the GNU Library General Public8 * License as published by the Free Software Foundation; either9 * version 2 of the License, or (at your option) any later version.10 *11 * This library is distributed in the hope that it will be useful,12 * but WITHOUT ANY WARRANTY; without even the implied warranty of13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU14 * Library General Public License for more details.15 *16 * You should have received a copy of the GNU Library General Public17 * License along with this library; if not, write to the Free18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19 *20 * @(#)crypt_util.c 2.40 09/21/9221 *22 * Support routines23 *24 */25 26 #include <string.h>27 28 #ifdef DEBUG29 #include <stdio.h>30 #endif31 32 #ifndef STATIC33 #define STATIC static34 #endif35 36 #ifndef DOS37 #include "patchlevel.h"38 #include "ufc-crypt.h"39 #else40 /*41 * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)42 * for DOS patches43 */44 #include "pl.h"45 #include "ufc.h"46 #endif47 48 static char patchlevel_str[] = PATCHLEVEL;49 50 /*51 * Permutation done once on the 56 bit52 * key derived from the original 8 byte ASCII key.53 */54 static int pc1[56] = {55 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,56 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,57 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,58 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 459 };60 61 /*62 * How much to rotate each 28 bit half of the pc1 permutated63 * 56 bit key before using pc2 to give the i' key64 */65 static int rots[16] = {66 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 167 };68 69 /*70 * Permutation giving the key71 * of the i' DES round72 */73 static int pc2[48] = {74 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,75 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,76 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,77 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 3278 };79 80 /*81 * The E expansion table which selects82 * bits from the 32 bit intermediate result.83 */84 static int esel[48] = {85 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,86 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,87 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,88 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 189 };90 static int e_inverse[64];91 92 /*93 * Permutation done on the94 * result of sbox lookups95 */96 static int perm32[32] = {97 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,98 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 2599 };100 101 /*102 * The sboxes103 */104 static int sbox[8][4][16]= {105 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },106 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },107 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },108 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }109 },110 111 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },112 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },113 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },114 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }115 },116 117 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },118 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },119 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },120 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }121 },122 123 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },124 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },125 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },126 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }127 },128 129 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },130 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },131 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },132 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }133 },134 135 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },136 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },137 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },138 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }139 },140 141 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },142 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },143 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },144 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }145 },146 147 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },148 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },149 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },150 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }151 }152 };153 154 /*155 * This is the initial156 * permutation matrix157 */158 static int initial_perm[64] = {159 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,160 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,161 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,162 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7163 };164 165 /*166 * This is the final167 * permutation matrix168 */169 static int final_perm[64] = {170 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,171 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,172 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,173 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25174 };175 176 /*177 * The 16 DES keys in BITMASK format178 */179 #ifdef _UFC_32_180 long32 _ufc_keytab[16][2];181 #endif182 #ifdef _UFC_64_183 long64 _ufc_keytab[16];184 #endif185 186 #define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')187 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')188 189 /* Macro to set a bit (0..23) */190 #define BITMASK(i) ( (1L<<(11L-(i)%12L+3L)) << ((i)<12L?16L:0L) )191 192 /*193 * sb arrays:194 *195 * Workhorses of the inner loop of the DES implementation.196 * They do sbox lookup, shifting of this value, 32 bit197 * permutation and E permutation for the next round.198 *199 * Kept in 'BITMASK' format.200 */201 202 #ifdef _UFC_32_203 long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192];204 static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};205 #endif206 207 #ifdef _UFC_64_208 long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096];209 static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};210 #endif211 212 /*213 * eperm32tab: do 32 bit permutation and E selection214 *215 * The first index is the byte number in the 32 bit value to be permuted216 * - second - is the value of this byte217 * - third - selects the two 32 bit values218 *219 * The table is used and generated internally in init_des to speed it up220 */221 static ufc_long eperm32tab[4][256][2];222 223 /*224 * do_pc1: permform pc1 permutation in the key schedule generation.225 *226 * The first index is the byte number in the 8 byte ASCII key227 * - second - - the two 28 bits halfs of the result228 * - third - selects the 7 bits actually used of each byte229 *230 * The result is kept with 28 bit per 32 bit with the 4 most significant231 * bits zero.232 */233 static ufc_long do_pc1[8][2][128];234 235 /*236 * do_pc2: permform pc2 permutation in the key schedule generation.237 *238 * The first index is the septet number in the two 28 bit intermediate values239 * - second - - - septet values240 *241 * Knowledge of the structure of the pc2 permutation is used.242 *243 * The result is kept with 28 bit per 32 bit with the 4 most significant244 * bits zero.245 */246 static ufc_long do_pc2[8][128];247 248 /*249 * efp: undo an extra e selection and do final250 * permutation giving the DES result.251 *252 * Invoked 6 bit a time on two 48 bit values253 * giving two 32 bit longs.254 */255 static ufc_long efp[16][64][2];256 257 /*258 * revfinal: undo final permutation and do E expension.259 *260 * Invoked 6 bit a time on DES output261 * giving 4 32 bit longs.262 */263 static ufc_long revfinal[11][64][4];264 265 266 static unsigned char bytemask[8] = {267 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01268 };269 270 static ufc_long longmask[32] = {271 0x80000000, 0x40000000, 0x20000000, 0x10000000,272 0x08000000, 0x04000000, 0x02000000, 0x01000000,273 0x00800000, 0x00400000, 0x00200000, 0x00100000,274 0x00080000, 0x00040000, 0x00020000, 0x00010000,275 0x00008000, 0x00004000, 0x00002000, 0x00001000,276 0x00000800, 0x00000400, 0x00000200, 0x00000100,277 0x00000080, 0x00000040, 0x00000020, 0x00000010,278 0x00000008, 0x00000004, 0x00000002, 0x00000001279 };280 281 #ifdef DEBUG282 283 pr_bits(a, n)284 ufc_long *a;285 int n;286 { ufc_long i, j, t, tmp;287 n /= 8;288 for(i = 0; i < n; i++) {289 tmp=0;290 for(j = 0; j < 8; j++) {291 t=8*i+j;292 tmp|=(a[t/24] & BITMASK(t % 24))?bytemask[j]:0;293 }294 (void)printf("%02x ",tmp);295 }296 printf(" ");297 }298 299 static set_bits(v, b)300 ufc_long v;301 ufc_long *b;302 { ufc_long i;303 *b = 0;304 for(i = 0; i < 24; i++) {305 if(v & longmask[8 + i])306 *b |= BITMASK(i);307 }308 }309 310 #endif311 312 /*313 * Silly rewrite of 'bzero'. I do so314 * because some machines don't have315 * bzero and some don't have memset.316 */317 318 STATIC void clearmem(start, cnt)319 char *start;320 int cnt;321 { while(cnt--)322 *start++ = '\0';323 }324 325 static int initialized = 0;326 327 /* lookup a 6 bit value in sbox */328 329 #define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];330 331 /*332 * Initialize unit - may be invoked directly333 * by fcrypt users.334 */335 336 void init_des()337 { int comes_from_bit;338 int bit, sg;339 ufc_long j;340 ufc_long mask1, mask2;341 342 /*343 * Create the do_pc1 table used344 * to affect pc1 permutation345 * when generating keys346 */347 for(bit = 0; bit < 56; bit++) {348 comes_from_bit = pc1[bit] - 1;349 mask1 = bytemask[comes_from_bit % 8 + 1];350 mask2 = longmask[bit % 28 + 4];351 for(j = 0; j < 128; j++) {352 if(j & mask1)353 do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;354 }355 }356 357 /*358 * Create the do_pc2 table used359 * to affect pc2 permutation when360 * generating keys361 */362 for(bit = 0; bit < 48; bit++) {363 comes_from_bit = pc2[bit] - 1;364 mask1 = bytemask[comes_from_bit % 7 + 1];365 mask2 = BITMASK(bit % 24);366 for(j = 0; j < 128; j++) {367 if(j & mask1)368 do_pc2[comes_from_bit / 7][j] |= mask2;369 }370 }371 372 /*373 * Now generate the table used to do combined374 * 32 bit permutation and e expansion375 *376 * We use it because we have to permute 16384 32 bit377 * longs into 48 bit in order to initialize sb.378 *379 * Looping 48 rounds per permutation becomes380 * just too slow...381 *382 */383 384 clearmem((char*)eperm32tab, sizeof(eperm32tab));385 386 for(bit = 0; bit < 48; bit++) {387 ufc_long mask1,comes_from;388 389 comes_from = perm32[esel[bit]-1]-1;390 mask1 = bytemask[comes_from % 8];391 392 for(j = 256; j--;) {393 if(j & mask1)394 eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24);395 }396 }397 398 /*399 * Create the sb tables:400 *401 * For each 12 bit segment of an 48 bit intermediate402 * result, the sb table precomputes the two 4 bit403 * values of the sbox lookups done with the two 6404 * bit halves, shifts them to their proper place,405 * sends them through perm32 and finally E expands406 * them so that they are ready for the next407 * DES round.408 *409 */410 for(sg = 0; sg < 4; sg++) {411 int j1, j2;412 int s1, s2;413 414 for(j1 = 0; j1 < 64; j1++) {415 s1 = s_lookup(2 * sg, j1);416 for(j2 = 0; j2 < 64; j2++) {417 ufc_long to_permute, inx;418 419 s2 = s_lookup(2 * sg + 1, j2);420 to_permute = (((ufc_long)s1 << 4) |421 (ufc_long)s2) << (24 - 8 * (ufc_long)sg);422 423 #ifdef _UFC_32_424 inx = ((j1 << 6) | j2) << 1;425 sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];426 sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];427 sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];428 sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];429 sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];430 sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];431 sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];432 sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];433 #endif434 #ifdef _UFC_64_435 inx = ((j1 << 6) | j2);436 sb[sg][inx] =437 ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |438 (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];439 sb[sg][inx] |=440 ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |441 (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];442 sb[sg][inx] |=443 ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |444 (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];445 sb[sg][inx] |=446 ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |447 (long64)eperm32tab[3][(to_permute) & 0xff][1];448 #endif449 }450 }451 }452 453 /*454 * Create an inverse matrix for esel telling455 * where to plug out bits if undoing it456 */457 for(bit=48; bit--;) {458 e_inverse[esel[bit] - 1 ] = bit;459 e_inverse[esel[bit] - 1 + 32] = bit + 48;460 }461 462 /*463 * create efp: the matrix used to464 * undo the E expansion and effect final permutation465 */466 clearmem((char*)efp, sizeof efp);467 for(bit = 0; bit < 64; bit++) {468 int o_bit, o_long;469 ufc_long word_value, mask1, mask2;470 int comes_from_f_bit, comes_from_e_bit;471 int comes_from_word, bit_within_word;472 473 /* See where bit i belongs in the two 32 bit long's */474 o_long = bit / 32; /* 0..1 */475 o_bit = bit % 32; /* 0..31 */476 477 /*478 * And find a bit in the e permutated value setting this bit.479 *480 * Note: the e selection may have selected the same bit several481 * times. By the initialization of e_inverse, we only look482 * for one specific instance.483 */484 comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */485 comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */486 comes_from_word = comes_from_e_bit / 6; /* 0..15 */487 bit_within_word = comes_from_e_bit % 6; /* 0..5 */488 489 mask1 = longmask[bit_within_word + 26];490 mask2 = longmask[o_bit];491 492 for(word_value = 64; word_value--;) {493 if(word_value & mask1)494 efp[comes_from_word][word_value][o_long] |= mask2;495 }496 }497 498 499 /*500 * Create revfinal: an array to undo final501 * the effects of efp502 */503 clearmem((char*)revfinal, sizeof(revfinal));504 for(bit = 0; bit < 96; bit++) {505 int ibit = initial_perm[esel[bit % 48] - 1 + ((bit >= 48) ? 32 : 0)] - 1;506 mask1 = bytemask[ibit % 6 + 2];507 mask2 = BITMASK(bit % 24);508 for(j = 64; j--;) {509 if(j & mask1) {510 revfinal[ibit / 6][j][bit / 24] |= mask2;511 }512 }513 }514 515 initialized++;516 }517 518 /*519 * Process the elements of the sb table permuting the520 * bits swapped in the expansion by the current salt.521 */522 523 #ifdef _UFC_32_524 STATIC void shuffle_sb(k, saltbits)525 long32 *k;526 ufc_long saltbits;527 { ufc_long j;528 long32 x;529 for(j=4096; j--;) {530 x = (k[0] ^ k[1]) & (long32)saltbits;531 *k++ ^= x;532 *k++ ^= x;533 }534 }535 #endif536 537 #ifdef _UFC_64_538 STATIC void shuffle_sb(k, saltbits)539 long64 *k;540 ufc_long saltbits;541 { ufc_long j;542 long64 x;543 for(j=4096; j--;) {544 x = ((*k >> 32) ^ *k) & (long64)saltbits;545 *k++ ^= (x << 32) | x;546 }547 }548 #endif549 550 /*551 * Setup the unit for a new salt552 * Hopefully we'll not see a new salt in each crypt call.553 */554 555 static unsigned char current_salt[3] = "&&"; /* invalid value */556 static ufc_long current_saltbits = 0;557 static int direction = 0;558 559 STATIC void setup_salt(s)560 char *s;561 { ufc_long i, j, saltbits;562 563 if(!initialized)564 init_des();565 566 if(s[0] == current_salt[0] && s[1] == current_salt[1])567 return;568 current_salt[0] = s[0]; current_salt[1] = s[1];569 570 /*571 * This is the only crypt change to DES:572 * entries are swapped in the expansion table573 * according to the bits set in the salt.574 */575 saltbits = 0;576 for(i = 0; i < 2; i++) {577 long c=ascii_to_bin(s[i]);578 #ifdef notdef579 /*580 * Some applications do rely on illegal581 * salts. It seems that UFC-crypt behaves582 * identically to standard crypt583 * implementations on illegal salts -- glad584 */585 if(c < 0 || c > 63)586 c = 0;587 #endif588 for(j = 0; j < 6; j++) {589 if((c >> j) & 0x1)590 saltbits |= BITMASK(6 * i + j);591 }592 }593 594 /*595 * Permute the sb table values596 * to reflect the changed e597 * selection table598 */599 shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits);600 shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits);601 shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits);602 shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits);603 604 current_saltbits = saltbits;605 }606 607 STATIC void ufc_mk_keytab(key)608 char *key;609 { ufc_long v1, v2, *k1;610 int i;611 #ifdef _UFC_32_612 long32 v, *k2 = &_ufc_keytab[0][0];613 #endif614 #ifdef _UFC_64_615 long64 v, *k2 = &_ufc_keytab[0];616 #endif617 618 v1 = v2 = 0; k1 = &do_pc1[0][0][0];619 for(i = 8; i--;) {620 v1 |= k1[*key & 0x7f]; k1 += 128;621 v2 |= k1[*key++ & 0x7f]; k1 += 128;622 }623 624 for(i = 0; i < 16; i++) {625 k1 = &do_pc2[0][0];626 627 v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));628 v = k1[(v1 >> 21) & 0x7f]; k1 += 128;629 v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;630 v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;631 v |= k1[(v1 ) & 0x7f]; k1 += 128;632 633 #ifdef _UFC_32_634 *k2++ = v;635 v = 0;636 #endif637 #ifdef _UFC_64_638 v <<= 32;639 #endif640 641 v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));642 v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;643 v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;644 v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;645 v |= k1[(v2 ) & 0x7f];646 647 *k2++ = v;648 }649 650 direction = 0;651 }652 653 /*654 * Undo an extra E selection and do final permutations655 */656 657 ufc_long *_ufc_dofinalperm(l1, l2, r1, r2)658 ufc_long l1,l2,r1,r2;659 { ufc_long v1, v2, x;660 static ufc_long ary[2];661 662 x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x;663 x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x;664 665 v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;666 667 v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];668 v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];669 v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];670 v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];671 672 v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];673 v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];674 v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];675 v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];676 677 v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];678 v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];679 v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];680 v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];681 682 v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];683 v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];684 v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];685 v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];686 687 ary[0] = v1; ary[1] = v2;688 return ary;689 }690 691 /*692 * crypt only: convert from 64 bit to 11 bit ASCII693 * prefixing with the salt694 */695 696 STATIC char *output_conversion(v1, v2, salt)697 ufc_long v1, v2;698 char *salt;699 { static char outbuf[14];700 int i, s, shf;701 702 outbuf[0] = salt[0];703 outbuf[1] = salt[1] ? salt[1] : salt[0];704 705 for(i = 0; i < 5; i++) {706 shf = (26 - 6 * i); /* to cope with MSC compiler bug */707 outbuf[i + 2] = bin_to_ascii((v1 >> shf) & 0x3f);708 }709 710 s = (v2 & 0xf) << 2;711 v2 = (v2 >> 2) | ((v1 & 0x3) << 30);712 713 for(i = 5; i < 10; i++) {714 shf = (56 - 6 * i);715 outbuf[i + 2] = bin_to_ascii((v2 >> shf) & 0x3f);716 }717 718 outbuf[12] = bin_to_ascii(s);719 outbuf[13] = 0;720 721 return outbuf;722 }723 724 ufc_long *_ufc_doit();725 726 /*727 * UNIX crypt function728 */729 730 char *crypt(key, salt)731 char *key, *salt;732 { ufc_long *s;733 char ktab[9];734 735 /*736 * Hack DES tables according to salt737 */738 setup_salt(salt);739 740 /*741 * Setup key schedule742 */743 clearmem(ktab, sizeof ktab);744 (void)strncpy(ktab, key, 8);745 ufc_mk_keytab(ktab);746 747 /*748 * Go for the 25 DES encryptions749 */750 s = _ufc_doit((ufc_long)0, (ufc_long)0,751 (ufc_long)0, (ufc_long)0, (ufc_long)25);752 /*753 * Do final permutations754 */755 s = _ufc_dofinalperm(s[0], s[1], s[2], s[3]);756 757 /*758 * And convert back to 6 bit ASCII759 */760 return output_conversion(s[0], s[1], salt);761 }762 763 /*764 * To make fcrypt users happy.765 * They don't need to call init_des.766 */767 768 char *fcrypt(key, salt)769 char *key;770 char *salt;771 { return crypt(key, salt);772 }773 774 /*775 * UNIX encrypt function. Takes a bitvector776 * represented by one byte per bit and777 * encrypt/decrypt according to edflag778 */779 780 void encrypt(block, edflag)781 char *block;782 int edflag;783 { ufc_long l1, l2, r1, r2, *s;784 int i;785 786 /*787 * Undo any salt changes to E expansion788 */789 setup_salt("..");790 791 /*792 * Reverse key table if793 * changing operation (encrypt/decrypt)794 */795 if((edflag == 0) != (direction == 0)) {796 for(i = 0; i < 8; i++) {797 #ifdef _UFC_32_798 long32 x;799 x = _ufc_keytab[15-i][0];800 _ufc_keytab[15-i][0] = _ufc_keytab[i][0];801 _ufc_keytab[i][0] = x;802 803 x = _ufc_keytab[15-i][1];804 _ufc_keytab[15-i][1] = _ufc_keytab[i][1];805 _ufc_keytab[i][1] = x;806 #endif807 #ifdef _UFC_64_808 long64 x;809 x = _ufc_keytab[15-i];810 _ufc_keytab[15-i] = _ufc_keytab[i];811 _ufc_keytab[i] = x;812 #endif813 }814 direction = edflag;815 }816 817 /*818 * Do initial permutation + E expansion819 */820 i = 0;821 for(l1 = 0; i < 24; i++) {822 if(block[initial_perm[esel[i]-1]-1])823 l1 |= BITMASK(i);824 }825 for(l2 = 0; i < 48; i++) {826 if(block[initial_perm[esel[i]-1]-1])827 l2 |= BITMASK(i-24);828 }829 830 i = 0;831 for(r1 = 0; i < 24; i++) {832 if(block[initial_perm[esel[i]-1+32]-1])833 r1 |= BITMASK(i);834 }835 for(r2 = 0; i < 48; i++) {836 if(block[initial_perm[esel[i]-1+32]-1])837 r2 |= BITMASK(i-24);838 }839 840 /*841 * Do DES inner loops + final conversion842 */843 s = _ufc_doit(l1, l2, r1, r2, (ufc_long)1);844 /*845 * Do final permutations846 */847 s = _ufc_dofinalperm(s[0], s[1], s[2], s[3]);848 849 /*850 * And convert to bit array851 */852 l1 = s[0]; r1 = s[1];853 for(i = 0; i < 32; i++) {854 *block++ = (l1 & longmask[i]) != 0;855 }856 for(i = 0; i < 32; i++) {857 *block++ = (r1 & longmask[i]) != 0;858 }859 860 }861 862 /*863 * UNIX setkey function. Take a 64 bit DES864 * key and setup the machinery.865 */866 867 void setkey(key)868 char *key;869 { int i,j;870 unsigned char c;871 unsigned char ktab[8];872 873 setup_salt(".."); /* be sure we're initialized */874 875 for(i = 0; i < 8; i++) {876 for(j = 0, c = 0; j < 8; j++)877 c = c << 1 | *key++;878 ktab[i] = c >> 1;879 }880 881 ufc_mk_keytab(ktab);882 }883 884 /*885 * Ultrix crypt16 function, thanks to pcl@convex.oxford.ac.uk (Paul Leyland)886 */887 888 char *crypt16(key, salt)889 char *key, *salt;890 { ufc_long *s, *t;891 char ktab[9], ttab[9];892 static char q[14], res[25];893 /*894 * Hack DES tables according to salt895 */896 setup_salt(salt);897 898 /*899 * Setup key schedule900 */901 clearmem(ktab, sizeof ktab);902 (void)strncpy(ktab, key, 8);903 ufc_mk_keytab(ktab);904 905 /*906 * Go for first 20 DES encryptions907 */908 s = _ufc_doit((ufc_long)0, (ufc_long)0,909 (ufc_long)0, (ufc_long)0, (ufc_long)20);910 911 /*912 * And convert back to 6 bit ASCII913 */914 strcpy (res, output_conversion(s[0], s[1], salt));915 916 clearmem(ttab, sizeof ttab);917 if (strlen (key) > 8) (void)strncpy(ttab, key+8, 8);918 ufc_mk_keytab(ttab);919 920 /*921 * Go for second 5 DES encryptions922 */923 t = _ufc_doit((ufc_long)0, (ufc_long)0,924 (ufc_long)0, (ufc_long)0, (ufc_long)5);925 /*926 * And convert back to 6 bit ASCII927 */928 strcpy (q, output_conversion(t[0], t[1], salt));929 strcpy (res+13, q+2);930 931 clearmem(ktab, sizeof ktab);932 (void)strncpy(ktab, key, 8);933 ufc_mk_keytab(ktab);934 935 return res;936 }937 938 /*939 * Experimental -- not supported -- may choke your dog940 */941 942 void ufc_setup_password(cookie, s)943 long *cookie;944 char *s;945 { char c;946 int i;947 ufc_long x;948 ufc_long dl1, dl2, dr1, dr2;949 950 setup_salt(s);951 dl1 = dl2 = dr1 = dr2 = 0;952 for(i = 0, s += 2; c = *s++; i++) {953 int x = ascii_to_bin(c);954 dl1 |= revfinal[i][x][0];955 dl2 |= revfinal[i][x][1];956 dr1 |= revfinal[i][x][2];957 dr2 |= revfinal[i][x][3];958 }959 x = (dl1 ^ dl2) & current_saltbits;960 x = (dr1 ^ dr2) & current_saltbits;961 cookie[0] = dl1 ^ x; cookie[1] = dl2 ^ x;962 cookie[2] = dr1 ^ x; cookie[3] = dr2 ^ x;963 }964 965 void ufc_do_pw(cookie, guess)966 long *cookie;967 char *guess;968 { char ktab[9];969 ufc_long *s;970 clearmem(ktab, sizeof ktab);971 (void)strncpy(ktab, guess, 8);972 ufc_mk_keytab(ktab);973 s = _ufc_doit((ufc_long)0, (ufc_long)0,974 (ufc_long)0, (ufc_long)0, (ufc_long)25);975 cookie[0] = s[0]; cookie[1] = s[1];976 cookie[2] = s[2]; cookie[3] = s[3];977 } -
new file src/system/libroot/posix/crypt/crypto_scrypt.cpp
diff --git a/src/system/libroot/posix/crypt/crypto_scrypt.cpp b/src/system/libroot/posix/crypt/crypto_scrypt.cpp new file mode 100644 index 0000000..78d77b5
- + 1 /*- 2 * Copyright 2009 Colin Percival 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * This file was originally written by Colin Percival as part of the Tarsnap 27 * online backup system. 28 */ 29 #include <sys/types.h> 30 #include <sys/mman.h> 31 32 #include <errno.h> 33 #include <stdint.h> 34 #include <stdlib.h> 35 #include <string.h> 36 37 #include "pbkdf2.h" 38 39 #include "crypto_scrypt_smix.h" 40 41 #include "crypto_scrypt.h" 42 43 static void (*smix_func)(uint8_t *, size_t, uint64_t, void *, void *) = NULL; 44 45 /** 46 * _crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen, smix): 47 * Perform the requested scrypt computation, using ${smix} as the smix routine. 48 */ 49 static int 50 _crypto_scrypt(const uint8_t * passwd, size_t passwdlen, 51 const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p, 52 uint8_t * buf, size_t buflen, 53 void (*smix)(uint8_t *, size_t, uint64_t, void *, void *)) 54 { 55 void * B0, * V0, * XY0; 56 uint8_t * B; 57 uint32_t * V; 58 uint32_t * XY; 59 size_t r = _r, p = _p; 60 uint32_t i; 61 62 /* Sanity-check parameters. */ 63 #if SIZE_MAX > UINT32_MAX 64 if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { 65 errno = EFBIG; 66 goto err0; 67 } 68 #endif 69 if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { 70 errno = EFBIG; 71 goto err0; 72 } 73 if (((N & (N - 1)) != 0) || (N < 2)) { 74 errno = EINVAL; 75 goto err0; 76 } 77 if ((r > SIZE_MAX / 128 / p) || 78 #if SIZE_MAX / 256 <= UINT32_MAX 79 (r > (SIZE_MAX - 64) / 256) || 80 #endif 81 (N > SIZE_MAX / 128 / r)) { 82 errno = ENOMEM; 83 goto err0; 84 } 85 86 /* Allocate memory. */ 87 #ifdef HAVE_POSIX_MEMALIGN 88 if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0) 89 goto err0; 90 B = (uint8_t *)(B0); 91 if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0) 92 goto err1; 93 XY = (uint32_t *)(XY0); 94 #if !defined(MAP_ANON) || !defined(HAVE_MMAP) 95 if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0) 96 goto err2; 97 V = (uint32_t *)(V0); 98 #endif 99 #else 100 if ((B0 = malloc(128 * r * p + 63)) == NULL) 101 goto err0; 102 B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63)); 103 if ((XY0 = malloc(256 * r + 64 + 63)) == NULL) 104 goto err1; 105 XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63)); 106 #if !defined(MAP_ANON) || !defined(HAVE_MMAP) 107 if ((V0 = malloc(128 * r * N + 63)) == NULL) 108 goto err2; 109 V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); 110 #endif 111 #endif 112 #if defined(MAP_ANON) && defined(HAVE_MMAP) 113 if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, 114 #ifdef MAP_NOCORE 115 MAP_ANON | MAP_PRIVATE | MAP_NOCORE, 116 #else 117 MAP_ANON | MAP_PRIVATE, 118 #endif 119 -1, 0)) == MAP_FAILED) 120 goto err2; 121 V = (uint32_t *)(V0); 122 #endif 123 124 /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ 125 PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); 126 127 /* 2: for i = 0 to p - 1 do */ 128 for (i = 0; i < p; i++) { 129 /* 3: B_i <-- MF(B_i, N) */ 130 (smix)(&B[i * 128 * r], r, N, V, XY); 131 } 132 133 /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ 134 PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); 135 136 /* Free memory. */ 137 #if defined(MAP_ANON) && defined(HAVE_MMAP) 138 if (munmap(V0, 128 * r * N)) 139 goto err2; 140 #else 141 free(V0); 142 #endif 143 free(XY0); 144 free(B0); 145 146 /* Success! */ 147 return (0); 148 149 err2: 150 free(XY0); 151 err1: 152 free(B0); 153 err0: 154 /* Failure! */ 155 return (-1); 156 } 157 158 #define TESTLEN 64 159 static struct scrypt_test { 160 const char * passwd; 161 const char * salt; 162 uint64_t N; 163 uint32_t r; 164 uint32_t p; 165 uint8_t result[TESTLEN]; 166 } testcase = { 167 "pleaseletmein", 168 "SodiumChloride", 169 16, 170 8, 171 1, 172 { 173 0x25, 0xa9, 0xfa, 0x20, 0x7f, 0x87, 0xca, 0x09, 174 0xa4, 0xef, 0x8b, 0x9f, 0x77, 0x7a, 0xca, 0x16, 175 0xbe, 0xb7, 0x84, 0xae, 0x18, 0x30, 0xbf, 0xbf, 176 0xd3, 0x83, 0x25, 0xaa, 0xbb, 0x93, 0x77, 0xdf, 177 0x1b, 0xa7, 0x84, 0xd7, 0x46, 0xea, 0x27, 0x3b, 178 0xf5, 0x16, 0xa4, 0x6f, 0xbf, 0xac, 0xf5, 0x11, 179 0xc5, 0xbe, 0xba, 0x4c, 0x4a, 0xb3, 0xac, 0xc7, 180 0xfa, 0x6f, 0x46, 0x0b, 0x6c, 0x0f, 0x47, 0x7b, 181 } 182 }; 183 184 static int 185 testsmix(void (*smix)(uint8_t *, size_t, uint64_t, void *, void *)) 186 { 187 uint8_t hbuf[TESTLEN]; 188 189 /* Perform the computation. */ 190 if (_crypto_scrypt( 191 (const uint8_t *)testcase.passwd, strlen(testcase.passwd), 192 (const uint8_t *)testcase.salt, strlen(testcase.salt), 193 testcase.N, testcase.r, testcase.p, hbuf, TESTLEN, smix)) 194 return (-1); 195 196 /* Does it match? */ 197 return (memcmp(testcase.result, hbuf, TESTLEN)); 198 } 199 200 static void 201 selectsmix(void) 202 { 203 /* If generic smix works, use it. */ 204 if (!testsmix(crypto_scrypt_smix)) { 205 smix_func = crypto_scrypt_smix; 206 return; 207 } 208 209 /* If we get here, something really bad happened. */ 210 abort(); 211 } 212 213 /** 214 * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): 215 * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, 216 * p, buflen) and write the result into buf. The parameters r, p, and buflen 217 * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N 218 * must be a power of 2 greater than 1. 219 * 220 * Return 0 on success; or -1 on error. 221 */ 222 int 223 crypto_scrypt(const uint8_t * passwd, size_t passwdlen, 224 const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p, 225 uint8_t * buf, size_t buflen) 226 { 227 228 if (smix_func == NULL) 229 selectsmix(); 230 231 return (_crypto_scrypt(passwd, passwdlen, salt, saltlen, N, _r, _p, 232 buf, buflen, smix_func)); 233 } -
new file src/system/libroot/posix/crypt/crypto_scrypt.h
diff --git a/src/system/libroot/posix/crypt/crypto_scrypt.h b/src/system/libroot/posix/crypt/crypto_scrypt.h new file mode 100644 index 0000000..e7e0082
- + 1 /*- 2 * Copyright 2009 Colin Percival 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * This file was originally written by Colin Percival as part of the Tarsnap 27 * online backup system. 28 */ 29 #ifndef _CRYPTO_SCRYPT_H_ 30 #define _CRYPTO_SCRYPT_H_ 31 32 #include <stdint.h> 33 #include <unistd.h> 34 35 /** 36 * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): 37 * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, 38 * p, buflen) and write the result into buf. The parameters r, p, and buflen 39 * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N 40 * must be a power of 2 greater than 1. 41 * 42 * Return 0 on success; or -1 on error. 43 */ 44 int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, 45 uint32_t, uint32_t, uint8_t *, size_t); 46 47 #endif /* !_CRYPTO_SCRYPT_H_ */ -
new file src/system/libroot/posix/crypt/crypto_scrypt_smix.cpp
diff --git a/src/system/libroot/posix/crypt/crypto_scrypt_smix.cpp b/src/system/libroot/posix/crypt/crypto_scrypt_smix.cpp new file mode 100644 index 0000000..eea418c
- + 1 /*- 2 * Copyright 2009 Colin Percival 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * This file was originally written by Colin Percival as part of the Tarsnap 27 * online backup system. 28 */ 29 #include <stdio.h> 30 #include <stdint.h> 31 #include <string.h> 32 #include <ByteOrder.h> 33 #include "pbkdf2.h" 34 #include "crypto_scrypt_smix.h" 35 36 static void blkcpy(void *, const void *, size_t); 37 static void blkxor(void *, const void *, size_t); 38 static void salsa20_8(uint32_t[16]); 39 static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t); 40 static uint64_t integerify(const void *, size_t); 41 42 static void 43 blkcpy(void * dest, const void * src, size_t len) 44 { 45 size_t * D = (size_t *)dest; 46 const size_t * S = (const size_t *)src; 47 size_t L = len / sizeof(size_t); 48 size_t i; 49 50 for (i = 0; i < L; i++) 51 D[i] = S[i]; 52 } 53 54 static void 55 blkxor(void * dest, const void * src, size_t len) 56 { 57 size_t * D = (size_t *)dest; 58 const size_t * S = (const size_t *)src; 59 size_t L = len / sizeof(size_t); 60 size_t i; 61 62 for (i = 0; i < L; i++) 63 D[i] ^= S[i]; 64 } 65 66 /** 67 * salsa20_8(B): 68 * Apply the salsa20/8 core to the provided block. 69 */ 70 static void 71 salsa20_8(uint32_t B[16]) 72 { 73 uint32_t x[16]; 74 size_t i; 75 76 blkcpy(x, B, 64); 77 for (i = 0; i < 8; i += 2) { 78 #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) 79 /* Operate on columns. */ 80 x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); 81 x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); 82 83 x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); 84 x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); 85 86 x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); 87 x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); 88 89 x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); 90 x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); 91 92 /* Operate on rows. */ 93 x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); 94 x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); 95 96 x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); 97 x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); 98 99 x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); 100 x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); 101 102 x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); 103 x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); 104 #undef R 105 } 106 for (i = 0; i < 16; i++) 107 B[i] += x[i]; 108 } 109 110 /** 111 * blockmix_salsa8(Bin, Bout, X, r): 112 * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r 113 * bytes in length; the output Bout must also be the same size. The 114 * temporary space X must be 64 bytes. 115 */ 116 static void 117 blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) 118 { 119 size_t i; 120 121 /* 1: X <-- B_{2r - 1} */ 122 blkcpy(X, &Bin[(2 * r - 1) * 16], 64); 123 124 /* 2: for i = 0 to 2r - 1 do */ 125 for (i = 0; i < 2 * r; i += 2) { 126 /* 3: X <-- H(X \xor B_i) */ 127 blkxor(X, &Bin[i * 16], 64); 128 salsa20_8(X); 129 130 /* 4: Y_i <-- X */ 131 /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ 132 blkcpy(&Bout[i * 8], X, 64); 133 134 /* 3: X <-- H(X \xor B_i) */ 135 blkxor(X, &Bin[i * 16 + 16], 64); 136 salsa20_8(X); 137 138 /* 4: Y_i <-- X */ 139 /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ 140 blkcpy(&Bout[i * 8 + r * 16], X, 64); 141 } 142 } 143 144 /** 145 * integerify(B, r): 146 * Return the result of parsing B_{2r-1} as a little-endian integer. 147 */ 148 static uint64_t 149 integerify(const void * B, size_t r) 150 { 151 const uint32_t * X = (const uint32_t *)((uintptr_t)(B) + (2 * r - 1) * 64); 152 153 return (((uint64_t)(X[1]) << 32) + X[0]); 154 } 155 156 /** 157 * crypto_scrypt_smix(B, r, N, V, XY): 158 * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; 159 * the temporary storage V must be 128rN bytes in length; the temporary 160 * storage XY must be 256r + 64 bytes in length. The value N must be a 161 * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a 162 * multiple of 64 bytes. 163 */ 164 void 165 crypto_scrypt_smix(uint8_t * B, size_t r, uint64_t N, void * _V, void * XY) 166 { 167 uint32_t * X = (uint32_t *)XY; 168 uint32_t * Y = (uint32_t *)((uint8_t *)(XY) + 128 * r); 169 uint32_t * Z = (uint32_t *)((uint8_t *)(XY) + 256 * r); 170 uint32_t * V = (uint32_t *)_V; 171 uint64_t i; 172 uint64_t j; 173 size_t k; 174 175 /* 1: X <-- B */ 176 for (k = 0; k < 32 * r; k++) { 177 X[k] = B_LENDIAN_TO_HOST_INT32(((uint32_t*)B)[k]); 178 } 179 180 /* 2: for i = 0 to N - 1 do */ 181 for (i = 0; i < N; i += 2) { 182 /* 3: V_i <-- X */ 183 blkcpy(&V[i * (32 * r)], X, 128 * r); 184 185 /* 4: X <-- H(X) */ 186 blockmix_salsa8(X, Y, Z, r); 187 188 /* 3: V_i <-- X */ 189 blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r); 190 191 /* 4: X <-- H(X) */ 192 blockmix_salsa8(Y, X, Z, r); 193 } 194 195 /* 6: for i = 0 to N - 1 do */ 196 for (i = 0; i < N; i += 2) { 197 /* 7: j <-- Integerify(X) mod N */ 198 j = integerify(X, r) & (N - 1); 199 200 /* 8: X <-- H(X \xor V_j) */ 201 blkxor(X, &V[j * (32 * r)], 128 * r); 202 blockmix_salsa8(X, Y, Z, r); 203 204 /* 7: j <-- Integerify(X) mod N */ 205 j = integerify(Y, r) & (N - 1); 206 207 /* 8: X <-- H(X \xor V_j) */ 208 blkxor(Y, &V[j * (32 * r)], 128 * r); 209 blockmix_salsa8(Y, X, Z, r); 210 } 211 212 /* 10: B' <-- X */ 213 for (k = 0; k < 32 * r; k++) { 214 uint32_t* B32 = &(reinterpret_cast<uint32_t*>(B)[k]); 215 *B32 = B_HOST_TO_LENDIAN_INT32(X[k]); 216 } 217 } -
new file src/system/libroot/posix/crypt/crypto_scrypt_smix.h
diff --git a/src/system/libroot/posix/crypt/crypto_scrypt_smix.h b/src/system/libroot/posix/crypt/crypto_scrypt_smix.h new file mode 100644 index 0000000..d2a8e6b
- + 1 /*- 2 * Copyright 2009 Colin Percival 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * This file was originally written by Colin Percival as part of the Tarsnap 27 * online backup system. 28 */ 29 30 #ifndef _CRYPTO_SCRYPT_SMIX_H_ 31 #define _CRYPTO_SCRYPT_SMIX_H_ 32 33 /** 34 * crypto_scrypt_smix(B, r, N, V, XY): 35 * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; 36 * the temporary storage V must be 128rN bytes in length; the temporary 37 * storage XY must be 256r + 64 bytes in length. The value N must be a 38 * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a 39 * multiple of 64 bytes. 40 */ 41 void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *); 42 43 #endif /* !_CRYPTO_SCRYPT_SMIX_H_ */ -
new file src/system/libroot/posix/crypt/pbkdf2.cpp
diff --git a/src/system/libroot/posix/crypt/pbkdf2.cpp b/src/system/libroot/posix/crypt/pbkdf2.cpp new file mode 100644 index 0000000..792b783
- + 1 /* This file is distributed under the following terms: 2 3 * Copyright 2005-2014 Colin Percival. All rights reserved. 4 * Copyright 2014 Sean Kelly. All rights reserved. 5 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <assert.h> 29 #include <stdint.h> 30 #include <string.h> 31 #include <ByteOrder.h> 32 #include "pbkdf2.h" 33 34 /* Function which does the zeroing. */ 35 static void 36 insecure_memzero_func(volatile void * buf, size_t len) 37 { 38 volatile uint8_t * _buf = (volatile uint8_t *)buf; 39 size_t i; 40 41 for (i = 0; i < len; i++) 42 _buf[i] = 0; 43 } 44 45 /* Pointer to memory-zeroing function. */ 46 void (* volatile insecure_memzero_ptr)(volatile void *, size_t) = 47 insecure_memzero_func; 48 49 /** 50 * HMAC_SHA256_Init(ctx, K, Klen): 51 * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from 52 * ${K}. 53 */ 54 void 55 HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) 56 { 57 uint8_t pad[64]; 58 uint8_t khash[32]; 59 const uint8_t * K = (const uint8_t *)_K; 60 size_t i; 61 62 /* If Klen > 64, the key is really SHA256(K). */ 63 if (Klen > 64) { 64 ctx->ictx.Init(); 65 ctx->ictx.Update(K, Klen); 66 memcpy(khash, ctx->ictx.Digest(), 32); 67 K = khash; 68 Klen = 32; 69 } 70 71 /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ 72 ctx->ictx.Init(); 73 memset(pad, 0x36, 64); 74 for (i = 0; i < Klen; i++) 75 pad[i] ^= K[i]; 76 ctx->ictx.Update(pad, 64); 77 78 /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ 79 ctx->octx.Init(); 80 memset(pad, 0x5c, 64); 81 for (i = 0; i < Klen; i++) 82 pad[i] ^= K[i]; 83 ctx->octx.Update(pad, 64); 84 85 /* Clean the stack. */ 86 insecure_memzero(khash, 32); 87 insecure_memzero(pad, 64); 88 } 89 90 /** 91 * HMAC_SHA256_Update(ctx, in, len): 92 * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. 93 */ 94 void 95 HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len) 96 { 97 98 /* Feed data to the inner SHA256 operation. */ 99 ctx->ictx.Update(in, len); 100 } 101 102 /** 103 * HMAC_SHA256_Final(digest, ctx): 104 * Output the HMAC-SHA256 of the data input to the context ${ctx} into the 105 * buffer ${digest}. 106 */ 107 void 108 HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx) 109 { 110 uint8_t ihash[32]; 111 112 /* Finish the inner SHA256 operation. */ 113 memcpy(ihash, ctx->ictx.Digest(), 32); 114 115 /* Feed the inner hash to the outer SHA256 operation. */ 116 ctx->octx.Update(ihash, 32); 117 118 /* Finish the outer SHA256 operation. */ 119 memcpy(digest, ctx->octx.Digest(), 32); 120 121 /* Clean the stack. */ 122 insecure_memzero(ihash, 32); 123 } 124 125 /** 126 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): 127 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and 128 * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). 129 */ 130 void 131 PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, 132 size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) 133 { 134 HMAC_SHA256_CTX PShctx, hctx; 135 size_t i; 136 uint32_t ivec; 137 uint8_t U[32]; 138 uint8_t T[32]; 139 uint64_t j; 140 int k; 141 size_t clen; 142 143 /* Sanity-check. */ 144 assert(dkLen <= 32 * (size_t)(UINT32_MAX)); 145 146 /* Compute HMAC state after processing P and S. */ 147 HMAC_SHA256_Init(&PShctx, passwd, passwdlen); 148 HMAC_SHA256_Update(&PShctx, salt, saltlen); 149 150 /* Iterate through the blocks. */ 151 for (i = 0; i * 32 < dkLen; i++) { 152 /* Generate INT(i + 1). */ 153 ivec = B_HOST_TO_BENDIAN_INT32((uint32_t)(i + 1)); 154 155 /* Compute U_1 = PRF(P, S || INT(i)). */ 156 memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); 157 HMAC_SHA256_Update(&hctx, &ivec, 4); 158 HMAC_SHA256_Final(U, &hctx); 159 160 /* T_i = U_1 ... */ 161 memcpy(T, U, 32); 162 163 for (j = 2; j <= c; j++) { 164 /* Compute U_j. */ 165 HMAC_SHA256_Init(&hctx, passwd, passwdlen); 166 HMAC_SHA256_Update(&hctx, U, 32); 167 HMAC_SHA256_Final(U, &hctx); 168 169 /* ... xor U_j ... */ 170 for (k = 0; k < 32; k++) 171 T[k] ^= U[k]; 172 } 173 174 /* Copy as many bytes as necessary into buf. */ 175 clen = dkLen - i * 32; 176 if (clen > 32) 177 clen = 32; 178 memcpy(&buf[i * 32], T, clen); 179 } 180 181 /* Clean PShctx, since we never called _Final on it. */ 182 insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX)); 183 } -
new file src/system/libroot/posix/crypt/pbkdf2.h
diff --git a/src/system/libroot/posix/crypt/pbkdf2.h b/src/system/libroot/posix/crypt/pbkdf2.h new file mode 100644 index 0000000..1208eb6
- + 1 /* This file is distributed under the following terms: 2 3 * Copyright 2005-2014 Colin Percival. All rights reserved. 4 * Copyright 2014 Sean Kelly. All rights reserved. 5 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #ifndef _SHA256_H_ 29 #define _SHA256_H_ 30 31 #include <stddef.h> 32 #include <stdint.h> 33 #include <SHA256.h> 34 35 /* Pointer to memory-zeroing function. */ 36 extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t); 37 38 /** 39 * insecure_memzero(buf, len): 40 * Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers' 41 * best (standards-compliant) attempts to remove the buffer-zeroing. In 42 * particular, to avoid performing the zeroing, a compiler would need to 43 * use optimistic devirtualization; recognize that non-volatile objects do not 44 * need to be treated as volatile, even if they are accessed via volatile 45 * qualified pointers; and perform link-time optimization; in addition to the 46 * dead-code elimination which often causes buffer-zeroing to be elided. 47 * 48 * Note however that zeroing a buffer does not guarantee that the data held 49 * in the buffer is not stored elsewhere; in particular, there may be copies 50 * held in CPU registers or in anonymous allocations on the stack, even if 51 * every named variable is successfully sanitized. Solving the "wipe data 52 * from the system" problem will require a C language extension which does not 53 * yet exist. 54 * 55 * For more information, see: 56 * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html 57 * http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html 58 */ 59 static inline void 60 insecure_memzero(volatile void * buf, size_t len) 61 { 62 63 (insecure_memzero_ptr)(buf, len); 64 } 65 66 /* Context structure for SHA256 operations. */ 67 typedef struct { 68 uint32_t state[8]; 69 uint64_t count; 70 uint8_t buf[64]; 71 } SHA256_CTX; 72 73 /* Context structure for HMAC-SHA256 operations. */ 74 typedef struct { 75 SHA256 ictx; 76 SHA256 octx; 77 } HMAC_SHA256_CTX; 78 79 /** 80 * HMAC_SHA256_Init(ctx, K, Klen): 81 * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from 82 * ${K}. 83 */ 84 void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); 85 86 /** 87 * HMAC_SHA256_Update(ctx, in, len): 88 * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. 89 */ 90 void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); 91 92 /** 93 * HMAC_SHA256_Final(digest, ctx): 94 * Output the HMAC-SHA256 of the data input to the context ${ctx} into the 95 * buffer ${digest}. 96 */ 97 void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *); 98 99 /** 100 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): 101 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and 102 * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). 103 */ 104 void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, 105 uint64_t, uint8_t *, size_t); 106 107 #endif /* !_SHA256_H_ */ -
new file src/tests/system/libroot/posix/CryptTest.cpp
diff --git a/src/tests/system/libroot/posix/CryptTest.cpp b/src/tests/system/libroot/posix/CryptTest.cpp new file mode 100644 index 0000000..555bc62
- + 1 /* 2 * Copyright 2017, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Andrew Aldridge, i80and@foxquill.com 7 */ 8 9 10 #include <errno.h> 11 #include <string.h> 12 #include <unistd.h> 13 14 #include "CryptTest.h" 15 16 #include <cppunit/TestCaller.h> 17 #include <cppunit/TestSuite.h> 18 19 20 #define PASSWORD "password" 21 #define HASH_SALT "$s$12$101f2cf1a3b35aa671b8e006c6fb037e429d5b4ecb8dab16919097789e2d3a5f$ignorethis" 22 #define HASH_RESULT "$s$12$101f2cf1a3b35aa671b8e006c6fb037e429d5b4ecb8dab16919097789e2d3a5f$4c5c886740871c447639e2dd5eeba004f22c0860ce88c811032ca6de6c95b23e" 23 24 // This salt is only 31 bytes, while we need 32 bytes 25 #define HASH_BAD_SALT "$s$12$101f2cf1a3b35aa671b8e006c6fb037e429d5b4ecb8dab16919097789e2d3a$ignorethis" 26 27 28 CryptTest::CryptTest() 29 { 30 } 31 32 33 CryptTest::~CryptTest() 34 { 35 } 36 37 38 void 39 CryptTest::setUp() 40 { 41 } 42 43 44 void 45 CryptTest::tearDown() 46 { 47 } 48 49 50 void 51 CryptTest::TestLegacy() 52 { 53 char* buf = crypt(PASSWORD, "1d"); 54 CPPUNIT_ASSERT(buf != NULL); 55 CPPUNIT_ASSERT(strcmp(buf, "1dVzQK99LSks6") == 0); 56 } 57 58 59 void 60 CryptTest::TestCustomSalt() 61 { 62 char* buf = crypt(PASSWORD, HASH_SALT); 63 CPPUNIT_ASSERT(buf != NULL); 64 CPPUNIT_ASSERT(strcmp(buf, HASH_RESULT) == 0); 65 } 66 67 68 void 69 CryptTest::TestSaltGeneration() 70 { 71 char tmp[200]; 72 char* salt = crypt_gensalt(12); 73 CPPUNIT_ASSERT(salt != NULL); 74 CPPUNIT_ASSERT(strstr(salt, "12") == salt + 3); 75 76 char* buf = crypt(PASSWORD, salt); 77 CPPUNIT_ASSERT(buf != NULL); 78 strlcpy(tmp, buf, sizeof(tmp)); 79 buf = crypt(PASSWORD, tmp); 80 CPPUNIT_ASSERT(strcmp(buf, tmp) == 0); 81 } 82 83 84 void 85 CryptTest::TestBadSalt() 86 { 87 errno = 0; 88 CPPUNIT_ASSERT(crypt(PASSWORD, HASH_BAD_SALT) == NULL); 89 CPPUNIT_ASSERT(errno == EINVAL); 90 } 91 92 93 void 94 CryptTest::AddTests(BTestSuite& parent) 95 { 96 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("CryptTest"); 97 suite.addTest(new CppUnit::TestCaller<CryptTest>( 98 "CryptTest::TestLegacy", 99 &CryptTest::TestLegacy)); 100 suite.addTest(new CppUnit::TestCaller<CryptTest>( 101 "CryptTest::TestCustomSalt", 102 &CryptTest::TestCustomSalt)); 103 suite.addTest(new CppUnit::TestCaller<CryptTest>( 104 "CryptTest::TestSaltGeneration", 105 &CryptTest::TestSaltGeneration)); 106 suite.addTest(new CppUnit::TestCaller<CryptTest>( 107 "CryptTest::TestBadSalt", 108 &CryptTest::TestBadSalt)); 109 parent.addTest("CryptTest", &suite); 110 } -
new file src/tests/system/libroot/posix/CryptTest.h
diff --git a/src/tests/system/libroot/posix/CryptTest.h b/src/tests/system/libroot/posix/CryptTest.h new file mode 100644 index 0000000..ee208ad
- + 1 /* 2 * Copyright 2017, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Andrew Aldridge, i80and@foxquill.com 7 */ 8 9 10 #ifndef CRYPT_TEST_H 11 #define CRYPT_TEST_H 12 13 14 #include <TestCase.h> 15 #include <TestSuite.h> 16 17 18 class CryptTest : public CppUnit::TestCase { 19 public: 20 CryptTest(); 21 virtual ~CryptTest(); 22 23 virtual void setUp(); 24 virtual void tearDown(); 25 26 void TestLegacy(); 27 void TestCustomSalt(); 28 void TestSaltGeneration(); 29 void TestBadSalt(); 30 31 static void AddTests(BTestSuite& suite); 32 }; 33 34 35 #endif // CRYPT_TEST_H -
src/tests/system/libroot/posix/Jamfile
diff --git a/src/tests/system/libroot/posix/Jamfile b/src/tests/system/libroot/posix/Jamfile index b62c971..fbd2c4f 100644
a b SimpleTest test_wcfuncs : test_wcfuncs.c ; 73 73 SimpleTest test_wctype : test_wctype.c ; 74 74 SimpleTest wcs_test : wcs_test.cpp ; 75 75 76 UnitTestLib librootposixtest.so : 77 LibRootPosix.cpp 78 79 CryptTest.cpp 80 81 : be [ TargetLibstdc++ ] [ TargetLibsupc++ ] 82 ; 76 83 77 84 SubInclude HAIKU_TOP src tests system libroot posix math ; 78 85 SubInclude HAIKU_TOP src tests system libroot posix string ; -
new file src/tests/system/libroot/posix/LibRootPosix.cpp
diff --git a/src/tests/system/libroot/posix/LibRootPosix.cpp b/src/tests/system/libroot/posix/LibRootPosix.cpp new file mode 100644 index 0000000..c7c32b5
- + 1 /* 2 * Copyright 2017, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Andrew Aldridge, i80and@foxquill.com 7 */ 8 9 10 #include <TestSuite.h> 11 #include <TestSuiteAddon.h> 12 13 #include "CryptTest.h" 14 15 16 BTestSuite* 17 getTestSuite() 18 { 19 BTestSuite* suite = new BTestSuite("LibRootPosix"); 20 CryptTest::AddTests(*suite); 21 return suite; 22 }