Skip to content

Commit aa807fc

Browse files
authored
[pycryptodome] Additional Fuzzer (google#4339)
* initial commit * update build script, build failing * add necessary environment variable definitions * build working * programmatically get system bits * add md5 fuzzer * fix style * add fuzzers for two more hash functions * testing dynamic includes * build working * clean up build script * add aes fuzzer * patch block_common to avoid build issues * remove comments * update patchfile location * move patchfile again * apply patch from subdirectory * remove another comment * change state type, use same data for encryption and decryption
1 parent 038a3e2 commit aa807fc

File tree

4 files changed

+69
-3
lines changed

4 files changed

+69
-3
lines changed

projects/pycryptodome/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
FROM gcr.io/oss-fuzz-base/base-builder
1818
RUN apt-get update && apt-get install -y make autoconf automake libtool
1919
RUN git clone --depth 1 https://github.com/Legrandin/pycryptodome.git
20-
WORKDIR pycryptodome
20+
WORKDIR pycryptodome/src
2121
COPY build.sh *_fuzzer.cc $SRC/
22+
COPY block_common.patch $SRC/pycryptodome/src
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
diff --git a/src/block_common.c b/src/block_common.c
2+
index 169200a6..c6da1f85 100644
3+
--- a/src/block_common.c
4+
+++ b/src/block_common.c
5+
@@ -106,7 +106,7 @@ EXPORT_SYM int CIPHER_START_OPERATION(const uint8_t key[], size_t key_len, CIPHE
6+
if ((key == NULL) || (pResult == NULL))
7+
return ERR_NULL;
8+
9+
- *pResult = calloc(1, sizeof(CIPHER_STATE_TYPE));
10+
+ *pResult = (CIPHER_STATE_TYPE *) calloc(1, sizeof(CIPHER_STATE_TYPE));
11+
if (NULL == *pResult)
12+
return ERR_MEMORY;

projects/pycryptodome/build.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#
1616
################################################################################
1717

18-
PCD_INTERNALS=(src/*.c src/libtom/*.c)
18+
patch block_common.c block_common.patch
19+
20+
PCD_INTERNALS=(./*.c ./libtom/*.c)
1921
PCD_FLAGS=(
2022
"-I $SRC/pycryptodome/src"
2123
"-I $SRC/pycryptodome/src/libtom"
@@ -29,7 +31,7 @@ PCD_FLAGS=(
2931
$CC $CFLAGS \
3032
${PCD_FLAGS[@]} \
3133
-c "${PCD_INTERNALS//'blake2.c'/}"
32-
ar -qc $WORK/libpycryptodome.a *.o
34+
ar -qc $WORK/libpycryptodome.a *.o
3335

3436
PCD_HASH_OPTIONS=(
3537
"-D HASHTYPE=md2 -D FNAME=MD2.c -D DIGEST_SIZE=16 -o $OUT/md2_fuzzer"
@@ -46,3 +48,7 @@ for ((i = 0; i < ${#PCD_HASH_OPTIONS[@]}; i++)); do
4648
$SRC/pcd_hash_fuzzer.cc ${PCD_HASH_OPTIONS[i]} \
4749
$LIB_FUZZING_ENGINE $WORK/libpycryptodome.a
4850
done
51+
52+
$CXX $CXXFLAGS ${PCD_FLAGS[@]} \
53+
$SRC/pcd_aes_fuzzer.cc -o $OUT/aes_fuzzer \
54+
$LIB_FUZZING_ENGINE $WORK/libpycryptodome.a
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "AES.c"
16+
#include "common.h"
17+
#include <fuzzer/FuzzedDataProvider.h>
18+
19+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
20+
21+
if (!size)
22+
return 0;
23+
24+
enum KeySize { AES128 = 16, AES192 = 24, AES256 = 32, kMaxValue = AES256 };
25+
26+
FuzzedDataProvider stream(data, size);
27+
const KeySize keySize = stream.ConsumeEnum<KeySize>();
28+
if (stream.remaining_bytes() < keySize)
29+
return 0;
30+
31+
std::vector<uint8_t> keyBuf = stream.ConsumeBytes<uint8_t>(keySize);
32+
const uint8_t *key = keyBuf.data();
33+
34+
BlockBase *state;
35+
if (AES_start_operation(key, keySize, reinterpret_cast<AES_State **>(&state)))
36+
return 0;
37+
38+
uint8_t outEnc[size];
39+
uint8_t outDec[size];
40+
41+
AES_encrypt(reinterpret_cast<BlockBase *>(state), data, outEnc, size);
42+
AES_decrypt(reinterpret_cast<BlockBase *>(state), data, outDec, size);
43+
44+
AES_stop_operation(reinterpret_cast<BlockBase *>(state));
45+
46+
return 0;
47+
}

0 commit comments

Comments
 (0)