/*====================================================================* * * Copyright (c) 2013 Qualcomm Atheros, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted (subject to the limitations * in the disclaimer below) provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of Qualcomm Atheros nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE * COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *--------------------------------------------------------------------*/ /*====================================================================* * * rkey.c - random key generator; * * generate random SHA256, device access, network membership and * network identifier keys using a seed file; * * read the seed file, increment the seed for each key generated * then save the seed when done; exit the loop in an orderly way * on keyboard interrupt; * * * Contributor(s); * Charles Maier <cmaier@qca.qualcomm.com> * *--------------------------------------------------------------------*/ #define _GETOPT_H /*====================================================================* * system header files; *--------------------------------------------------------------------*/ #include <unistd.h> #include <stdlib.h> #include <limits.h> #include <signal.h> #include <errno.h> /*====================================================================* * custom header files; *--------------------------------------------------------------------*/ #include "../tools/getoptv.h" #include "../tools/putoptv.h" #include "../tools/memory.h" #include "../tools/number.h" #include "../tools/error.h" #include "../tools/files.h" #include "../tools/flags.h" #include "../key/HPAVKey.h" #include "../key/SHA256.h" /*====================================================================* * custom source files; *--------------------------------------------------------------------*/ #ifndef MAKEFILE #include "../tools/getoptv.c" #include "../tools/putoptv.c" #include "../tools/version.c" #include "../tools/uintspec.c" #include "../tools/todigit.c" #include "../tools/strincr.c" #include "../tools/hexout.c" #include "../tools/error.c" #endif #ifndef MAKEFILE #include "../key/HPAVKeyDAK.c" #include "../key/HPAVKeyNMK.c" #include "../key/HPAVKeyNID.c" #include "../key/HPAVKeySHA.c" #include "../key/HPAVKeyOut.c" #include "../key/SHA256Reset.c" #include "../key/SHA256Write.c" #include "../key/SHA256Block.c" #include "../key/SHA256Fetch.c" #endif /*====================================================================* * program constants; *--------------------------------------------------------------------*/ #define DEFAULT_LEVEL 0 #define DEFAULT_COUNT 1 /*====================================================================* * program variables; *--------------------------------------------------------------------*/ static unsigned count = DEFAULT_COUNT; /*====================================================================* * * void stop (signo_t signal); * * terminate the program; we want to ensure an organized program * exit such that the current pass phrase is saved; * * *--------------------------------------------------------------------*/ #if defined (__linux__) static void stop (signo_t signal) { count = 0; return; } #endif /*====================================================================* * * int main (int argc, const char * argv []); * * * *--------------------------------------------------------------------*/ int main (int argc, const char * argv []) { static const char * optv [] = { "DL:MNn:oqv", "seedfile", "generate HomePlug AV compliant keys", "D\tDAK - Device Access Keys", "L n\tSecurity Level is n [" LITERAL (DEFAULT_LEVEL) "]", "M\tNMK - Network Membership Keys", "N\tNID - Network Identifier", "n n\tgenerate n keys [" LITERAL (DEFAULT_COUNT) "]", "o\tuse old seedfile value", "q\tquiet mode", "v\tverbose mode", (const char *)(0) }; #if defined (__linux__) struct sigaction sa; #endif char phrase [HPAVKEY_PHRASE_MAX + 1]; uint8_t digest [SHA256_DIGEST_LENGTH]; unsigned level = DEFAULT_LEVEL; signed type = 0; signed next = 1; signed fd; flag_t flags = (flag_t)(0); signed c; while ((c = getoptv (argc, argv, optv)) != -1) { switch ((char)(c)) { case 'D': type = HPAVKEY_DAK; break; case 'M': type = HPAVKEY_NMK; break; case 'N': type = HPAVKEY_NID; break; case 'n': count = (unsigned)(uintspec (optarg, 0, UINT_MAX)); break; case 'L': level = (unsigned)(uintspec (optarg, 0, 1)); break; case 'o': next = 0; break; case 'q': _setbits (flags, HPAVKEY_SILENCE); break; case 'v': _setbits (flags, HPAVKEY_VERBOSE); break; default: break; } } argc -= optind; argv += optind; if (argc != 1) { error (1, ECANCELED, "No secret file given"); } memset (phrase, 0, sizeof (phrase)); if ((fd = open (* argv, O_BINARY|O_CREAT|O_RDWR, FILE_FILEMODE)) == -1) { error (1, errno, "Can't open %s", * argv); } if (read (fd, phrase, sizeof (phrase) - 1) == -1) { error (1, errno, "Can't read seedfile"); } for (c = 0; c < (signed)(sizeof (phrase) - 1); c++) { if (phrase [c] < HPAVKEY_CHAR_MIN) { phrase [c] = HPAVKEY_CHAR_MIN; continue; } if (phrase [c] > HPAVKEY_CHAR_MAX) { phrase [c] = HPAVKEY_CHAR_MAX; continue; } } #if defined (__linux__) memset (&sa, 0, sizeof (struct sigaction)); sa.sa_handler = stop; sigaction (SIGTERM, &sa, (struct sigaction *)(0)); sigaction (SIGQUIT, &sa, (struct sigaction *)(0)); sigaction (SIGTSTP, &sa, (struct sigaction *)(0)); sigaction (SIGINT, &sa, (struct sigaction *)(0)); sigaction (SIGHUP, &sa, (struct sigaction *)(0)); #endif while (count-- > 0) { memset (digest, 0, sizeof (digest)); if (next && strincr ((uint8_t *)(phrase), (size_t) (sizeof (phrase) - 1), HPAVKEY_CHAR_MIN, HPAVKEY_CHAR_MAX)) { error (1, errno, "Can't increment seedfile"); } if (type == HPAVKEY_DAK) { HPAVKeyDAK (digest, phrase); HPAVKeyOut (digest, HPAVKEY_DAK_LEN, phrase, flags); continue; } if (type == HPAVKEY_NMK) { HPAVKeyNMK (digest, phrase); HPAVKeyOut (digest, HPAVKEY_NMK_LEN, phrase, flags); continue; } if (type == HPAVKEY_NID) { HPAVKeyNMK (digest, phrase); HPAVKeyNID (digest, digest, level); HPAVKeyOut (digest, HPAVKEY_NID_LEN, phrase, flags); continue; } HPAVKeySHA (digest, phrase); HPAVKeyOut (digest, HPAVKEY_SHA_LEN, phrase, flags); } if (lseek (fd, 0, SEEK_SET) == -1) { error (1, errno, "Can't rewind seedfile"); } if (write (fd, phrase, sizeof (phrase) - 1) == -1) { error (1, errno, "Can't update seedfile"); } close (fd); return (0); }