-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
641 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# @devicescript/crypto | ||
|
||
[DeviceScript](https://microsoft.github.io/devicescript/) cryptographic algorithms (AES, SHA) support. | ||
|
||
- [Read documentation](https://microsoft.github.io/devicescript/developer/crypto) | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! See [contributing page](../../CONTRIBUTING.md). | ||
|
||
## Trademarks | ||
|
||
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft | ||
trademarks or logos is subject to and must follow | ||
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). | ||
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. | ||
Any use of third-party trademarks or logos are subject to those third-party's policies. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "@devicescript/crypto", | ||
"version": "2.12.1", | ||
"private": true, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@devicescript/cli": "*" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/microsoft/devicescript.git", | ||
"directory": "packages/crypto" | ||
}, | ||
"scripts": { | ||
"setup": "devicescript build", | ||
"build:devicescript": "devicescript build src/main.ts -F allFunctions", | ||
"build": "yarn build:devicescript", | ||
"watch:devicescript": "devicescript devtools src/main.ts", | ||
"watch": "yarn watch:devicescript", | ||
"test:devicescript": "devicescript run src/main.ts --test --test-self-exit -F allFunctions", | ||
"test": "yarn test:devicescript", | ||
"start": "yarn watch" | ||
}, | ||
"main": "./src/index.ts", | ||
"license": "MIT", | ||
"devicescript": { | ||
"bundle": true, | ||
"library": true | ||
}, | ||
"files": [ | ||
"src/*.ts", | ||
"devsconfig.json" | ||
], | ||
"keywords": [ | ||
"devicescript" | ||
], | ||
"author": "Microsoft", | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import * as ds from "@devicescript/core" | ||
|
||
export type SymmetricAlgorithm = "aes-256-ccm" | ||
export type HashAlgorithm = "sha256" | ||
|
||
export interface CipherOptions { | ||
/** | ||
* Data to be encrypted or decrypted. | ||
*/ | ||
data: Buffer | ||
|
||
/** | ||
* Algorithm to use. | ||
*/ | ||
algo: SymmetricAlgorithm | ||
|
||
/** | ||
* Key, has to be of the right size for the algorithm. | ||
* For AES256 key length is 256 bits, so 32 bytes. | ||
* @see keySize() | ||
*/ | ||
key: Buffer | ||
|
||
/** | ||
* Nonce/initialization vector - use a random one for every message! | ||
* For AES-CCM this is 13 bytes. | ||
* @see ivSize() | ||
*/ | ||
iv: Buffer | ||
|
||
/** | ||
* For authenticated encryption, the length of the tag that is appended at the end of the cipher-text. | ||
*/ | ||
tagLength: 0 | 4 | 8 | 16 | ||
} | ||
|
||
/** | ||
* Return the expected key buffer size for a given algorithm. | ||
*/ | ||
export function keySize(algo: SymmetricAlgorithm) { | ||
if (algo === "aes-256-ccm") return 32 | ||
return undefined | ||
} | ||
|
||
/** | ||
* Return the expected IV (nonce) buffer size for a given algorithm. | ||
*/ | ||
export function ivSize(algo: SymmetricAlgorithm) { | ||
if (algo === "aes-256-ccm") return 13 | ||
return undefined | ||
} | ||
|
||
function expectBuffer(v: Buffer, lbl: string, len?: number) { | ||
if (!(v instanceof Buffer)) | ||
throw new TypeError(`expecting ${lbl} buffer, got ${v}`) | ||
if (len !== undefined && v.length !== len) | ||
throw new TypeError( | ||
`expecting ${lbl} buffer to be ${len}, not ${v.length}` | ||
) | ||
} | ||
|
||
function validateOptions(options: CipherOptions) { | ||
const { algo } = options | ||
if (algo !== "aes-256-ccm") | ||
throw new TypeError(`invalid symm algo: ${options.algo}`) | ||
expectBuffer(options.data, "data") | ||
expectBuffer(options.key, "key", keySize(algo)) | ||
expectBuffer(options.iv, "iv", ivSize(algo)) | ||
switch (options.tagLength) { | ||
case 0: | ||
case 4: | ||
case 8: | ||
case 16: | ||
break | ||
default: | ||
throw new TypeError(`invalid tagLength ${options.tagLength}`) | ||
} | ||
} | ||
|
||
/** | ||
* Encrypt a plain text buffer. | ||
*/ | ||
export function encrypt(options: CipherOptions): Buffer { | ||
validateOptions(options) | ||
return (options.data as any).encrypt( | ||
options.algo, | ||
options.key, | ||
options.iv, | ||
options.tagLength | ||
) | ||
} | ||
|
||
/** | ||
* Decrypt a cipher-text buffer. | ||
*/ | ||
export function decrypt(options: CipherOptions): Buffer { | ||
validateOptions(options) | ||
return (options.data as any).encrypt( | ||
options.algo, | ||
options.key, | ||
options.iv, | ||
0x1000 + options.tagLength | ||
) | ||
} | ||
|
||
/** | ||
* Fill buffer with cryptographically strong random values | ||
*/ | ||
export function getRandom(size: number): Buffer { | ||
const r = Buffer.alloc(size) | ||
;(r as any).fillRandom() | ||
return r | ||
} | ||
|
||
function validateHash(algo: HashAlgorithm) { | ||
if (algo !== "sha256") throw new TypeError(`invalid hash: ${algo}`) | ||
} | ||
|
||
/** | ||
* Compute digest (hash) of the concatenation of the specified buffers. | ||
*/ | ||
export function digest(algo: HashAlgorithm, ...data: Buffer[]): Buffer { | ||
validateHash(algo) | ||
return (Buffer as any).digest(undefined, algo, data) | ||
} | ||
|
||
/** | ||
* Compute HMAC digest (authenticated hash) of the concatenation of the specified buffers. | ||
*/ | ||
export function hmac( | ||
key: Buffer, | ||
algo: HashAlgorithm, | ||
...data: Buffer[] | ||
): Buffer { | ||
validateHash(algo) | ||
expectBuffer(key, "key") | ||
return (Buffer as any).digest(key, algo, data) | ||
} | ||
|
||
export function sha256Hkdf( | ||
salt: Buffer, | ||
key: Buffer, | ||
info: Buffer, | ||
info2: Buffer = hex`` | ||
) { | ||
const outkey = hmac(salt, "sha256", key) | ||
return hmac(outkey, "sha256", info, info2, hex`01`) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./crypto" |
Oops, something went wrong.