Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Functions | Variables

crypt-blowfish.c File Reference

#include "postgres.h"
#include "px-crypt.h"
Include dependency graph for crypt-blowfish.c:

Go to the source code of this file.

Data Structures

struct  BF_ctx

Defines

#define BF_ASM   0
#define BF_SCALE   0
#define BF_N   16
#define BF_safe_atoi64(dst, src)
#define BF_INDEX(S, i)   (*((BF_word *)(((unsigned char *)(S)) + (i))))
#define BF_ROUND(L, R, N)
#define BF_ENCRYPT
#define BF_body()

Typedefs

typedef unsigned int BF_word
typedef signed int BF_word_signed
typedef BF_word BF_key [BF_N+2]

Functions

static int BF_decode (BF_word *dst, const char *src, int size)
static void BF_encode (char *dst, const BF_word *src, int size)
static void BF_swap (BF_word *x, int count)
static void BF_set_key (const char *key, BF_key expanded, BF_key initial, int sign_extension_bug)
char * _crypt_blowfish_rn (const char *key, const char *setting, char *output, int size)

Variables

static BF_word BF_magic_w [6]
static BF_ctx BF_init_state
static unsigned char BF_itoa64 [64+1] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
static unsigned char BF_atoi64 [0x60]

Define Documentation

#define BF_ASM   0

Definition at line 46 of file crypt-blowfish.c.

#define BF_body (  ) 
Value:
L = R = 0; \
    ptr = data.ctx.P; \
    do { \
        ptr += 2; \
        BF_ENCRYPT; \
        *(ptr - 2) = L; \
        *(ptr - 1) = R; \
    } while (ptr < &data.ctx.P[BF_N + 2]); \
\
    ptr = data.ctx.S[0]; \
    do { \
        ptr += 2; \
        BF_ENCRYPT; \
        *(ptr - 2) = L; \
        *(ptr - 1) = R; \
    } while (ptr < &data.ctx.S[3][0xFF]);

Definition at line 527 of file crypt-blowfish.c.

Referenced by _crypt_blowfish_rn().

#define BF_ENCRYPT
Value:
L ^= data.ctx.P[0]; \
    BF_ROUND(L, R, 0); \
    BF_ROUND(R, L, 1); \
    BF_ROUND(L, R, 2); \
    BF_ROUND(R, L, 3); \
    BF_ROUND(L, R, 4); \
    BF_ROUND(R, L, 5); \
    BF_ROUND(L, R, 6); \
    BF_ROUND(R, L, 7); \
    BF_ROUND(L, R, 8); \
    BF_ROUND(R, L, 9); \
    BF_ROUND(L, R, 10); \
    BF_ROUND(R, L, 11); \
    BF_ROUND(L, R, 12); \
    BF_ROUND(R, L, 13); \
    BF_ROUND(L, R, 14); \
    BF_ROUND(R, L, 15); \
    tmp4 = R; \
    R = L; \
    L = tmp4 ^ data.ctx.P[BF_N + 1];

Definition at line 497 of file crypt-blowfish.c.

Referenced by bf_cbc_encrypt(), bf_cfb64_encrypt(), bf_check_supported_key_len(), and bf_ecb_encrypt().

#define BF_INDEX (   S,
  i 
)    (*((BF_word *)(((unsigned char *)(S)) + (i))))

Definition at line 473 of file crypt-blowfish.c.

#define BF_N   16

Definition at line 54 of file crypt-blowfish.c.

Referenced by _crypt_blowfish_rn(), and BF_set_key().

#define BF_ROUND (   L,
  R,
  N 
)
Value:
tmp1 = (L) & 0xFF; \
    tmp1 <<= 2; \
    tmp2 = (L) >> 6; \
    tmp2 &= 0x3FC; \
    tmp3 = (L) >> 14; \
    tmp3 &= 0x3FC; \
    tmp4 = (L) >> 22; \
    tmp4 &= 0x3FC; \
    tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
    tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
    tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
    tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
    tmp3 ^= tmp2; \
    (R) ^= data.ctx.P[(N) + 1]; \
    tmp3 += tmp1; \
    (R) ^= tmp3;

Definition at line 475 of file crypt-blowfish.c.

#define BF_safe_atoi64 (   dst,
  src 
)
Value:
do { \
    tmp = (unsigned char)(src); \
    if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
    tmp = BF_atoi64[tmp]; \
    if (tmp > 63) return -1; \
    (dst) = tmp; \
} while (0)

Definition at line 360 of file crypt-blowfish.c.

Referenced by BF_decode().

#define BF_SCALE   0

Definition at line 47 of file crypt-blowfish.c.


Typedef Documentation

typedef BF_word BF_key[BF_N+2]

Definition at line 56 of file crypt-blowfish.c.

typedef unsigned int BF_word

Definition at line 50 of file crypt-blowfish.c.

typedef signed int BF_word_signed

Definition at line 51 of file crypt-blowfish.c.


Function Documentation

char* _crypt_blowfish_rn ( const char *  key,
const char *  setting,
char *  output,
int  size 
)

Definition at line 578 of file crypt-blowfish.c.

References BF_atoi64, BF_body, BF_decode(), BF_encode(), BF_itoa64, BF_magic_w, BF_N, BF_set_key(), BF_swap(), i, and BF_ctx::S.

Referenced by run_crypt_bf().

{
    struct
    {
        BF_ctx      ctx;
        BF_key      expanded_key;
        union
        {
            BF_word     salt[4];
            BF_word     output[6];
        }           binary;
    }           data;
    BF_word     L,
                R;
    BF_word     tmp1,
                tmp2,
                tmp3,
                tmp4;
    BF_word    *ptr;
    BF_word     count;
    int         i;

    if (size < 7 + 22 + 31 + 1)
        return NULL;

    if (setting[0] != '$' ||
        setting[1] != '2' ||
        (setting[2] != 'a' && setting[2] != 'x') ||
        setting[3] != '$' ||
        setting[4] < '0' || setting[4] > '3' ||
        setting[5] < '0' || setting[5] > '9' ||
        (setting[4] == '3' && setting[5] > '1') ||
        setting[6] != '$')
    {
        return NULL;
    }

    count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
    if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
    {
        memset(data.binary.salt, 0, sizeof(data.binary.salt));
        return NULL;
    }
    BF_swap(data.binary.salt, 4);

    BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x');

    memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));

    L = R = 0;
    for (i = 0; i < BF_N + 2; i += 2)
    {
        L ^= data.binary.salt[i & 2];
        R ^= data.binary.salt[(i & 2) + 1];
        BF_ENCRYPT;
        data.ctx.P[i] = L;
        data.ctx.P[i + 1] = R;
    }

    ptr = data.ctx.S[0];
    do
    {
        ptr += 4;
        L ^= data.binary.salt[(BF_N + 2) & 3];
        R ^= data.binary.salt[(BF_N + 3) & 3];
        BF_ENCRYPT;
        *(ptr - 4) = L;
        *(ptr - 3) = R;

        L ^= data.binary.salt[(BF_N + 4) & 3];
        R ^= data.binary.salt[(BF_N + 5) & 3];
        BF_ENCRYPT;
        *(ptr - 2) = L;
        *(ptr - 1) = R;
    } while (ptr < &data.ctx.S[3][0xFF]);

    do
    {
        data.ctx.P[0] ^= data.expanded_key[0];
        data.ctx.P[1] ^= data.expanded_key[1];
        data.ctx.P[2] ^= data.expanded_key[2];
        data.ctx.P[3] ^= data.expanded_key[3];
        data.ctx.P[4] ^= data.expanded_key[4];
        data.ctx.P[5] ^= data.expanded_key[5];
        data.ctx.P[6] ^= data.expanded_key[6];
        data.ctx.P[7] ^= data.expanded_key[7];
        data.ctx.P[8] ^= data.expanded_key[8];
        data.ctx.P[9] ^= data.expanded_key[9];
        data.ctx.P[10] ^= data.expanded_key[10];
        data.ctx.P[11] ^= data.expanded_key[11];
        data.ctx.P[12] ^= data.expanded_key[12];
        data.ctx.P[13] ^= data.expanded_key[13];
        data.ctx.P[14] ^= data.expanded_key[14];
        data.ctx.P[15] ^= data.expanded_key[15];
        data.ctx.P[16] ^= data.expanded_key[16];
        data.ctx.P[17] ^= data.expanded_key[17];

        BF_body();

        tmp1 = data.binary.salt[0];
        tmp2 = data.binary.salt[1];
        tmp3 = data.binary.salt[2];
        tmp4 = data.binary.salt[3];
        data.ctx.P[0] ^= tmp1;
        data.ctx.P[1] ^= tmp2;
        data.ctx.P[2] ^= tmp3;
        data.ctx.P[3] ^= tmp4;
        data.ctx.P[4] ^= tmp1;
        data.ctx.P[5] ^= tmp2;
        data.ctx.P[6] ^= tmp3;
        data.ctx.P[7] ^= tmp4;
        data.ctx.P[8] ^= tmp1;
        data.ctx.P[9] ^= tmp2;
        data.ctx.P[10] ^= tmp3;
        data.ctx.P[11] ^= tmp4;
        data.ctx.P[12] ^= tmp1;
        data.ctx.P[13] ^= tmp2;
        data.ctx.P[14] ^= tmp3;
        data.ctx.P[15] ^= tmp4;
        data.ctx.P[16] ^= tmp1;
        data.ctx.P[17] ^= tmp2;

        BF_body();
    } while (--count);

    for (i = 0; i < 6; i += 2)
    {
        L = BF_magic_w[i];
        R = BF_magic_w[i + 1];

        count = 64;
        do
        {
            BF_ENCRYPT;
        } while (--count);

        data.binary.output[i] = L;
        data.binary.output[i + 1] = R;
    }

    memcpy(output, setting, 7 + 22 - 1);
    output[7 + 22 - 1] = BF_itoa64[(int)
                         BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30];

/* This has to be bug-compatible with the original implementation, so
 * only encode 23 of the 24 bytes. :-) */
    BF_swap(data.binary.output, 6);
    BF_encode(&output[7 + 22], data.binary.output, 23);
    output[7 + 22 + 31] = '\0';

/* Overwrite the most obvious sensitive data we have on the stack. Note
 * that this does not guarantee there's no sensitive data left on the
 * stack and/or in registers; I'm not aware of portable code that does. */
    memset(&data, 0, sizeof(data));

    return output;
}

static int BF_decode ( BF_word dst,
const char *  src,
int  size 
) [static]

Definition at line 370 of file crypt-blowfish.c.

References BF_safe_atoi64, and end.

Referenced by _crypt_blowfish_rn().

{
    unsigned char *dptr = (unsigned char *) dst;
    unsigned char *end = dptr + size;
    const unsigned char *sptr = (const unsigned char *) src;
    unsigned int tmp,
                c1,
                c2,
                c3,
                c4;

    do
    {
        BF_safe_atoi64(c1, *sptr++);
        BF_safe_atoi64(c2, *sptr++);
        *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
        if (dptr >= end)
            break;

        BF_safe_atoi64(c3, *sptr++);
        *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
        if (dptr >= end)
            break;

        BF_safe_atoi64(c4, *sptr++);
        *dptr++ = ((c3 & 0x03) << 6) | c4;
    } while (dptr < end);

    return 0;
}

static void BF_encode ( char *  dst,
const BF_word src,
int  size 
) [static]

Definition at line 402 of file crypt-blowfish.c.

References BF_itoa64, and end.

Referenced by _crypt_blowfish_rn().

{
    const unsigned char *sptr = (const unsigned char *) src;
    const unsigned char *end = sptr + size;
    unsigned char *dptr = (unsigned char *) dst;
    unsigned int c1,
                c2;

    do
    {
        c1 = *sptr++;
        *dptr++ = BF_itoa64[c1 >> 2];
        c1 = (c1 & 0x03) << 4;
        if (sptr >= end)
        {
            *dptr++ = BF_itoa64[c1];
            break;
        }

        c2 = *sptr++;
        c1 |= c2 >> 4;
        *dptr++ = BF_itoa64[c1];
        c1 = (c2 & 0x0f) << 2;
        if (sptr >= end)
        {
            *dptr++ = BF_itoa64[c1];
            break;
        }

        c2 = *sptr++;
        c1 |= c2 >> 6;
        *dptr++ = BF_itoa64[c1];
        *dptr++ = BF_itoa64[c2 & 0x3f];
    } while (sptr < end);
}

static void BF_set_key ( const char *  key,
BF_key  expanded,
BF_key  initial,
int  sign_extension_bug 
) [static]

Definition at line 547 of file crypt-blowfish.c.

References BF_N, i, and BF_ctx::P.

Referenced by _crypt_blowfish_rn(), bf_check_supported_key_len(), and bf_init().

{
    const char *ptr = key;
    int         i,
                j;
    BF_word     tmp;

    for (i = 0; i < BF_N + 2; i++)
    {
        tmp = 0;
        for (j = 0; j < 4; j++)
        {
            tmp <<= 8;
            if (sign_extension_bug)
                tmp |= (BF_word_signed) (signed char) *ptr;
            else
                tmp |= (unsigned char) *ptr;

            if (!*ptr)
                ptr = key;
            else
                ptr++;
        }

        expanded[i] = tmp;
        initial[i] = BF_init_state.P[i] ^ tmp;
    }
}

static void BF_swap ( BF_word x,
int  count 
) [static]

Definition at line 439 of file crypt-blowfish.c.

Referenced by _crypt_blowfish_rn().

{
    /* Swap on little-endian hardware, else do nothing */
#ifndef WORDS_BIGENDIAN
    BF_word     tmp;

    do
    {
        tmp = *x;
        tmp = (tmp << 16) | (tmp >> 16);
        *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
    } while (--count);
#endif
}


Variable Documentation

unsigned char BF_atoi64[0x60] [static]
Initial value:
 {
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
    54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
    64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
    64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
    43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
}

Definition at line 351 of file crypt-blowfish.c.

Referenced by _crypt_blowfish_rn().

Definition at line 76 of file crypt-blowfish.c.

unsigned char BF_itoa64[64+1] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" [static]

Definition at line 348 of file crypt-blowfish.c.

Referenced by _crypt_blowfish_rn(), and BF_encode().

BF_word BF_magic_w[6] [static]
Initial value:
 {
    0x4F727068, 0x65616E42, 0x65686F6C,
    0x64657253, 0x63727944, 0x6F756274
}

Definition at line 68 of file crypt-blowfish.c.

Referenced by _crypt_blowfish_rn().