Ejemplo n.º 1
0
/* Generates an key derived from a password and salt using a memory hard
 * algorithm.
 * Implements RFC 7914: scrypt PBKDF.
 *
 * output     The derived key.
 * passwd     The password to derive key from.
 * passLen    The length of the password.
 * salt       The key specific data.
 * saltLen    The length of the salt data.
 * cost       The CPU/memory cost parameter. Range: 1..(128*r/8-1)
 *            (Iterations = 2^cost)
 * blockSize  The number of 128 byte octets in a working block.
 * parallel   The number of parallel mix operations to perform.
 *            (Note: this implementation does not use threads.)
 * dkLen      The length of the derived key in bytes.
 * returns BAD_FUNC_ARG when: parallel not 1, blockSize is too large for cost.
 */
int wc_scrypt(byte* output, const byte* passwd, int passLen,
              const byte* salt, int saltLen, int cost, int blockSize,
              int parallel, int dkLen)
{
    int    ret = 0;
    int    i;
    byte*  v = NULL;
    byte*  y = NULL;
    byte*  blocks = NULL;
    word32 blocksSz;
    word32 bSz;

    if (blockSize > 8)
        return BAD_FUNC_ARG;

    if (cost < 1 || cost >= 128 * blockSize / 8)
        return BAD_FUNC_ARG;

    bSz = 128 * blockSize;
    blocksSz = bSz * parallel;
    blocks = XMALLOC(blocksSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (blocks == NULL)
        goto end;
    /* Temporary for scryptROMix. */
    v = XMALLOC((1 << cost) * bSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (v == NULL)
        goto end;
    /* Temporary for scryptBlockMix. */
    y = XMALLOC(blockSize * 128, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (y == NULL)
        goto end;

    /* Step 1. */
    ret = wc_PBKDF2(blocks, passwd, passLen, salt, saltLen, 1, blocksSz,
                    SHA256);
    if (ret != 0)
        goto end;

    /* Step 2. */
    for (i = 0; i < parallel; i++)
        scryptROMix(blocks + i * bSz, v, y, blockSize, 1 << cost);

    /* Step 3. */
    ret = wc_PBKDF2(output, passwd, passLen, blocks, blocksSz, 1, dkLen,
                    SHA256);
end:
    if (blocks != NULL)
        XFREE(blocks, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (v != NULL)
        XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (y != NULL)
        XFREE(y, NULL, DYNAMIC_TYPE_TMP_BUFFER);

    return ret;
}
Ejemplo n.º 2
0
/*
 * makes a cyptographically secure key by stretching a user entered pwdKey
 */
int wolfsslGenKey(RNG* rng, byte* pwdKey, int size, byte* salt, int pad)
{
    int ret;        /* return variable */

    /* randomly generates salt */

    ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE-1);

    if (ret != 0)
        return ret;

    /* set first value of salt to let us know
     * if message has padding or not
     */
    if (pad == 0)
        salt[0] = 0;

    /* stretches pwdKey */
    ret = (int) wc_PBKDF2(pwdKey, pwdKey, (int) strlen((const char*)pwdKey), salt, SALT_SIZE,
                                                            4096, size, SHA256);
    if (ret != 0)
        return ret;

    return 0;
}
/*
 * Makes a cryptographically secure key by stretching a user entered key
 */
int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
{
    int ret;

    ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE);
    if (ret != 0)
        return -1020;

    if (pad == 0)
        salt[0] = 0;

    /* stretches key */
    ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
    	size, WC_SHA256);
    if (ret != 0)
        return -1030;

    return 0;
}
/*
 * Makes a cryptographically secure key by stretMDMching a user entered key
 */
int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
{
    int ret;

    ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE-1);
    if (ret != 0)
        return -1020;

    if (pad == 0)        /* sets first value of salt to check if the */
        salt[0] = 0;            /* message is padded */

    /* stretches key */
    ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
        size, SHA256);
    if (ret != 0)
        return -1030;

    return 0;
}
/*
 * Decrypts a file using AES
 */
int AesDecrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
{
    RNG     rng;
    byte    iv[AES_BLOCK_SIZE];
    byte*   input;
    byte*   output;
    byte    salt[SALT_SIZE] = {0};

    int     i = 0;
    int     ret = 0;
    int     length;
    int     aSize;

    fseek(inFile, 0, SEEK_END);
    length = ftell(inFile);
    fseek(inFile, 0, SEEK_SET);
    aSize = length;

    input = malloc(aSize);
    output = malloc(aSize);

    wc_InitRng(&rng);

    /* reads from inFile and writes whatever is there to the input array */
    ret = fread(input, 1, length, inFile);
    if (ret == 0) {
        printf("Input file does not exist.\n");
        return -1010;
    }
    for (i = 0; i < SALT_SIZE; i++) {
        /* finds salt from input message */
        salt[i] = input[i];
    }
    for (i = SALT_SIZE; i < AES_BLOCK_SIZE + SALT_SIZE; i++) {
        /* finds iv from input message */
        iv[i - SALT_SIZE] = input[i];
    }

    /* replicates old key if keys match */
    ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
    	size, WC_SHA256);
    if (ret != 0)
        return -1050;

    /* sets key */
    ret = wc_AesSetKey(aes, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION);
    if (ret != 0)
        return -1002;

    /* change length to remove salt/iv block from being decrypted */
    length -= (AES_BLOCK_SIZE + SALT_SIZE);
    for (i = 0; i < length; i++) {
        /* shifts message: ignores salt/iv on message*/
        input[i] = input[i + (AES_BLOCK_SIZE + SALT_SIZE)];
    }
    /* decrypts the message to output based on input length + padding*/
    ret = wc_AesCbcDecrypt(aes, output, input, length);
    if (ret != 0)
        return -1006;

    if (salt[0] != 0) {
        /* reduces length based on number of padded elements */
        length -= output[length-1];
    }
    /* writes output to the outFile based on shortened length */
    fwrite(output, 1, length, outFile);

    /* closes the opened files and frees the memory*/
    memset(input, 0, aSize);
    memset(output, 0, aSize);
    memset(key, 0, size);
    free(input);
    free(output);
    free(key);
    fclose(inFile);
    fclose(outFile);
    wc_FreeRng(&rng);

    return 0;
}