commit 10f5cee39b8d9ba271e9ffc4bda209a0318ca7b4
parent b8ccc9bb5529e8976db74ed567884c80cb95f62f
Author: sin <sin@2f30.org>
Date: Tue, 30 Apr 2013 11:34:07 +0100
add blowfish encryption to mapfs
Diffstat:
2 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/src/mapfs/mapfs.go b/src/mapfs/mapfs.go
@@ -3,6 +3,7 @@ package mapfs
import (
"bytes"
+ "code.google.com/p/go.crypto/blowfish"
"fmt"
"math/rand"
"os"
@@ -19,6 +20,8 @@ type Mapfs struct {
dict map[int]mapfsVal
lock sync.Mutex
cacheOnly bool
+ encrypt bool
+ cipher *blowfish.Cipher
}
type mapfsVal struct {
@@ -37,6 +40,11 @@ func MakeMapIter(m *Mapfs) MapIter {
v, ok := m.dict[i]
if ok {
i++
+ if m.encrypt {
+ pt := make([]byte, len(v.data))
+ m.cipher.Decrypt(pt, v.data)
+ return i - 1, pt, true
+ }
return i - 1, v.data, true
}
i++
@@ -52,9 +60,25 @@ func NewMapfs(name string, path string, prefix string) *Mapfs {
prefix: prefix,
dict: make(map[int]mapfsVal),
cacheOnly: false,
+ encrypt: false,
+ cipher: nil,
}
}
+func NewEncryptedMapfs(name string, path string, prefix string, key string) *Mapfs {
+ c, _ := blowfish.NewCipher([]byte(key))
+ return &Mapfs{
+ name: name,
+ path: path,
+ prefix: prefix,
+ dict: make(map[int]mapfsVal),
+ cacheOnly: false,
+ encrypt: true,
+ cipher: c,
+ }
+
+}
+
// Sync dirty entries to disk
func (m *Mapfs) Sync() error {
m.lock.Lock()
@@ -69,8 +93,13 @@ func (m *Mapfs) Sync() error {
return err
}
m.dict[k] = mapfsVal{false, v.data}
- fmt.Printf("Synced entry (%d, %v)\n",
- k, v.data)
+ if !m.encrypt {
+ fmt.Printf("Synced entry (%d, %v)\n",
+ k, v.data)
+ } else {
+ fmt.Printf("Synced entry (%d, %v)\n",
+ k, "ENCRYPTED")
+ }
}
}
return nil
@@ -151,8 +180,13 @@ func (m *Mapfs) CountMatches(buf []byte) int {
m.lock.Lock()
defer m.lock.Unlock()
i := 0
+ raw := buf
+ if m.encrypt {
+ ct := m.encryptbuf(buf)
+ raw = ct
+ }
for _, v := range m.dict {
- if bytes.Equal(v.data, buf) {
+ if bytes.Equal(v.data, raw) {
i++
}
}
@@ -169,6 +203,11 @@ func (m *Mapfs) Put(key int, buf []byte) error {
if ok {
return fmt.Errorf("Key %d already in use", key)
}
+ if m.encrypt {
+ ct := m.encryptbuf(buf)
+ m.dict[key] = mapfsVal{true, ct}
+ return nil
+ }
m.dict[key] = mapfsVal{true, buf}
return nil
}
@@ -177,6 +216,13 @@ func (m *Mapfs) Put(key int, buf []byte) error {
func (m *Mapfs) Append(buf []byte) (int, error) {
m.lock.Lock()
defer m.lock.Unlock()
+ if m.encrypt {
+ ct := m.encryptbuf(buf)
+ key := len(m.dict)
+ m.dict[key] = mapfsVal{true, ct}
+ return key, nil
+ }
+
key := len(m.dict)
m.dict[key] = mapfsVal{true, buf}
return key, nil
@@ -193,6 +239,10 @@ func (m *Mapfs) Get(key int) ([]byte, error) {
if !ok {
return nil, fmt.Errorf("No entry with key: %d", key)
}
+ if m.encrypt {
+ pt := m.decryptbuf(val.data)
+ return pt, nil
+ }
return val.data, nil
}
@@ -204,6 +254,10 @@ func (m *Mapfs) Rand() ([]byte, int) {
for k, _ := range m.dict {
if i == idx {
val := m.dict[k]
+ if m.encrypt {
+ pt := m.decryptbuf(val.data)
+ return pt, k
+ }
return val.data, k
}
i++
@@ -225,3 +279,32 @@ func (m *Mapfs) Len() int {
defer m.lock.Unlock()
return len(m.dict)
}
+
+func (m *Mapfs) encryptbuf(a []byte) []byte {
+ //pad it
+ padded := a
+ diff := len(a) % blowfish.BlockSize
+ if diff != 0 {
+ diff = blowfish.BlockSize - diff
+ }
+ for i := 0; i < diff; i++ {
+ padded = append(padded, byte(0x0))
+ }
+ ct := make([]byte, len(padded))
+ for i := 0; i < len(a); i += blowfish.BlockSize {
+ if i+blowfish.BlockSize > len(a) {
+ m.cipher.Encrypt(ct[i:], padded[i:])
+ return ct
+ }
+ m.cipher.Encrypt(ct[i:i+blowfish.BlockSize], padded[i:i+blowfish.BlockSize])
+ }
+ return ct
+}
+
+func (m *Mapfs) decryptbuf(a []byte) []byte {
+ pt := make([]byte, len(a))
+ for i := 0; i < len(a); i += blowfish.BlockSize {
+ m.cipher.Decrypt(pt[i:i+blowfish.BlockSize], a[i:i+blowfish.BlockSize])
+ }
+ return pt
+}
diff --git a/src/mapfs/mapfs_test.go b/src/mapfs/mapfs_test.go
@@ -0,0 +1,15 @@
+package mapfs
+
+import (
+ "testing"
+)
+
+func TestEncryptingFs(t *testing.T) {
+ mfs := NewEncryptedMapfs("kota", "./", "moufa", "ICEBABY!@#")
+ test := []byte("sweet plaintext!") //this test will only work without padding
+ mfs.Append(test)
+ r0, _ := mfs.Get(0)
+ if string(r0) != string(test) { //byte equality will fail here(padding)
+ t.Error("encryption failed got:" + string(r0))
+ }
+}