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