-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a01e030
commit 680f199
Showing
7 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
all: module.a cryptofuzz.a | ||
|
||
CXXFLAGS += -Wall -Wextra -std=c++17 -I ../../include -I ../../fuzzing-headers/include -DFUZZING_HEADERS_NO_IMPL | ||
|
||
module.a: module.o | ||
rm -rf tmp/ | ||
mkdir tmp/ | ||
cd tmp/ && ar x ../cryptofuzz.a && ar rcs ../module.a *.o ../module.o | ||
ranlib module.a | ||
rm -rf tmp/ | ||
generate_ids : generate_ids.cpp | ||
$(CXX) $(CXXFLAGS) generate_ids.cpp -o generate_ids | ||
ids.go : generate_ids | ||
./generate_ids | ||
cryptofuzz.a: cryptofuzz.go ids.go | ||
go build -o cryptofuzz.a -buildmode=c-archive cryptofuzz.go ids.go | ||
module.o: cryptofuzz.a module.cpp module.h | ||
$(CXX) $(CXXFLAGS) -fPIC -c module.cpp -o module.o | ||
clean: | ||
rm -rf *.o module.a cryptofuzz.a cryptofuzz.h generate_ids ids.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"strconv" | ||
"encoding/hex" | ||
"encoding/json" | ||
"math/big" | ||
"github.com/cloudflare/circl/ecc/p384" | ||
) | ||
|
||
import "C" | ||
|
||
type ByteSlice []byte | ||
type Type uint64 | ||
|
||
type SliceOpt struct { | ||
slice ByteSlice | ||
opt byte | ||
} | ||
|
||
func (t *Type) UnmarshalJSON(in []byte) error { | ||
res, err := strconv.ParseUint(string(in[1:len(in)-1]), 10, 64) | ||
*t = Type(res) | ||
return err | ||
} | ||
|
||
func (b *ByteSlice) MarshalJSON() ([]byte, error) { | ||
var buffer bytes.Buffer | ||
buffer.WriteString("\"") | ||
buffer.WriteString(hex.EncodeToString(*b)) | ||
buffer.WriteString("\"") | ||
return buffer.Bytes(), nil | ||
} | ||
|
||
func (b *ByteSlice) UnmarshalJSON(in []byte) error { | ||
res, err := hex.DecodeString(string(in[1:len(in)-1])) | ||
*b = res | ||
return err | ||
} | ||
|
||
func decodeBignum(s string) *big.Int { | ||
if s == "" { | ||
s = "0" | ||
} | ||
|
||
bn, ok := new(big.Int).SetString(s, 10) | ||
if ok == false { | ||
panic("Cannot decode bignum") | ||
} | ||
return bn | ||
} | ||
|
||
type OpECC_Point_Add struct { | ||
Modifier ByteSlice | ||
CurveType Type | ||
A_x string | ||
A_y string | ||
B_x string | ||
B_y string | ||
} | ||
|
||
type OpECC_Point_Mul struct { | ||
Modifier ByteSlice | ||
CurveType Type | ||
A_x string | ||
A_y string | ||
B string | ||
} | ||
|
||
type OpECC_Point_Dbl struct { | ||
Modifier ByteSlice | ||
CurveType Type | ||
A_x string | ||
A_y string | ||
} | ||
|
||
var result []byte | ||
|
||
func resetResult() { | ||
result = []byte{} | ||
} | ||
|
||
func setResult(r ByteSlice) { | ||
r2, err := json.Marshal(&r) | ||
if err != nil { | ||
panic("Cannot marshal to JSON") | ||
} | ||
result = r2 | ||
} | ||
|
||
func unmarshal(in []byte, op interface{}) { | ||
err := json.Unmarshal(in, &op) | ||
if err != nil { | ||
panic("Cannot unmarshal JSON, which is expected to be well-formed") | ||
} | ||
} | ||
|
||
//export circl_Cryptofuzz_GetResult | ||
func circl_Cryptofuzz_GetResult() *C.char { | ||
return C.CString(string(result)) | ||
} | ||
|
||
//export circl_Cryptofuzz_OpECC_Point_Add | ||
func circl_Cryptofuzz_OpECC_Point_Add(in []byte) { | ||
resetResult() | ||
|
||
var op OpECC_Point_Add | ||
unmarshal(in, &op) | ||
|
||
if !issecp384r1(op.CurveType) { | ||
return | ||
} | ||
|
||
curve := p384.P384() | ||
|
||
a_x := decodeBignum(op.A_x) | ||
a_y := decodeBignum(op.A_y) | ||
|
||
b_x := decodeBignum(op.B_x) | ||
b_y := decodeBignum(op.B_y) | ||
|
||
res_x, res_y := curve.Add(a_x, a_y, b_x, b_y) | ||
|
||
if curve.IsOnCurve(a_x, a_y) == false { | ||
return | ||
} | ||
|
||
if curve.IsOnCurve(b_x, b_y) == false { | ||
return | ||
} | ||
|
||
res := make([]string, 2) | ||
res[0], res[1] = res_x.String(), res_y.String() | ||
|
||
r2, err := json.Marshal(&res) | ||
if err != nil { | ||
panic("Cannot marshal to JSON") | ||
} | ||
|
||
result = r2 | ||
} | ||
|
||
//export circl_Cryptofuzz_OpECC_Point_Mul | ||
func circl_Cryptofuzz_OpECC_Point_Mul(in []byte) { | ||
resetResult() | ||
|
||
var op OpECC_Point_Mul | ||
unmarshal(in, &op) | ||
|
||
if !issecp384r1(op.CurveType) { | ||
return | ||
} | ||
|
||
curve := p384.P384() | ||
|
||
a_x := decodeBignum(op.A_x) | ||
a_y := decodeBignum(op.A_y) | ||
|
||
b := decodeBignum(op.B) | ||
/* https://github.com/cloudflare/circl/issues/312 */ | ||
order := decodeBignum("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643") | ||
if ( b.Cmp(order) >= 0 ) { | ||
return | ||
} | ||
|
||
res_x, res_y := curve.ScalarMult(a_x, a_y, b.Bytes()) | ||
|
||
if curve.IsOnCurve(a_x, a_y) == false { | ||
return | ||
} | ||
|
||
res := make([]string, 2) | ||
res[0], res[1] = res_x.String(), res_y.String() | ||
|
||
r2, err := json.Marshal(&res) | ||
if err != nil { | ||
panic("Cannot marshal to JSON") | ||
} | ||
|
||
result = r2 | ||
} | ||
|
||
//export circl_Cryptofuzz_OpECC_Point_Dbl | ||
func circl_Cryptofuzz_OpECC_Point_Dbl(in []byte) { | ||
resetResult() | ||
|
||
var op OpECC_Point_Dbl | ||
unmarshal(in, &op) | ||
|
||
if !issecp384r1(op.CurveType) { | ||
return | ||
} | ||
|
||
curve := p384.P384() | ||
|
||
a_x := decodeBignum(op.A_x) | ||
a_y := decodeBignum(op.A_y) | ||
|
||
res_x, res_y := curve.Double(a_x, a_y) | ||
|
||
if curve.IsOnCurve(a_x, a_y) == false { | ||
return | ||
} | ||
|
||
res := make([]string, 2) | ||
res[0], res[1] = res_x.String(), res_y.String() | ||
|
||
r2, err := json.Marshal(&res) | ||
if err != nil { | ||
panic("Cannot marshal to JSON") | ||
} | ||
|
||
result = r2 | ||
} | ||
|
||
func main() { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include <cstdint> | ||
#include <cstddef> | ||
#include <stdio.h> | ||
#include <regex> | ||
#include <fuzzing/datasource/id.hpp> | ||
#include "../../repository_map.h" | ||
|
||
int main(void) | ||
{ | ||
FILE* fp = fopen("ids.go", "wb"); | ||
fprintf(fp, "package main\n"); | ||
for (const auto& digest : DigestLUTMap ) { | ||
auto digestStr = std::string(digest.second.name); | ||
digestStr = std::regex_replace(digestStr, std::regex("[.-]"), "_"); | ||
fprintf(fp, "func is%s(id Type) bool { return id == %s }\n", digestStr.c_str(), std::to_string(digest.first).c_str()); | ||
} | ||
for (const auto& cipher : CipherLUTMap ) { | ||
auto cipherStr = std::string(cipher.second.name); | ||
cipherStr = std::regex_replace(cipherStr, std::regex("[.-]"), "_"); | ||
if ( cipherStr == "GOST_28147_89" ) { | ||
/* XXX */ | ||
continue; | ||
} | ||
fprintf(fp, "func is%s(id Type) bool { return id == %s }\n", cipherStr.c_str(), std::to_string(cipher.first).c_str()); | ||
} | ||
for (const auto& curve : ECC_CurveLUTMap ) { | ||
auto curveStr = std::string(curve.second.name); | ||
curveStr = std::regex_replace(curveStr, std::regex("[.-]"), "_"); | ||
fprintf(fp, "func is%s(id Type) bool { return id == %s }\n", curveStr.c_str(), std::to_string(curve.first).c_str()); | ||
} | ||
for (const auto& bnOp : CalcOpLUTMap ) { | ||
auto bnOpStr = std::string(bnOp.second.name); | ||
bnOpStr = std::regex_replace(bnOpStr, std::regex("\\(.*"), ""); | ||
fprintf(fp, "func is%s(id Type) bool { return id == %s }\n", bnOpStr.c_str(), std::to_string(bnOp.first).c_str()); | ||
} | ||
fclose(fp); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include "module.h" | ||
#include <cryptofuzz/util.h> | ||
#include <cryptofuzz/repository.h> | ||
#include <fuzzing/datasource/id.hpp> | ||
#include <boost/lexical_cast.hpp> | ||
|
||
extern "C" { | ||
#include "cryptofuzz.h" | ||
} | ||
|
||
namespace cryptofuzz { | ||
namespace module { | ||
|
||
circl::circl(void) : | ||
Module("circl") { | ||
} | ||
|
||
std::string circl::getResult(void) const { | ||
auto res = circl_Cryptofuzz_GetResult(); | ||
std::string ret(res); | ||
free(res); | ||
return ret; | ||
} | ||
|
||
std::optional<nlohmann::json> circl::getJsonResult(void) const { | ||
const auto res = getResult(); | ||
if ( res.empty() ) { | ||
return std::nullopt; | ||
} | ||
|
||
try { | ||
return nlohmann::json::parse(getResult()); | ||
} catch ( std::exception e ) { | ||
/* Must always parse correctly non-empty strings */ | ||
abort(); | ||
} | ||
} | ||
|
||
template <class T> std::optional<T> circl::getResultAs(void) const { | ||
std::optional<T> ret = std::nullopt; | ||
|
||
auto j = getJsonResult(); | ||
if ( j != std::nullopt ) { | ||
ret = T(*j); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static GoSlice toGoSlice(std::string& in) { | ||
return {in.data(), static_cast<GoInt>(in.size()), static_cast<GoInt>(in.size())}; | ||
} | ||
|
||
std::optional<component::ECC_Point> circl::OpECC_Point_Add(operation::ECC_Point_Add& op) { | ||
auto jsonStr = op.ToJSON().dump(); | ||
circl_Cryptofuzz_OpECC_Point_Add(toGoSlice(jsonStr)); | ||
|
||
return getResultAs<component::ECC_Point>(); | ||
} | ||
|
||
std::optional<component::ECC_Point> circl::OpECC_Point_Mul(operation::ECC_Point_Mul& op) { | ||
auto jsonStr = op.ToJSON().dump(); | ||
circl_Cryptofuzz_OpECC_Point_Mul(toGoSlice(jsonStr)); | ||
|
||
return getResultAs<component::ECC_Point>(); | ||
} | ||
|
||
std::optional<component::ECC_Point> circl::OpECC_Point_Dbl(operation::ECC_Point_Dbl& op) { | ||
auto jsonStr = op.ToJSON().dump(); | ||
circl_Cryptofuzz_OpECC_Point_Dbl(toGoSlice(jsonStr)); | ||
|
||
return getResultAs<component::ECC_Point>(); | ||
} | ||
|
||
} /* namespace module */ | ||
} /* namespace cryptofuzz */ |
Oops, something went wrong.