Updated to 1.2

Rewritten main loop. Added more modes, options and help. Removed OpenSSL
dependency. Closed #8, closed #14, closed #18.
This commit is contained in:
wiire 2015-12-06 23:22:07 +01:00
parent 08a78c3c27
commit 32091e45ee
20 changed files with 2434 additions and 824 deletions

9
Android.mk Normal file
View File

@ -0,0 +1,9 @@
LOCAL_PATH:=$(call my-dir)/src
include $(CLEAR_VARS)
LOCAL_CFLAGS:=-std=c99 -O3
LOCAL_MODULE:=pixiewps
LOCAL_SRC_FILES:=pixiewps.c random_r.c crypto/sha256.c crypto/md.c crypto/md_wrap.c
include $(BUILD_EXECUTABLE)

View File

@ -11,7 +11,6 @@ define Package/pixiewps
CATEGORY:=Network
SUBMENU:=wireless
TITLE:=An offline WPS bruteforce utility
DEPENDS:=+libopenssl
URL:=https://github.com/wiire/pixiewps
endef

159
README.md
View File

@ -1,51 +1,70 @@
# OVERVIEW [![License](https://img.shields.io/badge/License-GPL%20v3%2B-blue.svg)] (https://github.com/wiire/pixiewps/blob/master/LICENSE.md)
# Overview [![License](https://img.shields.io/badge/License-GPL%20v3-blue.svg)] (https://github.com/wiire/pixiewps/blob/master/LICENSE.md)
Pixiewps is a tool written in C used to bruteforce offline the WPS pin exploiting the low or non-existing entropy of some APs (pixie dust attack). It is meant for educational purposes only. All credits for the research go to Dominique Bongard.
**Pixiewps** is a tool written in C used to **bruteforce offline** the WPS pin exploiting the low or non-existing entropy of some APs (pixie dust attack). It is meant for educational purposes only.
# DEPENDENCIES
- - -
Pixiewps requires libssl. To install it:
# Requirements
```
sudo apt-get install libssl-dev
Prior versions of 1.2 require [libssl-dev](https://www.openssl.org/).
- - -
# Setup
**Download**
`git clone https://github.com/wiire/pixiewps`
or
`wget https://github.com/wiire/pixiewps/archive/master.zip && unzip master.zip`
**Build**
```bash
cd pixiewps*/
cd src/
make
```
# INSTALLATION
**Install**
Pixiewps can be built and installed by running:
`sudo make install`
- - -
# Usage
```
~/pixiewps$ cd src
~/pixiewps/src$ make
~/pixiewps/src$ sudo make install
Usage: pixiewps <arguments>
Required Arguments:
-e, --pke : Enrollee public key
-r, --pkr : Registrar public key
-s, --e-hash1 : Enrollee hash 1
-z, --e-hash2 : Enrollee hash 2
-a, --authkey : Authentication session key
-n, --e-nonce : Enrollee nonce
Optional Arguments:
-m, --r-nonce : Registrar nonce
-b, --e-bssid : Enrollee BSSID
-S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]
-v, --verbosity : Verbosity level 1-3, 1 is quietest [3]
-h : Display this usage screen
--help : Verbose help and more usage examples
-V, --version : Display version
--mode N[,... N] : Mode selection, comma separated [Auto]
--start [mm/]yyyy : Starting date (only mode 3) [Current time]
--end [mm/]yyyy : Ending date (only mode 3) [-3 days]
```
# USAGE
```
Usage: pixiewps <arguments>
Required Arguments:
-e, --pke : Enrollee public key
-r, --pkr : Registrar public key
-s, --e-hash1 : Enrollee Hash1
-z, --e-hash2 : Enrollee Hash2
-a, --authkey : Authentication session key
Optional Arguments:
-n, --e-nonce : Enrollee nonce
-m, --r-nonce : Registrar nonce
-b, --e-bssid : Enrollee BSSID
-S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]
-f, --force : Bruteforce the whole keyspace [No]
-v, --verbosity : Verbosity level 1-3, 1 is quietest [3]
-h, --help : Display this usage screen
```
# USAGE EXAMPLE
# Usage example
A common usage example is:
@ -53,68 +72,4 @@ A common usage example is:
pixiewps --pke <pke> --pkr <pkr> --e-hash1 <e-hash1> --e-hash2 <e-hash2> --authkey <authkey> --e-nonce <e-nonce>
```
which requires a modified version of Reaver or Bully which prints *AuthKey*. The recommended version is [reaver-wps-fork-t6x](https://github.com/t6x/reaver-wps-fork-t6x).
If the following message is shown:
> [!] The AP /might be/ vulnerable. Try again with --force or with another (newer) set of data.
then the AP might be vulnerable and Pixiewps should be run again with the same set of data along with the option `--force` or alternatively with a newer set of data.
# DESCRIPTION OF ARGUMENTS
```
-e, --pke
Enrollee's DH public key, found in M1.
-r, --pkr
Registrar's DH public key, found in M2 or can be avoided by specifying
--dh-small in both Reaver and Pixiewps.
-s, --e-hash1
Enrollee Hash-1, found in M3.
-z, --e-hash2
Enrollee Hash-2, found in M3.
-a, --authkey
Registration Protocol authentication session key. Although for this parameter a
modified version of Reaver or Bully is needed, it can be avoided by specifying
small Diffie-Hellman keys in both Reaver and Pixiewps and supplying --e-nonce,
--r-nonce and --e-bssid.
-n, --e-nonce
Enrollee's nonce, found in M1.
-m, --r-nonce
Registrar's nonce, found in M2.
-b, --e-bssid
Enrollee's BSSID.
-S, --dh-small
Small Diffie-Hellman keys. The same option MUST be specified in Reaver
(1.3 or later versions) too. This option should be avoided when possible.
-f, --force
Force Pixiewps to bruteforce the whole keyspace (only for one type of PRNG).
It could take up to several minutes to complete.
-v, --verbosity
Verbosity level (1-3). Level 3 displays the most information.
-h, --help
Display usage screen.
```
which requires a modified version of Reaver or Bully which prints *AuthKey*. The recommended version is [reaver-wps-fork-t6x](https://github.com/t6x/reaver-wps-fork-t6x).

View File

@ -1,306 +0,0 @@
/* Copyright (C) 1991,1992,1993,1995-2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _FEATURES_H
#define _FEATURES_H 1
/* These are defined by the user (or the compiler)
to specify the desired environment:
__STRICT_ANSI__ ISO Standard C.
_ISOC99_SOURCE Extensions to ISO C89 from ISO C99.
_POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2;
if >=199309L, add IEEE Std 1003.1b-1993;
if >=199506L, add IEEE Std 1003.1c-1995;
if >=200112L, all of IEEE 1003.1-2004
_XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if
Single Unix conformance is wanted, to 600 for the
upcoming sixth revision.
_XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.
_LARGEFILE_SOURCE Some more functions for correct standard I/O.
_LARGEFILE64_SOURCE Additional functionality from LFS for large files.
_FILE_OFFSET_BITS=N Select default filesystem interface.
_BSD_SOURCE ISO C, POSIX, and 4.3BSD things.
_SVID_SOURCE ISO C, POSIX, and SVID things.
_ATFILE_SOURCE Additional *at interfaces.
_GNU_SOURCE All of the above, plus GNU extensions.
_REENTRANT Select additionally reentrant object.
_THREAD_SAFE Same as _REENTRANT, often used by other systems.
_FORTIFY_SOURCE If set to numeric value > 0 additional security
measures are defined, according to level.
The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__.
If none of these are defined, the default is to have _SVID_SOURCE,
_BSD_SOURCE, and _POSIX_SOURCE set to one and _POSIX_C_SOURCE set to
200112L. If more than one of these are defined, they accumulate.
For example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE
together give you ISO C, 1003.1, and 1003.2, but nothing else.
These are defined by this file and are used by the
header files to decide what to declare or define:
__USE_ISOC99 Define ISO C99 things.
__USE_ISOC95 Define ISO C90 AMD1 (C95) things.
__USE_POSIX Define IEEE Std 1003.1 things.
__USE_POSIX2 Define IEEE Std 1003.2 things.
__USE_POSIX199309 Define IEEE Std 1003.1, and .1b things.
__USE_POSIX199506 Define IEEE Std 1003.1, .1b, .1c and .1i things.
__USE_XOPEN Define XPG things.
__USE_XOPEN_EXTENDED Define X/Open Unix things.
__USE_UNIX98 Define Single Unix V2 things.
__USE_XOPEN2K Define XPG6 things.
__USE_LARGEFILE Define correct standard I/O things.
__USE_LARGEFILE64 Define LFS things with separate names.
__USE_FILE_OFFSET64 Define 64bit interface as default.
__USE_BSD Define 4.3BSD things.
__USE_SVID Define SVID things.
__USE_MISC Define things common to BSD and System V Unix.
__USE_ATFILE Define *at interfaces and AT_* constants for them.
__USE_GNU Define GNU extensions.
__USE_REENTRANT Define reentrant/thread-safe *_r functions.
__USE_FORTIFY_LEVEL Additional security measures used, according to level.
__FAVOR_BSD Favor 4.3BSD things in cases of conflict.
The macros `__GNU_LIBRARY__', `__GLIBC__', and `__GLIBC_MINOR__' are
defined by this file unconditionally. `__GNU_LIBRARY__' is provided
only for compatibility. All new code should use the other symbols
to test for features.
All macros listed above as possibly being defined by this file are
explicitly undefined if they are not explicitly defined.
Feature-test macros that are not defined by the user or compiler
but are implied by the other feature-test macros defined (or by the
lack of any definitions) are defined by the file. */
/* Undefine everything, so we get a clean slate. */
#undef __USE_ISOC99
#undef __USE_ISOC95
#undef __USE_POSIX
#undef __USE_POSIX2
#undef __USE_POSIX199309
#undef __USE_POSIX199506
#undef __USE_XOPEN
#undef __USE_XOPEN_EXTENDED
#undef __USE_UNIX98
#undef __USE_XOPEN2K
#undef __USE_LARGEFILE
#undef __USE_LARGEFILE64
#undef __USE_FILE_OFFSET64
#undef __USE_BSD
#undef __USE_SVID
#undef __USE_MISC
#undef __USE_ATFILE
#undef __USE_GNU
#undef __USE_REENTRANT
#undef __USE_FORTIFY_LEVEL
#undef __FAVOR_BSD
#undef __KERNEL_STRICT_NAMES
/* Suppress kernel-name space pollution unless user expressedly asks
for it. */
#ifndef _LOOSE_KERNEL_NAMES
# define __KERNEL_STRICT_NAMES
#endif
/* Always use ISO C things. */
#define __USE_ANSI 1
/* Convenience macros to test the versions of glibc and gcc.
Use them like this:
#if __GNUC_PREREQ (2,8)
... code requiring gcc 2.8 or later ...
#endif
Note - they won't work for gcc1 or glibc1, since the _MINOR macros
were not defined then. */
#if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
# define __GNUC_PREREQ(maj, min) 0
#endif
/* If _BSD_SOURCE was defined by the user, favor BSD over POSIX. */
#if defined _BSD_SOURCE && \
!(defined _POSIX_SOURCE || defined _POSIX_C_SOURCE || \
defined _XOPEN_SOURCE || defined _XOPEN_SOURCE_EXTENDED || \
defined _GNU_SOURCE || defined _SVID_SOURCE)
# define __FAVOR_BSD 1
#endif
/* If _GNU_SOURCE was defined by the user, turn on all the other features. */
#ifdef _GNU_SOURCE
# undef _ISOC99_SOURCE
# define _ISOC99_SOURCE 1
# undef _POSIX_SOURCE
# define _POSIX_SOURCE 1
# undef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 200112L
# undef _XOPEN_SOURCE
# define _XOPEN_SOURCE 600
# undef _XOPEN_SOURCE_EXTENDED
# define _XOPEN_SOURCE_EXTENDED 1
# undef _LARGEFILE64_SOURCE
# define _LARGEFILE64_SOURCE 1
# undef _BSD_SOURCE
# define _BSD_SOURCE 1
# undef _SVID_SOURCE
# define _SVID_SOURCE 1
# undef _ATFILE_SOURCE
# define _ATFILE_SOURCE 1
#endif
/* If nothing (other than _GNU_SOURCE) is defined,
define _BSD_SOURCE and _SVID_SOURCE. */
#if (!defined __STRICT_ANSI__ && !defined _ISOC99_SOURCE && \
!defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE && \
!defined _XOPEN_SOURCE && !defined _XOPEN_SOURCE_EXTENDED && \
!defined _BSD_SOURCE && !defined _SVID_SOURCE)
# define _BSD_SOURCE 1
# define _SVID_SOURCE 1
#endif
/* This is to enable the ISO C99 extension. Also recognize the old macro
which was used prior to the standard acceptance. This macro will
eventually go away and the features enabled by default once the ISO C99
standard is widely adopted. */
#if (defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
# define __USE_ISOC99 1
#endif
/* This is to enable the ISO C90 Amendment 1:1995 extension. */
#if (defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L))
# define __USE_ISOC95 1
#endif
/* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2
(and IEEE Std 1003.1b-1993 unless _XOPEN_SOURCE is defined). */
#if ((!defined __STRICT_ANSI__ || (_XOPEN_SOURCE - 0) >= 500) && \
!defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE)
# define _POSIX_SOURCE 1
# if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 500
# define _POSIX_C_SOURCE 2
# elif defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 600
# define _POSIX_C_SOURCE 199506L
# else
# define _POSIX_C_SOURCE 200112L
# endif
#endif
#if defined _POSIX_SOURCE || _POSIX_C_SOURCE >= 1 || defined _XOPEN_SOURCE
# define __USE_POSIX 1
#endif
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 2 || defined _XOPEN_SOURCE
# define __USE_POSIX2 1
#endif
#if (_POSIX_C_SOURCE - 0) >= 199309L
# define __USE_POSIX199309 1
#endif
#if (_POSIX_C_SOURCE - 0) >= 199506L
# define __USE_POSIX199506 1
#endif
#if (_POSIX_C_SOURCE - 0) >= 200112L
# define __USE_XOPEN2K 1
#endif
#ifdef _XOPEN_SOURCE
# define __USE_XOPEN 1
# if (_XOPEN_SOURCE - 0) >= 500
# define __USE_XOPEN_EXTENDED 1
# define __USE_UNIX98 1
# undef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE 1
# if (_XOPEN_SOURCE - 0) >= 600
# define __USE_XOPEN2K 1
# undef __USE_ISOC99
# define __USE_ISOC99 1
# endif
# else
# ifdef _XOPEN_SOURCE_EXTENDED
# define __USE_XOPEN_EXTENDED 1
# endif
# endif
#endif
#ifdef _LARGEFILE_SOURCE
# define __USE_LARGEFILE 1
#endif
#ifdef _LARGEFILE64_SOURCE
# define __USE_LARGEFILE64 1
#endif
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
# define __USE_FILE_OFFSET64 1
#endif
#if defined _BSD_SOURCE || defined _SVID_SOURCE
# define __USE_MISC 1
#endif
#ifdef _BSD_SOURCE
# define __USE_BSD 1
#endif
#ifdef _SVID_SOURCE
# define __USE_SVID 1
#endif
#ifdef _ATFILE_SOURCE
# define __USE_ATFILE 1
#endif
#ifdef _GNU_SOURCE
# define __USE_GNU 1
#endif
#if defined _REENTRANT || defined _THREAD_SAFE
# define __USE_REENTRANT 1
#endif
#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \
&& __GNUC_PREREQ (4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
# if _FORTIFY_SOURCE > 1
# define __USE_FORTIFY_LEVEL 2
# else
# define __USE_FORTIFY_LEVEL 1
# endif
#else
# define __USE_FORTIFY_LEVEL 0
#endif
/* We do support the IEC 559 math functionality, real and complex. */
#define __STDC_IEC_559__ 1
#define __STDC_IEC_559_COMPLEX__ 1
/* wchar_t uses ISO 10646-1 (2nd ed., published 2000-09-15) / Unicode 3.1. */
#define __STDC_ISO_10646__ 200009L
/* This macro indicates that the installed library is the GNU C Library.
For historic reasons the value now is 6 and this will stay from now
on. The use of this variable is deprecated. Use __GLIBC__ and
__GLIBC_MINOR__ now (see below) when you want to test for a specific
GNU C library version and use the values in <gnu/lib-names.h> to get
the sonames of the shared libraries. */
#undef __GNU_LIBRARY__
#define __GNU_LIBRARY__ 6
/* Major and minor version number of the GNU C library package. Use
these macros to test for features in specific releases. */
#define __GLIBC__ 2
#define __GLIBC_MINOR__ 7
#define __GLIBC_PREREQ(maj, min) \
((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
/* Decide whether a compiler supports the long long datatypes. */
#if defined __GNUC__ \
|| (defined __PGI && defined __i386__ ) \
|| (defined __INTEL_COMPILER && (defined __i386__ || defined __ia64__)) \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
# define __GLIBC_HAVE_LONG_LONG 1
#endif
/* This is here only because every header file already includes this one. */
#ifndef __ASSEMBLER__
# ifndef _SYS_CDEFS_H
# include <sys/cdefs.h>
# endif
/* If we don't have __REDIRECT, prototypes will be missing if
__USE_FILE_OFFSET64 but not __USE_LARGEFILE[64]. */
# if defined __USE_FILE_OFFSET64 && !defined __REDIRECT
# define __USE_LARGEFILE 1
# define __USE_LARGEFILE64 1
# endif
#endif /* !ASSEMBLER */
/* Decide whether we can define 'extern inline' functions in headers. */
#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
&& !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__ \
&& defined __extern_inline
# define __USE_EXTERN_INLINES 1
#endif
/* This is here only because every header file already includes this one.
Get the definitions of all the appropriate `__stub_FUNCTION' symbols.
<gnu/stubs.h> contains `#define __stub_FUNCTION' when FUNCTION is a stub
that will always return failure (and set errno to ENOSYS). */
#ifndef __MACH__
#include <gnu/stubs.h>
#endif
#endif /* features.h */

View File

@ -1,14 +1,17 @@
CCFLAGS = -std=c99 -O3 -Wno-deprecated-declarations
LDFLAGS = -lcrypto
CCFLAGS = -std=c99 -O3 -Wall
TARGET = pixiewps
SOURCE = $(TARGET).c random_r.c
CRYPTO = crypto/sha256.c crypto/md.c crypto/md_wrap.c
SOURCE = $(TARGET).c random_r.c $(CRYPTO)
PREFIX = $(DESTDIR)/usr
BINDIR = $(PREFIX)/bin
OLDDIR = $(PREFIX)/local/bin
all:
$(CC) $(CCFLAGS) -o $(TARGET) $(SOURCE) $(LDFLAGS)
$(CC) $(CCFLAGS) -o $(TARGET) $(SOURCE)
debug:
$(CC) $(CCFLAGS) -DDEBUG -o $(TARGET) $(SOURCE)
install:
rm -f $(OLDDIR)/$(TARGET)

39
src/config.h Normal file
View File

@ -0,0 +1,39 @@
/*
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
* All credits for the research go to Dominique Bongard.
*
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
* SPDX-License-Identifier: GPL-3.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#if __STDC_VERSION__ < 199901L
# define inline static
#endif
#include <stdint.h>
typedef unsigned char uint8_t;
#include "crypto/md_internal.h"
#include "crypto/sha256.h"
#define sha256(i, l, d) mbedtls_sha256(i, l, d, 0)
#define hmac_sha256(k, l, i, n, o) \
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), k, l, i, n, o)
#endif /* CONFIG_H */

369
src/crypto/md.c Normal file
View File

@ -0,0 +1,369 @@
/**
* \file mbedtls_md.c
*
* \brief Generic message digest wrapper for mbed TLS
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#include <stdlib.h>
#include <string.h>
#include "md.h"
#include "md_internal.h"
#define mbedtls_calloc calloc
#define mbedtls_free free
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* Reminder: update profiles in x509_crt.c when adding a new hash!
*/
static const int supported_digests[] = {
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA224,
MBEDTLS_MD_NONE
};
const int *mbedtls_md_list( void )
{
return( supported_digests );
}
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
{
if( NULL == md_name )
return( NULL );
/* Get the appropriate digest information */
if( !strcmp( "SHA224", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
if( !strcmp( "SHA256", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
return( NULL );
}
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
{
switch( md_type )
{
case MBEDTLS_MD_SHA224:
return( &mbedtls_sha224_info );
case MBEDTLS_MD_SHA256:
return( &mbedtls_sha256_info );
default:
return( NULL );
}
}
void mbedtls_md_init( mbedtls_md_context_t *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
}
void mbedtls_md_free( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return;
if( ctx->md_ctx != NULL )
ctx->md_info->ctx_free_func( ctx->md_ctx );
if( ctx->hmac_ctx != NULL )
{
mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
mbedtls_free( ctx->hmac_ctx );
}
mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
}
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src )
{
if( dst == NULL || dst->md_info == NULL ||
src == NULL || src->md_info == NULL ||
dst->md_info != src->md_info )
{
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
return( 0 );
}
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
{
return mbedtls_md_setup( ctx, md_info, 1 );
}
#endif
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{
if( md_info == NULL || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
if( ctx->hmac_ctx == NULL )
{
md_info->ctx_free_func( ctx->md_ctx );
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
ctx->md_info = md_info;
return( 0 );
}
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->starts_func( ctx->md_ctx );
return( 0 );
}
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->update_func( ctx->md_ctx, input, ilen );
return( 0 );
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->finish_func( ctx->md_ctx, output );
return( 0 );
}
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output )
{
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info->digest_func( input, ilen, output );
return( 0 );
}
#if defined(MBEDTLS_FS_IO)
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
{
int ret;
FILE *f;
size_t n;
mbedtls_md_context_t ctx;
unsigned char buf[1024];
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
mbedtls_md_init( &ctx );
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
md_info->starts_func( ctx.md_ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md_info->update_func( ctx.md_ctx, buf, n );
if( ferror( f ) != 0 )
{
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
goto cleanup;
}
md_info->finish_func( ctx.md_ctx, output );
cleanup:
fclose( f );
mbedtls_md_free( &ctx );
return( ret );
}
#endif /* MBEDTLS_FS_IO */
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
{
unsigned char sum[MBEDTLS_MD_MAX_SIZE];
unsigned char *ipad, *opad;
size_t i;
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( keylen > (size_t) ctx->md_info->block_size )
{
ctx->md_info->starts_func( ctx->md_ctx );
ctx->md_info->update_func( ctx->md_ctx, key, keylen );
ctx->md_info->finish_func( ctx->md_ctx, sum );
keylen = ctx->md_info->size;
key = sum;
}
ipad = (unsigned char *) ctx->hmac_ctx;
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
memset( ipad, 0x36, ctx->md_info->block_size );
memset( opad, 0x5C, ctx->md_info->block_size );
for( i = 0; i < keylen; i++ )
{
ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
opad[i] = (unsigned char)( opad[i] ^ key[i] );
}
mbedtls_zeroize( sum, sizeof( sum ) );
ctx->md_info->starts_func( ctx->md_ctx );
ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
return( 0 );
}
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->update_func( ctx->md_ctx, input, ilen );
return( 0 );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
unsigned char *opad;
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
ctx->md_info->finish_func( ctx->md_ctx, tmp );
ctx->md_info->starts_func( ctx->md_ctx );
ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size );
ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size );
ctx->md_info->finish_func( ctx->md_ctx, output );
return( 0 );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
{
unsigned char *ipad;
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ipad = (unsigned char *) ctx->hmac_ctx;
ctx->md_info->starts_func( ctx->md_ctx );
ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
return( 0 );
}
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
mbedtls_md_context_t ctx;
int ret;
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
mbedtls_md_init( &ctx );
if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
return( ret );
mbedtls_md_hmac_starts( &ctx, key, keylen );
mbedtls_md_hmac_update( &ctx, input, ilen );
mbedtls_md_hmac_finish( &ctx, output );
mbedtls_md_free( &ctx );
return( 0 );
}
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->process_func( ctx->md_ctx, data );
return( 0 );
}
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
{
if( md_info == NULL )
return( 0 );
return md_info->size;
}
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
{
if( md_info == NULL )
return( MBEDTLS_MD_NONE );
return md_info->type;
}
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
{
if( md_info == NULL )
return( NULL );
return md_info->name;
}

334
src/crypto/md.h Normal file
View File

@ -0,0 +1,334 @@
/**
* \file mbedtls_md.h
*
* \brief Generic message digest wrapper
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_H
#define MBEDTLS_MD_H
#include <stddef.h>
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
typedef enum {
MBEDTLS_MD_NONE = 0,
MBEDTLS_MD_SHA224,
MBEDTLS_MD_SHA256,
} mbedtls_md_type_t;
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
/**
* Opaque struct defined in md_internal.h
*/
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
* Generic message digest context.
*/
typedef struct {
/** Information about the associated message digest */
const mbedtls_md_info_t *md_info;
/** Digest-specific context */
void *md_ctx;
/** HMAC part of the context */
void *hmac_ctx;
} mbedtls_md_context_t;
/**
* \brief Returns the list of digests supported by the generic digest module.
*
* \return a statically allocated array of digests, the last entry
* is 0.
*/
const int *mbedtls_md_list( void );
/**
* \brief Returns the message digest information associated with the
* given digest name.
*
* \param md_name Name of the digest to search for.
*
* \return The message digest information associated with md_name or
* NULL if not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/**
* \brief Returns the message digest information associated with the
* given digest type.
*
* \param md_type type of digest to search for.
*
* \return The message digest information associated with md_type or
* NULL if not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief Initialize a md_context (as NONE)
* This should always be called first.
* Prepares the context for mbedtls_md_setup() or mbedtls_md_free().
*/
void mbedtls_md_init( mbedtls_md_context_t *ctx );
/**
* \brief Free and clear the internal structures of ctx.
* Can be called at any time after mbedtls_md_init().
* Mandatory once mbedtls_md_setup() has been called.
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Select MD to use and allocate internal structures.
* Should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0
*
* \param ctx Context to set up.
* \param md_info Message digest to use.
*
* \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Select MD to use and allocate internal structures.
* Should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \param ctx Context to set up.
* \param md_info Message digest to use.
* \param hmac 0 to save some memory if HMAC will not be used,
* non-zero is HMAC is going to be used with this context.
*
* \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
* \brief Clone the state of an MD context
*
* \note The two contexts must have been setup to the same type
* (cloning from SHA-256 to SHA-512 make no sense).
*
* \warning Only clones the MD state, not the HMAC state! (for now)
*
* \param dst The destination context
* \param src The context to be cloned
*
* \return \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
/**
* \brief Returns the size of the message digest output.
*
* \param md_info message digest info
*
* \return size of the message digest output in bytes.
*/
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
/**
* \brief Returns the type of the message digest output.
*
* \param md_info message digest info
*
* \return type of the message digest output.
*/
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
/**
* \brief Returns the name of the message digest output.
*
* \param md_info message digest info
*
* \return name of the message digest output.
*/
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
/**
* \brief Prepare the context to digest a new message.
* Generally called after mbedtls_md_setup() or mbedtls_md_finish().
* Followed by mbedtls_md_update().
*
* \param ctx generic message digest context.
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/**
* \brief Generic message digest process buffer
* Called between mbedtls_md_starts() and mbedtls_md_finish().
* May be called repeatedly.
*
* \param ctx Generic message digest context
* \param input buffer holding the datal
* \param ilen length of the input data
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief Generic message digest final digest
* Called after mbedtls_md_update().
* Usually followed by mbedtls_md_free() or mbedtls_md_starts().
*
* \param ctx Generic message digest context
* \param output Generic message digest checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/**
* \brief Output = message_digest( input buffer )
*
* \param md_info message digest info
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic message digest checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Output = message_digest( file contents )
*
* \param md_info message digest info
* \param path input file name
* \param output generic message digest checksum result
*
* \return 0 if successful,
* MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed,
* MBEDTLS_ERR_MD_BAD_INPUT_DATA if md_info was NULL.
*/
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output );
#endif /* MBEDTLS_FS_IO */
/**
* \brief Set HMAC key and prepare to authenticate a new message.
* Usually called after mbedtls_md_setup() or mbedtls_md_hmac_finish().
*
* \param ctx HMAC context
* \param key HMAC secret key
* \param keylen length of the HMAC key in bytes
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen );
/**
* \brief Generic HMAC process buffer.
* Called between mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
* and mbedtls_md_hmac_finish().
* May be called repeatedly.
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief Output HMAC.
* Called after mbedtls_md_hmac_update().
* Usually followed my mbedtls_md_hmac_reset(), mbedtls_md_hmac_starts(),
* or mbedtls_md_free().
*
* \param ctx HMAC context
* \param output Generic HMAC checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/**
* \brief Prepare to authenticate a new message with the same key.
* Called after mbedtls_md_hmac_finish() and before mbedtls_md_hmac_update().
*
* \param ctx HMAC context to be reset
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/**
* \brief Output = Generic_HMAC( hmac key, input buffer )
*
* \param md_info message digest info
* \param key HMAC secret key
* \param keylen length of the HMAC key in bytes
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic HMAC-result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/* Internal use */
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#endif /* MBEDTLS_MD_H */

79
src/crypto/md_internal.h Normal file
View File

@ -0,0 +1,79 @@
/**
* \file md_internal.h
*
* \brief Message digest wrappers.
*
* \warning This in an internal header. Do not include directly.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_WRAP_H
#define MBEDTLS_MD_WRAP_H
#include "md.h"
/**
* Message digest information.
* Allows message digest functions to be called in a generic way.
*/
struct mbedtls_md_info_t
{
/** Digest identifier */
mbedtls_md_type_t type;
/** Name of the message digest */
const char * name;
/** Output length of the digest function in bytes */
int size;
/** Block length of the digest function in bytes */
int block_size;
/** Digest initialisation function */
void (*starts_func)( void *ctx );
/** Digest update function */
void (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
/** Digest finalisation function */
void (*finish_func)( void *ctx, unsigned char *output );
/** Generic digest function */
void (*digest_func)( const unsigned char *input, size_t ilen,
unsigned char *output );
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
/** Clone state from a context */
void (*clone_func)( void *dst, const void *src );
/** Internal use only */
void (*process_func)( void *ctx, const unsigned char *input );
};
extern const mbedtls_md_info_t mbedtls_sha224_info;
extern const mbedtls_md_info_t mbedtls_sha256_info;
#endif /* MBEDTLS_MD_WRAP_H */

122
src/crypto/md_wrap.c Normal file
View File

@ -0,0 +1,122 @@
/**
* \file md_wrap.c
*
* \brief Generic message digest wrapper for mbed TLS
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#include <stdlib.h>
#include "md_internal.h"
#include "sha256.h"
#define mbedtls_calloc calloc
#define mbedtls_free free
static void sha224_starts_wrap( void *ctx )
{
mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 1 );
}
static void sha224_update_wrap( void *ctx, const unsigned char *input,
size_t ilen )
{
mbedtls_sha256_update( (mbedtls_sha256_context *) ctx, input, ilen );
}
static void sha224_finish_wrap( void *ctx, unsigned char *output )
{
mbedtls_sha256_finish( (mbedtls_sha256_context *) ctx, output );
}
static void sha224_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
mbedtls_sha256( input, ilen, output, 1 );
}
static void *sha224_ctx_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
if( ctx != NULL )
mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
return( ctx );
}
static void sha224_ctx_free( void *ctx )
{
mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
mbedtls_free( ctx );
}
static void sha224_clone_wrap( void *dst, const void *src )
{
mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
(const mbedtls_sha256_context *) src );
}
static void sha224_process_wrap( void *ctx, const unsigned char *data )
{
mbedtls_sha256_process( (mbedtls_sha256_context *) ctx, data );
}
const mbedtls_md_info_t mbedtls_sha224_info = {
MBEDTLS_MD_SHA224,
"SHA224",
28,
64,
sha224_starts_wrap,
sha224_update_wrap,
sha224_finish_wrap,
sha224_wrap,
sha224_ctx_alloc,
sha224_ctx_free,
sha224_clone_wrap,
sha224_process_wrap,
};
static void sha256_starts_wrap( void *ctx )
{
mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 0 );
}
static void sha256_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
mbedtls_sha256( input, ilen, output, 0 );
}
const mbedtls_md_info_t mbedtls_sha256_info = {
MBEDTLS_MD_SHA256,
"SHA256",
32,
64,
sha256_starts_wrap,
sha224_update_wrap,
sha224_finish_wrap,
sha256_wrap,
sha224_ctx_alloc,
sha224_ctx_free,
sha224_clone_wrap,
sha224_process_wrap,
};

315
src/crypto/sha256.c Normal file
View File

@ -0,0 +1,315 @@
/*
* FIPS-180-2 compliant SHA-256 implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "sha256.h"
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
do { \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
} while( 0 )
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
do { \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
} while( 0 )
#endif
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
}
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src )
{
*dst = *src;
}
/*
* SHA-256 context setup
*/
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is224 == 0 )
{
/* SHA-256 */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
else
{
/* SHA-224 */
ctx->state[0] = 0xC1059ED8;
ctx->state[1] = 0x367CD507;
ctx->state[2] = 0x3070DD17;
ctx->state[3] = 0xF70E5939;
ctx->state[4] = 0xFFC00B31;
ctx->state[5] = 0x68581511;
ctx->state[6] = 0x64F98FA7;
ctx->state[7] = 0xBEFA4FA4;
}
ctx->is224 = is224;
}
#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
static const uint32_t K[] =
{
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
};
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define R(t) \
( \
W[t] = S1(W[t - 2]) + W[t - 7] + \
S0(W[t - 15]) + W[t - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
{
uint32_t temp1, temp2, W[64];
uint32_t A[8];
unsigned int i;
for( i = 0; i < 8; i++ )
A[i] = ctx->state[i];
#if defined(MBEDTLS_SHA256_SMALLER)
for( i = 0; i < 64; i++ )
{
if( i < 16 )
GET_UINT32_BE( W[i], data, 4 * i );
else
R( i );
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
GET_UINT32_BE( W[i], data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
}
for( i = 16; i < 64; i += 8 )
{
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
}
#endif /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 8; i++ )
ctx->state[i] += A[i];
}
/*
* SHA-256 process buffer
*/
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen == 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
mbedtls_sha256_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
mbedtls_sha256_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
static const unsigned char sha256_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-256 final digest
*/
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_BE( high, msglen, 0 );
PUT_UINT32_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
mbedtls_sha256_update( ctx, sha256_padding, padn );
mbedtls_sha256_update( ctx, msglen, 8 );
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
PUT_UINT32_BE( ctx->state[2], output, 8 );
PUT_UINT32_BE( ctx->state[3], output, 12 );
PUT_UINT32_BE( ctx->state[4], output, 16 );
PUT_UINT32_BE( ctx->state[5], output, 20 );
PUT_UINT32_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
PUT_UINT32_BE( ctx->state[7], output, 28 );
}
#endif /* !MBEDTLS_SHA256_ALT */
/*
* output = SHA-256( input buffer )
*/
void mbedtls_sha256( const unsigned char *input, size_t ilen,
unsigned char output[32], int is224 )
{
mbedtls_sha256_context ctx;
mbedtls_sha256_init( &ctx );
mbedtls_sha256_starts( &ctx, is224 );
mbedtls_sha256_update( &ctx, input, ilen );
mbedtls_sha256_finish( &ctx, output );
mbedtls_sha256_free( &ctx );
}

104
src/crypto/sha256.h Normal file
View File

@ -0,0 +1,104 @@
/**
* \file mbedtls_sha256.h
*
* \brief SHA-224 and SHA-256 cryptographic hash function
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA256_H
#define MBEDTLS_SHA256_H
#include <stddef.h>
#include <stdint.h>
/**
* \brief SHA-256 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
int is224; /*!< 0 => SHA-256, else SHA-224 */
}
mbedtls_sha256_context;
/**
* \brief Initialize SHA-256 context
*
* \param ctx SHA-256 context to be initialized
*/
void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
/**
* \brief Clear SHA-256 context
*
* \param ctx SHA-256 context to be cleared
*/
void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
/**
* \brief Clone (the state of) a SHA-256 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src );
/**
* \brief SHA-256 context setup
*
* \param ctx context to be initialized
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );
/**
* \brief SHA-256 process buffer
*
* \param ctx SHA-256 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief SHA-256 final digest
*
* \param ctx SHA-256 context
* \param output SHA-224/256 checksum result
*/
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] );
/* Internal use */
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
/**
* \brief Output = SHA-256( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-224/256 checksum result
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void mbedtls_sha256( const unsigned char *input, size_t ilen,
unsigned char output[32], int is224 );
#endif /* MBEDTLS_SHA256_H */

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,8 @@
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
* All credits for the research go to Dominique Bongard.
*
* Special thanks to: datahead, soxrok2212
*
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
* Version: 1.1
*
* DISCLAIMER: This tool was made for educational purposes only.
* The author is NOT responsible for any misuse or abuse.
* SPDX-License-Identifier: GPL-3.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,73 +17,95 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
#ifndef PIXIEWPS_H
#define PIXIEWPS_H
#define VERSION "1.1"
#define MAX_MODE 4
#define MODE4_DAYS 3
#define SEC_PER_HOUR 3600
/* Modes constants */
#define NONE 0
#define RT 1
#define ECOS_SIMPLE 2
#define RTL819x 3
#define ECOS_SIMPLEST 4 /* Not tested */
#define ECOS_KNUTH 5 /* Not tested */
/* Modes constants */
#define MODE_LEN 5
#define MODE3_DAYS 3
#define MODE3_TRIES 3
#define SEC_PER_DAY 86400
/* WPS constants */
#define WPS_PUBKEY_LEN 192
#define WPS_HASH_LEN 32
#define WPS_AUTHKEY_LEN 32
#define WPS_EMSK_LEN 32
#define WPS_KEYWRAPKEY_LEN 16
#define WPS_NONCE_LEN 16
#define WPS_SECRET_NONCE_LEN 16
#define WPS_PSK_LEN 16
#define WPS_BSSID_LEN 6
#define WPS_KDF_SALT_LEN 36
/* Exit costants */
#define PIN_ERROR 2
#define MEM_ERROR 3
#define ARG_ERROR 4
#define PIN_FOUND 0
#define PIN_ERROR 1
#define MEM_ERROR 2
#define ARG_ERROR 3
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef enum {false = 0, true = 1} bool;
#include "utils.h"
#if defined(DEBUG)
# define DEBUG_PRINT(fmt, args...); fprintf(stderr, "\n [DEBUG] %s:%d:%s(): " fmt, \
__FILE__, __LINE__, __func__, ##args); fflush(stdout);
# define DEBUG_PRINT_ARRAY(b, l); byte_array_print(b, l); fflush(stdout);
#else
# define DEBUG_PRINT(fmt, args...)
# define DEBUG_PRINT_ARRAY(b, l)
#endif
uint_fast8_t p_mode[MODE_LEN] = { 0 };
const char *p_mode_name[MODE_LEN + 1] = { "", "RT", "eCos simple", "RTL819x", "eCos simplest", "eCos Knuth" };
const uint8_t wps_rtl_pke[] = {
0xD0,0x14,0x1B,0x15, 0x65,0x6E,0x96,0xB8, 0x5F,0xCE,0xAD,0x2E, 0x8E,0x76,0x33,0x0D,
0x2B,0x1A,0xC1,0x57, 0x6B,0xB0,0x26,0xE7, 0xA3,0x28,0xC0,0xE1, 0xBA,0xF8,0xCF,0x91,
0x66,0x43,0x71,0x17, 0x4C,0x08,0xEE,0x12, 0xEC,0x92,0xB0,0x51, 0x9C,0x54,0x87,0x9F,
0x21,0x25,0x5B,0xE5, 0xA8,0x77,0x0E,0x1F, 0xA1,0x88,0x04,0x70, 0xEF,0x42,0x3C,0x90,
0xE3,0x4D,0x78,0x47, 0xA6,0xFC,0xB4,0x92, 0x45,0x63,0xD1,0xAF, 0x1D,0xB0,0xC4,0x81,
0xEA,0xD9,0x85,0x2C, 0x51,0x9B,0xF1,0xDD, 0x42,0x9C,0x16,0x39, 0x51,0xCF,0x69,0x18,
0x1B,0x13,0x2A,0xEA, 0x2A,0x36,0x84,0xCA, 0xF3,0x5B,0xC5,0x4A, 0xCA,0x1B,0x20,0xC8,
0x8B,0xB3,0xB7,0x33, 0x9F,0xF7,0xD5,0x6E, 0x09,0x13,0x9D,0x77, 0xF0,0xAC,0x58,0x07,
0x90,0x97,0x93,0x82, 0x51,0xDB,0xBE,0x75, 0xE8,0x67,0x15,0xCC, 0x6B,0x7C,0x0C,0xA9,
0x45,0xFa,0x8D,0xD8, 0xD6,0x61,0xBE,0xB7, 0x3B,0x41,0x40,0x32, 0x79,0x8D,0xAD,0xEE,
0x32,0xB5,0xDD,0x61, 0xBF,0x10,0x5F,0x18, 0xD8,0x92,0x17,0x76, 0x0B,0x75,0xC5,0xD9,
0x66,0xA5,0xA4,0x90, 0x47,0x2C,0xEB,0xA9, 0xE3,0xB4,0x22,0x4F, 0x3D,0x89,0xFB,0x2B
};
const uint8_t rtl_rnd_seed[] = {
0x52,0x65,0x61,0x6c, 0x74,0x65,0x6b,0x20, 0x57,0x69,0x46,0x69, 0x20,0x53,0x69,0x6d,
0x70,0x6c,0x65,0x2d, 0x43,0x6f,0x6e,0x66, 0x69,0x67,0x20,0x44, 0x61,0x65,0x6d,0x6f,
0x6e,0x20,0x70,0x72, 0x6f,0x67,0x72,0x61, 0x6d,0x20,0x32,0x30, 0x30,0x36,0x2d,0x30,
0x35,0x2d,0x31,0x35
};
struct global {
unsigned char *pke;
unsigned char *pkr;
unsigned char *e_hash1;
unsigned char *e_hash2;
unsigned char *authkey;
unsigned char *e_nonce;
unsigned char *r_nonce;
unsigned char *psk1;
unsigned char *psk2;
unsigned char *dhkey;
unsigned char *kdk;
unsigned char *wrapkey;
unsigned char *emsk;
unsigned char *e_s1;
unsigned char *e_s2;
unsigned char *e_bssid;
bool small_dh_keys;
bool bruteforce;
uint8_t *pke;
uint8_t *pkr;
uint8_t *e_hash1;
uint8_t *e_hash2;
uint8_t *authkey;
uint8_t *e_nonce;
uint8_t *r_nonce;
uint8_t *psk1;
uint8_t *psk2;
uint8_t *dhkey;
uint8_t *kdk;
uint8_t *wrapkey;
uint8_t *emsk;
uint8_t *e_s1;
uint8_t *e_s2;
uint8_t *e_bssid;
time_t start;
time_t end;
uint8_t small_dh_keys;
uint8_t mode_auto;
uint8_t bruteforce;
int verbosity;
char *error;
char *warning;
};
char usage[] =
@ -100,86 +117,127 @@ char usage[] =
"\n"
" Required Arguments:\n"
"\n"
" -e, --pke : Enrollee public key\n"
" -r, --pkr : Registrar public key\n"
" -s, --e-hash1 : Enrollee Hash1\n"
" -z, --e-hash2 : Enrollee Hash2\n"
" -a, --authkey : Authentication session key\n"
" -e, --pke : Enrollee public key\n"
" -r, --pkr : Registrar public key\n"
" -s, --e-hash1 : Enrollee hash-1\n"
" -z, --e-hash2 : Enrollee hash-2\n"
" -a, --authkey : Authentication session key\n"
" -n, --e-nonce : Enrollee nonce\n"
"\n"
" Optional Arguments:\n"
"\n"
" -n, --e-nonce : Enrollee nonce\n"
" -m, --r-nonce : Registrar nonce\n"
" -b, --e-bssid : Enrollee BSSID\n"
" -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]\n"
" -f, --force : Bruteforce the whole keyspace [No]\n"
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
" -m, --r-nonce : Registrar nonce\n"
" -b, --e-bssid : Enrollee BSSID\n"
" -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]\n"
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
"\n"
" -h, --help : Display this usage screen\n"
" -h : Display this usage screen\n"
" --help : Verbose help and more usage examples\n"
" -V, --version : Displays version\n"
"\n"
" Examples:\n"
" --mode N[,... N] : Mode selection, comma separated [Auto]\n"
" --start [mm/]yyyy : Starting date (only mode 3) [Current time]\n"
" --end [mm/]yyyy : Ending date (only mode 3) [-3 days]\n"
"\n"
" Example:\n"
"\n"
" pixiewps -e <pke> -r <pkr> -s <e-hash1> -z <e-hash2> -a <authkey> -n <e-nonce>\n"
" pixiewps -e <pke> -s <e-hash1> -z <e-hash2> -a <authkey> -n <e-nonce> -S\n"
" pixiewps -e <pke> -s <e-hash1> -z <e-hash2> -n <e-nonce> -m <r-nonce> -b <e-bssid> -S\n"
"%s";
/* SHA-256 */
void sha256(const unsigned char *data, const size_t data_len, unsigned char *digest) {
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, data, data_len);
SHA256_Final(digest, &ctx);
}
char v_usage[] =
"\n"
" Pixiewps %s WPS pixie dust attack tool\n"
" Copyright (c) 2015, wiire <wi7ire@gmail.com>\n"
"\n"
" Description of arguments:\n"
"\n"
" -e, --pke\n"
"\n"
" Enrollee DH public key, found in M1.\n"
"\n"
" -r, --pkr\n"
"\n"
" Registrar DH public key, found in M2. It can be avoided by specifying "
"--dh-small in both Reaver and Pixiewps.\n"
"\n"
" [?] pixiewps -e <pke> -s <e-hash1> -z <e-hash2> -a <authkey> -n <e-nonce> -S\n"
"\n"
" -s, --e-hash1\n"
"\n"
" Enrollee hash-1, found in M3.\n"
"\n"
" -z, --e-hash2\n"
"\n"
" Enrollee hash-2, found in M3.\n"
"\n"
" -a, --authkey\n"
"\n"
" Authentication session key. Although for this parameter a modified version of "
"Reaver or Bully is needed, it can be avoided by specifying small Diffie-Hellman "
"keys in both Reaver and Pixiewps and supplying --e-nonce, --r-nonce and --e-bssid.\n"
"\n"
" [?] pixiewps -e <pke> -s <e-hash1> -z <e-hash2> -S -n <e-nonce> -m <r-nonce> -b <e-bssid>\n"
"\n"
" -n, --e-nonce\n"
"\n"
" Enrollee's nonce, found in M1.\n"
"\n"
" -m, --r-nonce\n"
"\n"
" Registrar's nonce, found in M2.\n"
"\n"
" -b, --e-bssid\n"
"\n"
" Enrollee's BSSID.\n"
"\n"
" -S, --dh-small\n"
"\n"
" Small Diffie-Hellman keys. The same option MUST be specified in Reaver "
"(1.3 or later versions) too. It DOES NOT WORK with mode 3.\n"
"\n"
" --mode N[,... N]\n"
"\n"
" Select modes, comma separated (experimental modes are not used if not specified):\n"
"\n"
" 1 (%s)\n"
" 2 (%s)\n"
" 3 (%s)\n"
" 4 (%s) [Experimental]\n"
" 5 (%s) [Experimental]\n"
"\n"
" --start [mm/]yyyy\n"
" --end [mm/]yyyy\n"
"\n"
" Starting and ending dates for mode 3. They are interchangeable. "
"If only one is specified, the machine current time will be used for the other.\n"
"\n";
/* HMAC-SHA-256 */
void hmac_sha256(const void *key, int key_len, const unsigned char *data, const size_t data_len, unsigned char *digest) {
unsigned int h_len = WPS_HASH_LEN;
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, key_len, EVP_sha256(), 0);
HMAC_Update(&ctx, data, data_len);
HMAC_Final(&ctx, digest, &h_len);
HMAC_CTX_cleanup(&ctx);
}
/* Key Derivation Function */
void kdf(const void *key, const size_t key_len, unsigned char *res) {
uint32_t kdk_len = key_len * 8;
uint_fast8_t j = 0;
/* Wi-Fi Easy and Secure Key Derivation */
char *salt = "\x57\x69\x2d\x46\x69\x20\x45\x61\x73\x79\x20\x61\x6e\x64\x20\x53\x65\x63\x75\x72\x65\x20\x4b\x65\x79\x20\x44\x65\x72\x69\x76\x61\x74\x69\x6f\x6e";
unsigned char *buffer = malloc(WPS_KDF_SALT_LEN + 4 * 2);
for (uint32_t i = 1; i < 4; i++) {
uint32_t be = h32_to_be(i);
memcpy(buffer, &be, 4);
memcpy(buffer + 4, salt, WPS_KDF_SALT_LEN);
be = h32_to_be(kdk_len);
memcpy(buffer + 4 + 36, &be, 4);
hmac_sha256(key, WPS_HASH_LEN, buffer, WPS_KDF_SALT_LEN + 4 * 2, res + j);
j += WPS_HASH_LEN;
/* One digit comma separated number parsing */
inline uint_fast8_t parse_mode(char *list, uint_fast8_t *dst, const uint_fast8_t max_digit) {
uint_fast8_t cnt = 0;
while (*list != 0) {
if (*list <= (max_digit + '0')) {
dst[cnt] = *list - '0';
cnt++;
list++;
}
if (*list != 0) {
if (*list == ',')
list++;
else
return 1;
}
}
free(buffer);
return 0;
}
/* Pin checksum computing */
inline unsigned int wps_pin_checksum(unsigned int pin) {
unsigned int acc = 0;
while (pin) {
acc += 3 * (pin % 10);
pin /= 10;
acc += pin % 10;
pin /= 10;
/* Checks if passed mode is selected */
inline uint_fast8_t is_mode_selected(const uint_fast8_t mode) {
for (uint_fast8_t i = 0; p_mode[i] != NONE && i < MODE_LEN; i++) {
if (p_mode[i] == mode)
return 1;
}
return (10 - acc % 10) % 10;
}
/* Validity PIN control based on checksum */
inline unsigned int wps_pin_valid(unsigned int pin) {
return wps_pin_checksum(pin / 10) == (pin % 10);
return 0;
}
#endif /* PIXIEWPS_H */

View File

@ -30,11 +30,8 @@
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
# include <sys/param.h>
# if defined(__APPLE__) && defined(__MACH__)
# include "../include/features.h"
# elif(BSD)
/* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD)
Nothing to include */
# if defined(BSD) || defined(__APPLE__) && defined(__MACH__)
/* Nothing to include */
# else
# include <features.h>
# endif

View File

@ -2,13 +2,8 @@
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
* All credits for the research go to Dominique Bongard.
*
* Special thanks to: datahead, soxrok2212
*
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
* Version: 1.1
*
* DISCLAIMER: This tool was made for educational purposes only.
* The author is NOT responsible for any misuse or abuse.
* SPDX-License-Identifier: GPL-3.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,21 +17,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
#ifndef RANDOM_R_H
#define RANDOM_R_H

View File

@ -2,13 +2,8 @@
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
* All credits for the research go to Dominique Bongard.
*
* Special thanks to: datahead, soxrok2212
*
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
* Version: 1.1
*
* DISCLAIMER: This tool was made for educational purposes only.
* The author is NOT responsible for any misuse or abuse.
* SPDX-License-Identifier: GPL-3.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,26 +17,17 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
#ifndef UTILS_H
#define UTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* Converts an hex string to a byte array */
unsigned int hex_string_to_byte_array(char *in, unsigned char *out, const unsigned int n_len) {
unsigned int hex_string_to_byte_array(char *in, uint8_t *out, const unsigned int n_len) {
uint_fast8_t o;
unsigned int len = strlen(in);
unsigned int b_len = n_len * 2 + n_len - 1;
@ -88,8 +74,59 @@ int get_int(char *in, int *out) {
return 0;
};
/* Converts a [mm/]yyyy string to Unix date time */
unsigned int get_unix_datetime(char *s, time_t *datetime) {
unsigned int len = strlen(s);
int month = 0, year;
struct tm tm;
if (len == 4) {
if (get_int(s, &year))
return 1;
} else if (len == 7) {
if (s[2] != '/' && s[2] != '-' && s[2] != '.')
return 1;
char s_month[3];
char s_year[5];
if (s[0] == '0') {
s_month[0] = s[1];
s_month[1] = 0;
} else {
s_month[0] = s[0];
s_month[1] = s[1];
s_month[2] = 0;
}
s_year[0] = s[3];
s_year[1] = s[4];
s_year[2] = s[5];
s_year[3] = s[6];
s_year[4] = 0;
if (get_int(s_month, &month) || get_int(s_year, &year))
return 1;
} else {
return 1;
}
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
tm.tm_mday = 1;
tm.tm_mon = month - 1;
tm.tm_year = year - 1900;
tm.tm_isdst = -1;
*datetime = mktime(&tm);
if (*datetime < 0)
return 1;
return 0;
}
/* Converts an unsigned integer to a char array without termination */
void uint_to_char_array(unsigned int num, unsigned int len, unsigned char *dst) {
inline void uint_to_char_array(unsigned int num, unsigned int len, uint8_t *dst) {
unsigned int mul = 1;
while (len--) {
dst[len] = (num % (mul * 10) / mul) + '0';
@ -98,16 +135,17 @@ void uint_to_char_array(unsigned int num, unsigned int len, unsigned char *dst)
}
/* Prints a byte array in hexadecimal */
void byte_array_print(const unsigned char *buffer, const unsigned int length) {
void byte_array_print(const uint8_t *buffer, const unsigned int length) {
unsigned int i;
for (i = 0; i < length; i++) {
printf("%02x", buffer[i]);
if (i != length - 1) printf(":");
if (i != length - 1)
printf(":");
}
}
/* Converts a 32 Little Endian bit number to its Big Endian representation */
uint32_t h32_to_be(uint32_t num) {
uint32_t h32_to_be(const uint32_t num) {
uint32_t tmp = num;
uint32_t res;
uint32_t b0, b1, b2, b3;

27
src/version.h Normal file
View File

@ -0,0 +1,27 @@
/*
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
* All credits for the research go to Dominique Bongard.
*
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
* SPDX-License-Identifier: GPL-3.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VERSION_H
#define VERSION_H
#define SHORT_VERSION "1.2"
#define LONG_VERSION "1.2.0"
#endif /* VERSION_H */

113
src/wps.h Normal file
View File

@ -0,0 +1,113 @@
/*
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
* All credits for the research go to Dominique Bongard.
*
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
* SPDX-License-Identifier: GPL-3.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WPS_H
#define WPS_H
/* WPS constants */
#define WPS_PKEY_LEN 192
#define WPS_HASH_LEN 32
#define WPS_AUTHKEY_LEN 32
#define WPS_EMSK_LEN 32
#define WPS_KEYWRAPKEY_LEN 16
#define WPS_NONCE_LEN 16
#define WPS_SECRET_NONCE_LEN 16
#define WPS_PSK_LEN 16
#define WPS_BSSID_LEN 6
#include <stdlib.h>
#include <string.h>
#include "pixiewps.h"
#include "config.h"
#include "utils.h"
/* Diffie-Hellman group */
static const uint8_t dh_group5_generator[1] = { 0x02 };
static const uint8_t dh_group5_prime[192] = {
0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xC9,0x0F,0xDA,0xA2, 0x21,0x68,0xC2,0x34,
0xC4,0xC6,0x62,0x8B, 0x80,0xDC,0x1C,0xD1, 0x29,0x02,0x4E,0x08, 0x8A,0x67,0xCC,0x74,
0x02,0x0B,0xBE,0xA6, 0x3B,0x13,0x9B,0x22, 0x51,0x4A,0x08,0x79, 0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3, 0xCD,0x3A,0x43,0x1B, 0x30,0x2B,0x0A,0x6D, 0xF2,0x5F,0x14,0x37,
0x4F,0xE1,0x35,0x6D, 0x6D,0x51,0xC2,0x45, 0xE4,0x85,0xB5,0x76, 0x62,0x5E,0x7E,0xC6,
0xF4,0x4C,0x42,0xE9, 0xA6,0x37,0xED,0x6B, 0x0B,0xFF,0x5C,0xB6, 0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB, 0x5A,0x89,0x9F,0xA5, 0xAE,0x9F,0x24,0x11, 0x7C,0x4B,0x1F,0xE6,
0x49,0x28,0x66,0x51, 0xEC,0xE4,0x5B,0x3D, 0xC2,0x00,0x7C,0xB8, 0xA1,0x63,0xBF,0x05,
0x98,0xDA,0x48,0x36, 0x1C,0x55,0xD3,0x9A, 0x69,0x16,0x3F,0xA8, 0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23, 0xDC,0xA3,0xAD,0x96, 0x1C,0x62,0xF3,0x56, 0x20,0x85,0x52,0xBB,
0x9E,0xD5,0x29,0x07, 0x70,0x96,0x96,0x6D, 0x67,0x0C,0x35,0x4E, 0x4A,0xBC,0x98,0x04,
0xF1,0x74,0x6C,0x08, 0xCA,0x23,0x73,0x27, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF
};
/* Wi-Fi Easy and Secure Key Derivation */
static const uint8_t kdf_salt[] = {
0x57,0x69,0x2D,0x46, 0x69,0x20,0x45,0x61, 0x73,0x79,0x20,0x61, 0x6E,0x64,0x20,0x53,
0x65,0x63,0x75,0x72, 0x65,0x20,0x4B,0x65, 0x79,0x20,0x44,0x65, 0x72,0x69,0x76,0x61,
0x74,0x69,0x6F,0x6E
};
/* Key Derivation Function */
void kdf(const void *key, uint8_t *res) {
const uint32_t kdk_len = (WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN) * 8;
uint_fast8_t j = 0;
uint8_t *buffer = malloc(sizeof(kdf_salt) + sizeof(uint32_t) * 2);
for (uint32_t i = 1; i < 4; i++) {
uint32_t be = h32_to_be(i);
memcpy(buffer, &be, sizeof(uint32_t));
memcpy(buffer + sizeof(uint32_t), kdf_salt, sizeof(kdf_salt));
be = h32_to_be(kdk_len);
memcpy(buffer + sizeof(uint32_t) + sizeof(kdf_salt), &be, sizeof(uint32_t));
hmac_sha256(key, WPS_HASH_LEN, buffer, sizeof(kdf_salt) + sizeof(uint32_t) * 2, res + j);
j += WPS_HASH_LEN;
}
free(buffer);
}
/* Pin checksum computing */
inline uint_fast8_t wps_pin_checksum(uint_fast32_t pin) {
unsigned int acc = 0;
while (pin) {
acc += 3 * (pin % 10);
pin /= 10;
acc += pin % 10;
pin /= 10;
}
return (10 - acc % 10) % 10;
}
/* Validity PIN control based on checksum */
inline uint_fast8_t wps_pin_valid(uint_fast32_t pin) {
return wps_pin_checksum(pin / 10) == (pin % 10);
}
/* Checks if PKe == 2 */
inline uint_fast8_t check_small_dh_keys(const uint8_t *data) {
uint_fast8_t i = WPS_PKEY_LEN - 2;
while (--i) {
if (data[i] != 0)
break;
}
i = (i == 0 && data[WPS_PKEY_LEN - 1] == 0x02) ? 1 : 0;
return i;
}
#endif /* WPS_H */

View File

@ -1,4 +1,4 @@
PKG_NAME:=pixiewps
PKG_VERSION:=1.1
PKG_RELEASE:=2
PKG_LICENSE:=GPL-3.0+
PKG_VERSION:=1.2
PKG_RELEASE:=1
PKG_LICENSE:=GPL-3.0