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