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