mirror of
https://github.com/libp2p/go-openssl.git
synced 2024-12-25 23:30:06 +08:00
add m4 and m5 wrappers (#104)
This commit is contained in:
parent
0ffbced908
commit
543df27fc7
1
cert.go
1
cert.go
@ -31,6 +31,7 @@ type EVP_MD int
|
||||
const (
|
||||
EVP_NULL EVP_MD = iota
|
||||
EVP_MD5 EVP_MD = iota
|
||||
EVP_MD4 EVP_MD = iota
|
||||
EVP_SHA EVP_MD = iota
|
||||
EVP_SHA1 EVP_MD = iota
|
||||
EVP_DSS EVP_MD = iota
|
||||
|
89
md4.go
Normal file
89
md4.go
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (C) 2017. See AUTHORS.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package openssl
|
||||
|
||||
// #include "shim.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type MD4Hash struct {
|
||||
ctx *C.EVP_MD_CTX
|
||||
engine *Engine
|
||||
}
|
||||
|
||||
func NewMD4Hash() (*MD4Hash, error) { return NewMD4HashWithEngine(nil) }
|
||||
|
||||
func NewMD4HashWithEngine(e *Engine) (*MD4Hash, error) {
|
||||
hash := &MD4Hash{engine: e}
|
||||
hash.ctx = C.X_EVP_MD_CTX_new()
|
||||
if hash.ctx == nil {
|
||||
return nil, errors.New("openssl: md4: unable to allocate ctx")
|
||||
}
|
||||
runtime.SetFinalizer(hash, func(hash *MD4Hash) { hash.Close() })
|
||||
if err := hash.Reset(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hash, nil
|
||||
}
|
||||
|
||||
func (s *MD4Hash) Close() {
|
||||
if s.ctx != nil {
|
||||
C.X_EVP_MD_CTX_free(s.ctx)
|
||||
s.ctx = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MD4Hash) Reset() error {
|
||||
if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md4(), engineRef(s.engine)) {
|
||||
return errors.New("openssl: md4: cannot init digest ctx")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MD4Hash) Write(p []byte) (n int, err error) {
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]),
|
||||
C.size_t(len(p))) {
|
||||
return 0, errors.New("openssl: md4: cannot update digest")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (s *MD4Hash) Sum() (result [16]byte, err error) {
|
||||
if 1 != C.X_EVP_DigestFinal_ex(s.ctx,
|
||||
(*C.uchar)(unsafe.Pointer(&result[0])), nil) {
|
||||
return result, errors.New("openssl: md4: cannot finalize ctx")
|
||||
}
|
||||
return result, s.Reset()
|
||||
}
|
||||
|
||||
func MD4(data []byte) (result [16]byte, err error) {
|
||||
hash, err := NewMD4Hash()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer hash.Close()
|
||||
if _, err := hash.Write(data); err != nil {
|
||||
return result, err
|
||||
}
|
||||
return hash.Sum()
|
||||
}
|
120
md4_test.go
Normal file
120
md4_test.go
Normal file
@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2017. See AUTHORS.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package openssl
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"golang.org/x/crypto/md4"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMD4(t *testing.T) {
|
||||
for i := 0; i < 100; i++ {
|
||||
buf := make([]byte, 10*1024-i)
|
||||
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := [16]byte{}
|
||||
md4Ctx := md4.New()
|
||||
md4Ctx.Write(buf)
|
||||
copy(expected[:], md4Ctx.Sum(nil))
|
||||
got, err := MD4(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if expected != got {
|
||||
t.Fatalf("exp:%x got:%x", expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMD4Writer(t *testing.T) {
|
||||
ohash, err := NewMD4Hash()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash := md4.New()
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
if err := ohash.Reset(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash.Reset()
|
||||
buf := make([]byte, 10*1024-i)
|
||||
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := ohash.Write(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := hash.Write(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var got, exp [16]byte
|
||||
|
||||
hash.Sum(exp[:0])
|
||||
got, err := ohash.Sum()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if got != exp {
|
||||
t.Fatalf("exp:%x got:%x", exp, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type md4func func([]byte)
|
||||
|
||||
func benchmarkMD4(b *testing.B, length int64, fn md4func) {
|
||||
buf := make([]byte, length)
|
||||
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(length)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
fn(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMD4Large_openssl(b *testing.B) {
|
||||
benchmarkMD4(b, 1024*1024, func(buf []byte) { MD4(buf) })
|
||||
}
|
||||
|
||||
func BenchmarkMD4Large_stdlib(b *testing.B) {
|
||||
benchmarkMD4(b, 1024*1024, func(buf []byte) {
|
||||
md4Ctx := md4.New()
|
||||
md4Ctx.Write(buf)
|
||||
md4Ctx.Sum(nil)
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkMD4Small_openssl(b *testing.B) {
|
||||
benchmarkMD4(b, 1, func(buf []byte) { MD4(buf) })
|
||||
}
|
||||
|
||||
func BenchmarkMD4Small_stdlib(b *testing.B) {
|
||||
benchmarkMD4(b, 1, func(buf []byte) {
|
||||
md4Ctx := md4.New()
|
||||
md4Ctx.Write(buf)
|
||||
md4Ctx.Sum(nil)
|
||||
})
|
||||
}
|
89
md5.go
Normal file
89
md5.go
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (C) 2017. See AUTHORS.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package openssl
|
||||
|
||||
// #include "shim.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type MD5Hash struct {
|
||||
ctx *C.EVP_MD_CTX
|
||||
engine *Engine
|
||||
}
|
||||
|
||||
func NewMD5Hash() (*MD5Hash, error) { return NewMD5HashWithEngine(nil) }
|
||||
|
||||
func NewMD5HashWithEngine(e *Engine) (*MD5Hash, error) {
|
||||
hash := &MD5Hash{engine: e}
|
||||
hash.ctx = C.X_EVP_MD_CTX_new()
|
||||
if hash.ctx == nil {
|
||||
return nil, errors.New("openssl: md5: unable to allocate ctx")
|
||||
}
|
||||
runtime.SetFinalizer(hash, func(hash *MD5Hash) { hash.Close() })
|
||||
if err := hash.Reset(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hash, nil
|
||||
}
|
||||
|
||||
func (s *MD5Hash) Close() {
|
||||
if s.ctx != nil {
|
||||
C.X_EVP_MD_CTX_free(s.ctx)
|
||||
s.ctx = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MD5Hash) Reset() error {
|
||||
if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md5(), engineRef(s.engine)) {
|
||||
return errors.New("openssl: md5: cannot init digest ctx")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MD5Hash) Write(p []byte) (n int, err error) {
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]),
|
||||
C.size_t(len(p))) {
|
||||
return 0, errors.New("openssl: md5: cannot update digest")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (s *MD5Hash) Sum() (result [16]byte, err error) {
|
||||
if 1 != C.X_EVP_DigestFinal_ex(s.ctx,
|
||||
(*C.uchar)(unsafe.Pointer(&result[0])), nil) {
|
||||
return result, errors.New("openssl: md5: cannot finalize ctx")
|
||||
}
|
||||
return result, s.Reset()
|
||||
}
|
||||
|
||||
func MD5(data []byte) (result [16]byte, err error) {
|
||||
hash, err := NewMD5Hash()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer hash.Close()
|
||||
if _, err := hash.Write(data); err != nil {
|
||||
return result, err
|
||||
}
|
||||
return hash.Sum()
|
||||
}
|
109
md5_test.go
Normal file
109
md5_test.go
Normal file
@ -0,0 +1,109 @@
|
||||
// Copyright (C) 2017. See AUTHORS.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package openssl
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMD5(t *testing.T) {
|
||||
for i := 0; i < 100; i++ {
|
||||
buf := make([]byte, 10*1024-i)
|
||||
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := md5.Sum(buf)
|
||||
got, err := MD5(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if expected != got {
|
||||
t.Fatalf("exp:%x got:%x", expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMD5Writer(t *testing.T) {
|
||||
ohash, err := NewMD5Hash()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash := md5.New()
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
if err := ohash.Reset(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash.Reset()
|
||||
buf := make([]byte, 10*1024-i)
|
||||
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := ohash.Write(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := hash.Write(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var got, exp [16]byte
|
||||
|
||||
hash.Sum(exp[:0])
|
||||
got, err := ohash.Sum()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if got != exp {
|
||||
t.Fatalf("exp:%x got:%x", exp, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type md5func func([]byte)
|
||||
|
||||
func benchmarkMD5(b *testing.B, length int64, fn md5func) {
|
||||
buf := make([]byte, length)
|
||||
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(length)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
fn(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMD5Large_openssl(b *testing.B) {
|
||||
benchmarkMD5(b, 1024*1024, func(buf []byte) { MD5(buf) })
|
||||
}
|
||||
|
||||
func BenchmarkMD5Large_stdlib(b *testing.B) {
|
||||
benchmarkMD5(b, 1024*1024, func(buf []byte) { md5.Sum(buf) })
|
||||
}
|
||||
|
||||
func BenchmarkMD5Small_openssl(b *testing.B) {
|
||||
benchmarkMD5(b, 1, func(buf []byte) { MD5(buf) })
|
||||
}
|
||||
|
||||
func BenchmarkMD5Small_stdlib(b *testing.B) {
|
||||
benchmarkMD5(b, 1, func(buf []byte) { md5.Sum(buf) })
|
||||
}
|
4
shim.c
4
shim.c
@ -602,6 +602,10 @@ const EVP_MD *X_EVP_md5() {
|
||||
return EVP_md5();
|
||||
}
|
||||
|
||||
const EVP_MD *X_EVP_md4() {
|
||||
return EVP_md4();
|
||||
}
|
||||
|
||||
const EVP_MD *X_EVP_ripemd160() {
|
||||
return EVP_ripemd160();
|
||||
}
|
||||
|
1
shim.h
1
shim.h
@ -109,6 +109,7 @@ extern EVP_MD_CTX *X_EVP_MD_CTX_new();
|
||||
extern void X_EVP_MD_CTX_free(EVP_MD_CTX *ctx);
|
||||
extern const EVP_MD *X_EVP_md_null();
|
||||
extern const EVP_MD *X_EVP_md5();
|
||||
extern const EVP_MD *X_EVP_md4();
|
||||
extern const EVP_MD *X_EVP_sha();
|
||||
extern const EVP_MD *X_EVP_sha1();
|
||||
extern const EVP_MD *X_EVP_dss();
|
||||
|
Loading…
Reference in New Issue
Block a user