Ticket #12365: scrypt_v5.patch

File scrypt_v5.patch, 105.9 KB (added by i80and, 7 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);  
    277277extern int      ttyname_r(int fd, char *buffer, size_t bufferSize);
    278278
    279279/* misc */
     280extern char     *crypt_gensalt(int hardness);
    280281extern char     *crypt(const char *key, const char *salt);
    281282extern void     encrypt(char block[64], int edflag);
    282283extern 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()  
    14201420    _AddCopyrightsFromAttribute();
    14211421    _AddPackageCreditEntries();
    14221422
     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
    14231432    return new CropView(creditsScroller, 0, 1, 1, 1);
    14241433}
    14251434
  • 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)  
    172172        memset(repeatedPassword, 0, sizeof(repeatedPassword));
    173173
    174174        // 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);
    176182        memset(password, 0, sizeof(password));
    177183    }
    178184
    main(int argc, const char* const* argv)  
    182188        || message.AddInt32("last changed", time(NULL)) != B_OK
    183189        || message.AddString("password", "x") != B_OK
    184190        || message.AddString("shadow password", encryptedPassword) != B_OK) {
    185         fprintf(stderr, "Error: Out of memory!\n");
     191        fprintf(stderr, "Error: Failed to construct message!\n");
    186192        exit(1);
    187193    }
    188194
  • 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()  
    145145}
    146146
    147147
    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     else
    158         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 
    183148void
    184149PasswordWindow::MessageReceived(BMessage* message)
    185150{
    PasswordWindow::MessageReceived(BMessage* message)  
    196161                    alert->Go();
    197162                    break;
    198163                }
    199                 const char* salt = _SanitizeSalt(fPasswordControl->Text());
     164                char* salt = crypt_gensalt(-1);
    200165                fSettings.SetPassword(crypt(fPasswordControl->Text(), salt));
    201                 delete[] salt;
    202166            } else
    203167                fSettings.SetPassword("");
    204168
  • 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:  
    2929
    3030private:
    3131            void                _Setup();
    32             char*               _SanitizeSalt(const char* password);
    3332
    3433            BRadioButton*       fUseCustom;
    3534            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 ] {  
    8585            $(librootNoDebugObjects)
    8686            [ TargetStaticLibsupc++ ]
    8787            [ TargetLibgcc ]
     88            shared
    8889            ;
    8990
    9091        # Use the standard libroot.so soname, so when the debug version is
    for architectureObject in [ MultiArchSubDirSetup ] {  
    99100            $(librootDebugObjects)
    100101            [ TargetStaticLibsupc++ ]
    101102            [ TargetLibgcc ]
     103            shared
    102104            ;
    103105       
    104106        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  
    11SubDir HAIKU_TOP src system libroot posix crypt ;
    22
     3UsePrivateHeaders shared ;
     4UsePrivateSystemHeaders ;
     5
    36local architectureObject ;
    47for architectureObject in [ MultiArchSubDirSetup ] {
    58    on $(architectureObject) {
    for architectureObject in [ MultiArchSubDirSetup ] {  
    1114                : -Wall -Wmissing-prototypes -Wsign-compare ] ;
    1215
    1316        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
    1623            ;
    1724    }
    1825}
  • 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) 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.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
     30static const char* kHexAlphabet = "0123456789abcdef";
     31static 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
     40static int
     41toHex(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
     69static size_t
     70fromHex(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().
     100char*
     101crypt_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
     138char *
     139crypt(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.
     193char*
     194fcrypt(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
     34extern long32 _ufc_keytab[16][2];
     35extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
     36
     37#define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
     38
     39static ufc_long ary[4];
     40
     41ufc_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
     81extern long64 _ufc_keytab[16];
     82extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
     83
     84#define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
     85
     86static ufc_long ary[4];
     87
     88ufc_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
     5extern "C" {
     6#endif
     7
     8char *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
     49static 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 */
     55static 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 */
     66static 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 */
     74static 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 */
     85static 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};
     91static int e_inverse[64];
     92
     93/*
     94 * Permutation done on the
     95 * result of sbox lookups
     96 */
     97static 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 */
     105static 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 */
     159static 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 */
     170static 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_
     181long32 _ufc_keytab[16][2];
     182#endif
     183#ifdef _UFC_64_
     184long64 _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_
     204long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192];
     205static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
     206#endif
     207
     208#ifdef _UFC_64_
     209long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096];
     210static 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 */
     222static 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 */
     234static 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 */
     247static 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 */
     256static 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 */
     264static ufc_long revfinal[11][64][4];
     265
     266
     267static unsigned char bytemask[8]  = {
     268  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
     269};
     270
     271static 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
     284pr_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
     300static 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
     319STATIC void clearmem(start, cnt)
     320  char *start;
     321  int cnt;
     322  { while(cnt--)
     323      *start++ = '\0';
     324  }
     325
     326static 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
     337void 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_
     525STATIC 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_
     539STATIC 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
     556static unsigned char current_salt[3] = "&&"; /* invalid value */
     557static ufc_long current_saltbits = 0;
     558static int direction = 0;
     559
     560STATIC 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
     608STATIC 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
     658ufc_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
     697STATIC 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
     725ufc_long *_ufc_doit();
     726
     727/*
     728 * UNIX crypt function
     729 */
     730   
     731char *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
     770void 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
     857void 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   
     878char *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
     932void 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
     955void 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) 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 
    28 #ifdef DEBUG
    29 #include <stdio.h>
    30 #endif
    31 
    32 #ifndef STATIC
    33 #define STATIC static
    34 #endif
    35 
    36 #ifndef DOS
    37 #include "patchlevel.h"
    38 #include "ufc-crypt.h"
    39 #else
    40 /*
    41  * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)
    42  * for DOS patches
    43  */
    44 #include "pl.h"
    45 #include "ufc.h"
    46 #endif
    47 
    48 static char patchlevel_str[] = PATCHLEVEL;
    49 
    50 /*
    51  * Permutation done once on the 56 bit
    52  *  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,  4
    59 };
    60 
    61 /*
    62  * How much to rotate each 28 bit half of the pc1 permutated
    63  *  56 bit key before using pc2 to give the i' key
    64  */
    65 static int rots[16] = {
    66   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
    67 };
    68 
    69 /*
    70  * Permutation giving the key
    71  * of the i' DES round
    72  */
    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, 32
    78 };
    79 
    80 /*
    81  * The E expansion table which selects
    82  * 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,  1
    89 };
    90 static int e_inverse[64];
    91 
    92 /*
    93  * Permutation done on the
    94  * result of sbox lookups
    95  */
    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, 25
    99 };
    100 
    101 /*
    102  * The sboxes
    103  */
    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 initial
    156  * permutation matrix
    157  */
    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, 7
    163 };
    164 
    165 /*
    166  * This is the final
    167  * permutation matrix
    168  */
    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, 25
    174 };
    175 
    176 /*
    177  * The 16 DES keys in BITMASK format
    178  */
    179 #ifdef _UFC_32_
    180 long32 _ufc_keytab[16][2];
    181 #endif
    182 #ifdef _UFC_64_
    183 long64 _ufc_keytab[16];
    184 #endif
    185 
    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 bit
    197  * 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 #endif
    206 
    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 #endif
    211 
    212 /*
    213  * eperm32tab: do 32 bit permutation and E selection
    214  *
    215  * The first index is the byte number in the 32 bit value to be permuted
    216  *  -  second  -   is the value of this byte
    217  *  -  third   -   selects the two 32 bit values
    218  *
    219  * The table is used and generated internally in init_des to speed it up
    220  */
    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 key
    227  *  -  second    -      -    the two 28 bits halfs of the result
    228  *  -  third     -   selects the 7 bits actually used of each byte
    229  *
    230  * The result is kept with 28 bit per 32 bit with the 4 most significant
    231  * 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 values
    239  *  -  second    -    -  -  septet values
    240  *
    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 significant
    244  * bits zero.
    245  */
    246 static ufc_long do_pc2[8][128];
    247 
    248 /*
    249  * efp: undo an extra e selection and do final
    250  *      permutation giving the DES result.
    251  *
    252  *      Invoked 6 bit a time on two 48 bit values
    253  *      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 output
    261  *           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, 0x01
    268 };
    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, 0x00000001
    279 };
    280 
    281 #ifdef DEBUG
    282 
    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 #endif
    311 
    312 /*
    313  * Silly rewrite of 'bzero'. I do so
    314  * because some machines don't have
    315  * 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 directly
    333  * 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 used
    344      * to affect pc1 permutation
    345      * when generating keys
    346      */
    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 used
    359      * to affect pc2 permutation when
    360      * generating keys
    361      */
    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 combined
    374      * 32 bit permutation and e expansion
    375      *
    376      * We use it because we have to permute 16384 32 bit
    377      * longs into 48 bit in order to initialize sb.
    378      *
    379      * Looping 48 rounds per permutation becomes
    380      * 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 intermediate
    402      * result, the sb table precomputes the two 4 bit
    403      * values of the sbox lookups done with the two 6
    404      * bit halves, shifts them to their proper place,
    405      * sends them through perm32 and finally E expands
    406      * them so that they are ready for the next
    407      * 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 #endif
    434 #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 #endif
    449     }
    450       }
    451     } 
    452 
    453     /*
    454      * Create an inverse matrix for esel telling
    455      * where to plug out bits if undoing it
    456      */
    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 to
    464      * undo the E expansion and effect final permutation
    465      */
    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 several
    481        * times. By the initialization of e_inverse, we only look
    482        * 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 final
    501      * the effects of efp
    502      */
    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 the
    520  * 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 #endif
    536 
    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 #endif
    549 
    550 /*
    551  * Setup the unit for a new salt
    552  * 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 table
    573      * 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 notdef
    579       /*
    580        * Some applications do rely on illegal
    581        * salts. It seems that UFC-crypt behaves
    582        * identically to standard crypt
    583        * implementations on illegal salts -- glad
    584        */
    585       if(c < 0 || c > 63)
    586     c = 0;
    587 #endif
    588       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 values
    596      * to reflect the changed e
    597      * selection table
    598      */
    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 #endif
    614 #ifdef _UFC_64_
    615     long64 v, *k2 = &_ufc_keytab[0];
    616 #endif
    617 
    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 #endif
    637 #ifdef _UFC_64_
    638       v <<= 32;
    639 #endif
    640 
    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 permutations
    655  */
    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 ASCII
    693  * prefixing with the salt
    694  */
    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 function
    728  */
    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 salt
    737      */
    738     setup_salt(salt);
    739 
    740     /*
    741      * Setup key schedule
    742      */
    743     clearmem(ktab, sizeof ktab);
    744     (void)strncpy(ktab, key, 8);
    745     ufc_mk_keytab(ktab);
    746 
    747     /*
    748      * Go for the 25 DES encryptions
    749      */
    750     s = _ufc_doit((ufc_long)0, (ufc_long)0,
    751           (ufc_long)0, (ufc_long)0, (ufc_long)25);
    752     /*
    753      * Do final permutations
    754      */
    755     s = _ufc_dofinalperm(s[0], s[1], s[2], s[3]);
    756 
    757     /*
    758      * And convert back to 6 bit ASCII
    759      */
    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 bitvector
    776  * represented by one byte per bit and
    777  * encrypt/decrypt according to edflag
    778  */
    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 expansion
    788      */
    789     setup_salt("..");
    790 
    791     /*
    792      * Reverse key table if
    793      * 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 #endif
    807 #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 #endif
    813       }
    814       direction = edflag;
    815     }
    816 
    817     /*
    818      * Do initial permutation + E expansion
    819      */
    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 conversion
    842      */
    843     s = _ufc_doit(l1, l2, r1, r2, (ufc_long)1);
    844     /*
    845      * Do final permutations
    846      */
    847     s = _ufc_dofinalperm(s[0], s[1], s[2], s[3]);
    848 
    849     /*
    850      * And convert to bit array
    851      */
    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 DES
    864  * 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 salt
    895      */
    896     setup_salt(salt);
    897    
    898     /*
    899      * Setup key schedule
    900      */
    901     clearmem(ktab, sizeof ktab);
    902     (void)strncpy(ktab, key, 8);
    903     ufc_mk_keytab(ktab);
    904    
    905     /*
    906      * Go for first 20 DES encryptions
    907      */
    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 ASCII
    913      */
    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 encryptions
    922      */
    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 ASCII
    927      */
    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 dog
    940  */
    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
     43static 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 */
     49static 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
     149err2:
     150    free(XY0);
     151err1:
     152    free(B0);
     153err0:
     154    /* Failure! */
     155    return (-1);
     156}
     157
     158#define TESTLEN 64
     159static 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
     184static int
     185testsmix(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
     200static void
     201selectsmix(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 */
     222int
     223crypto_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 */
     44int 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
     36static void blkcpy(void *, const void *, size_t);
     37static void blkxor(void *, const void *, size_t);
     38static void salsa20_8(uint32_t[16]);
     39static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t);
     40static uint64_t integerify(const void *, size_t);
     41
     42static void
     43blkcpy(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
     54static void
     55blkxor(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 */
     70static void
     71salsa20_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 */
     116static void
     117blockmix_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 */
     148static uint64_t
     149integerify(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 */
     164void
     165crypto_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 */
     41void 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. */
     35static void
     36insecure_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. */
     46void (* 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 */
     54void
     55HMAC_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 */
     94void
     95HMAC_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 */
     107void
     108HMAC_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 */
     130void
     131PBKDF2_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. */
     36extern 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 */
     59static inline void
     60insecure_memzero(volatile void * buf, size_t len)
     61{
     62
     63    (insecure_memzero_ptr)(buf, len);
     64}
     65
     66/* Context structure for SHA256 operations. */
     67typedef 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. */
     74typedef 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 */
     84void 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 */
     90void 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 */
     97void 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 */
     104void 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
     28CryptTest::CryptTest()
     29{
     30}
     31
     32
     33CryptTest::~CryptTest()
     34{
     35}
     36
     37
     38void
     39CryptTest::setUp()
     40{
     41}
     42
     43
     44void
     45CryptTest::tearDown()
     46{
     47}
     48
     49
     50void
     51CryptTest::TestLegacy()
     52{
     53    char* buf = crypt(PASSWORD, "1d");
     54    CPPUNIT_ASSERT(buf != NULL);
     55    CPPUNIT_ASSERT(strcmp(buf, "1dVzQK99LSks6") == 0);
     56}
     57
     58
     59void
     60CryptTest::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
     68void
     69CryptTest::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
     84void
     85CryptTest::TestBadSalt()
     86{
     87    errno = 0;
     88    CPPUNIT_ASSERT(crypt(PASSWORD, HASH_BAD_SALT) == NULL);
     89    CPPUNIT_ASSERT(errno == EINVAL);
     90}
     91
     92
     93void
     94CryptTest::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
     18class CryptTest : public CppUnit::TestCase {
     19public:
     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 ;  
    7373SimpleTest test_wctype : test_wctype.c ;
    7474SimpleTest wcs_test : wcs_test.cpp ;
    7575
     76UnitTestLib librootposixtest.so :
     77    LibRootPosix.cpp
     78
     79    CryptTest.cpp
     80
     81    : be [ TargetLibstdc++ ] [ TargetLibsupc++ ]
     82;
    7683
    7784SubInclude HAIKU_TOP src tests system libroot posix math ;
    7885SubInclude 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
     16BTestSuite*
     17getTestSuite()
     18{
     19    BTestSuite* suite = new BTestSuite("LibRootPosix");
     20    CryptTest::AddTests(*suite);
     21    return suite;
     22}