subtle_wasm.mx raw
1 //:build wasm
2
3 package subtle
4
5 import (
6 "crypto/aes"
7 "crypto/cipher"
8 "crypto/hmac"
9 "crypto/pbkdf2"
10 "crypto/sha256"
11 "crypto/sha512"
12 "unsafe"
13 "vendor/golang.org/x/crypto/argon2"
14
15 "git.smesh.lol/nostr/pkg/crypto/aes256gcm"
16 )
17
18 //:wasmimport bridge subtle_random_bytes
19 func wasmRandomBytes(ptr *byte, length int32, capacity int32)
20
21 func RandomBytes(dst []byte) {
22 wasmRandomBytes(unsafe.StringData(dst), int32(len(dst)), int32(cap(dst)))
23 }
24
25 func AESCBCEncrypt(key, iv, plaintext []byte) (buf []byte) {
26 block, err := aes.NewCipher(key)
27 if err != nil {
28 return nil
29 }
30 padded := pkcs7Pad(plaintext, aes.BlockSize)
31 ct := []byte{:len(padded)}
32 cipher.NewCBCEncrypter(block, iv).CryptBlocks(ct, padded)
33 return ct
34 }
35
36 func AESCBCDecrypt(key, iv, ciphertext []byte) (buf []byte) {
37 block, err := aes.NewCipher(key)
38 if err != nil {
39 return nil
40 }
41 pt := []byte{:len(ciphertext)}
42 cipher.NewCBCDecrypter(block, iv).CryptBlocks(pt, ciphertext)
43 return pkcs7Unpad(pt, aes.BlockSize)
44 }
45
46 func AESGCMEncrypt(key, iv, plaintext []byte) (buf []byte) {
47 return aes256gcm.Seal(key, iv, plaintext, nil)
48 }
49
50 func AESGCMDecrypt(key, iv, ciphertext []byte) (buf []byte) {
51 pt, ok := aes256gcm.Open(key, iv, ciphertext, nil)
52 if !ok {
53 return nil
54 }
55 return pt
56 }
57
58 func PBKDF2DeriveKey(password string, salt []byte, iterations int32) (buf []byte) {
59 dk, _ := pbkdf2.Key(sha256.New, []byte(password), salt, iterations, 32)
60 return dk
61 }
62
63 func Argon2idDeriveKey(password string, salt []byte, t, m, p, dkLen int32) (buf []byte) {
64 return argon2.IDKey([]byte(password), salt, uint32(t), uint32(m), uint8(p), uint32(dkLen))
65 }
66
67 func SHA256Hex(data []byte) (s string) {
68 return sha256.SumHex(data)
69 }
70
71 func HMACSHA512(key, data []byte) (buf []byte) {
72 mac := hmac.New(sha512.New, key)
73 mac.Write(data)
74 return mac.Sum(nil)
75 }
76
77 func PBKDF2SHA512(password string, salt []byte, iterations, dkLen int32) (buf []byte) {
78 dk, _ := pbkdf2.Key(sha512.New, []byte(password), salt, iterations, dkLen)
79 return dk
80 }
81
82 func pkcs7Pad(data []byte, blockSize int32) (buf []byte) {
83 pad := blockSize - len(data)%blockSize
84 out := []byte{:0:len(data) + pad}
85 out = out | data
86 for i := 0; i < pad; i++ {
87 out = push(out, byte(pad))
88 }
89 return out
90 }
91
92 func pkcs7Unpad(data []byte, blockSize int32) (buf []byte) {
93 if len(data) == 0 {
94 return nil
95 }
96 pad := int32(data[len(data)-1])
97 if pad > blockSize || pad == 0 || pad > len(data) {
98 return nil
99 }
100 for i := len(data) - pad; i < len(data); i++ {
101 if int32(data[i]) != pad {
102 return nil
103 }
104 }
105 return data[:len(data)-pad]
106 }
107