diff --git a/projects/pycrypto/Dockerfile b/projects/pycrypto/Dockerfile new file mode 100644 index 000000000..3ea6ad6f7 --- /dev/null +++ b/projects/pycrypto/Dockerfile @@ -0,0 +1,20 @@ +# Copyright 2022 Google LLC +# +# 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. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder-python +RUN git clone https://github.com/pycrypto/pycrypto +COPY build.sh *.py $SRC/ +WORKDIR pycrypto diff --git a/projects/pycrypto/build.sh b/projects/pycrypto/build.sh new file mode 100644 index 000000000..652cb421a --- /dev/null +++ b/projects/pycrypto/build.sh @@ -0,0 +1,27 @@ +#!/bin/bash -eu +# Copyright 2022 Google LLC +# +# 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. +# +################################################################################ + +# time.clock has been removed in OSS-Fuzz's Python version. Update pycrypto's source +# code. Pycrypto is deprecated so we can't expect Pycrypto to be updated. +sed -i 's/clock(/perf_counter(/g' lib/Crypto/Random/_UserFriendlyRNG.py + +python3 setup.py build +python3 setup.py install + +for fuzzer in $(find $SRC -name 'fuzz_*.py'); do + compile_python_fuzzer $fuzzer +done diff --git a/projects/pycrypto/fuzz_aes.py b/projects/pycrypto/fuzz_aes.py new file mode 100644 index 000000000..e66b6da34 --- /dev/null +++ b/projects/pycrypto/fuzz_aes.py @@ -0,0 +1,47 @@ +#!/usr/bin/python3 +# Copyright 2022 Google LLC +# +# 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. + +import atheris +import sys + +with atheris.instrument_imports(): + from Crypto.Cipher import AES + + +def TestOneInput(data): + if len(data) < 20: + return + fdp = atheris.FuzzedDataProvider(data) + try: + obj = AES.new(fdp.ConsumeBytes(16), AES.MODE_CBC, 'This is an IV456') + except ValueError as e: + if not "Key cannot be the null string" in str(e): + raise e + return + + try: + ciphertext = obj.encrypt(data) + except ValueError as e: + if not "Input strings must be a multiple of 16 in length" in str(e): + raise e + + +def main(): + atheris.instrument_all() + atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) + atheris.Fuzz() + +if __name__ == "__main__": + main() diff --git a/projects/pycrypto/fuzz_all_or_nothing.py b/projects/pycrypto/fuzz_all_or_nothing.py new file mode 100644 index 000000000..db5eb8e51 --- /dev/null +++ b/projects/pycrypto/fuzz_all_or_nothing.py @@ -0,0 +1,40 @@ +#!/usr/bin/python3 +# Copyright 2022 Google LLC +# +# 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. + +import atheris +import sys + +with atheris.instrument_imports(): + from Crypto.Protocol import AllOrNothing + from Crypto.Cipher import AES + +def TestOneInput(data): + if len(data) < 10: + return + for i in range(50): + a1 = AllOrNothing.AllOrNothing(AES) + msgblocks = a1.digest(data) + a2 = AllOrNothing.AllOrNothing(AES) + round_tripped = a2.undigest(msgblocks) + assert data == round_tripped + + +def main(): + atheris.instrument_all() + atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) + atheris.Fuzz() + +if __name__ == "__main__": + main() diff --git a/projects/pycrypto/fuzz_hash.py b/projects/pycrypto/fuzz_hash.py new file mode 100644 index 000000000..2422dba58 --- /dev/null +++ b/projects/pycrypto/fuzz_hash.py @@ -0,0 +1,35 @@ +#!/usr/bin/python3 +# Copyright 2022 Google LLC +# +# 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. + +import atheris +import sys + +with atheris.instrument_imports(): + from Crypto.Hash import SHA256 + + +def TestOneInput(data): + fdp = atheris.FuzzedDataProvider(data) + h = SHA256.new() + h.update(data) + h.digest + + +def main(): + atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) + atheris.Fuzz() + +if __name__ == "__main__": + main() diff --git a/projects/pycrypto/project.yaml b/projects/pycrypto/project.yaml new file mode 100644 index 000000000..ada98143e --- /dev/null +++ b/projects/pycrypto/project.yaml @@ -0,0 +1,11 @@ +fuzzing_engines: +- libfuzzer +homepage: https://github.com/pycrypto/pycrypto +language: python +main_repo: https://github.com/pycrypto/pycrypto +sanitizers: +- address +- undefined +vendor_ccs: +- david@adalogics.com +- adam@adalogics.com