13b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root/*
23b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * Copyright (C) 2010 The Android Open Source Project
33b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root *
43b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
53b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * you may not use this file except in compliance with the License.
63b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * You may obtain a copy of the License at
73b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root *
83b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
93b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root *
103b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * Unless required by applicable law or agreed to in writing, software
113b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
123b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * See the License for the specific language governing permissions and
143b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * limitations under the License.
153b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root */
163b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
173b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <openssl/evp.h>
183b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
193b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <sys/types.h>
203b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <errno.h>
213b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <fcntl.h>
223b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <stdio.h>
233b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <string.h>
243b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#include <unistd.h>
253b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
263b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root/**
273b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * Simple program to generate a key based on PBKDF2 with preset inputs.
283b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root *
293b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * Will print out the salt and key in hex.
303b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root */
313b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
323b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define SALT_LEN 8
333b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define ROUNDS 1024
343b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define KEY_BITS 128
353b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
363b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Rootint main(int argc, char* argv[])
373b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root{
383b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    if (argc != 2) {
393b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        fprintf(stderr, "Usage: %s <password>\n", argv[0]);
403b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        exit(1);
413b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
423b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
433b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    int fd = open("/dev/urandom", O_RDONLY);
443b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    if (fd < 0) {
453b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        fprintf(stderr, "Could not open /dev/urandom: %s\n", strerror(errno));
463b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        close(fd);
473b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        exit(1);
483b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
493b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
503b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    unsigned char salt[SALT_LEN];
513b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
523b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    if (read(fd, &salt, SALT_LEN) != SALT_LEN) {
533b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        fprintf(stderr, "Could not read salt from /dev/urandom: %s\n", strerror(errno));
543b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        close(fd);
553b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        exit(1);
563b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
573b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    close(fd);
583b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
593b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    unsigned char rawKey[KEY_BITS];
603b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
613b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    if (PKCS5_PBKDF2_HMAC_SHA1(argv[1], strlen(argv[1]), salt, SALT_LEN,
623b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root            ROUNDS, KEY_BITS, rawKey) != 1) {
633b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        fprintf(stderr, "Could not generate PBKDF2 output: %s\n", strerror(errno));
643b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        exit(1);
653b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
663b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
673b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    printf("salt=");
683b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    for (int i = 0; i < SALT_LEN; i++) {
693b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        printf("%02x", salt[i]);
703b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
713b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    printf("\n");
723b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root
733b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    printf("key=");
743b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    for (int i = 0; i < (KEY_BITS / 8); i++) {
753b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root        printf("%02x", rawKey[i]);
763b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    }
773b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root    printf("\n");
783b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root}
79