Skip to content
Snippets Groups Projects
Commit 0223438f authored by Donald Stufft's avatar Donald Stufft
Browse files

Port the crypto_secretbox implementation to the new layout

parent 2a35b6b3
No related branches found
No related tags found
No related merge requests found
/* Copyright 2013 Donald Stufft and individual contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
size_t crypto_secretbox_keybytes();
size_t crypto_secretbox_noncebytes();
size_t crypto_secretbox_zerobytes();
size_t crypto_secretbox_boxzerobytes();
int crypto_secretbox(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
int crypto_secretbox_open(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k);
...@@ -23,6 +23,11 @@ from nacl.c.crypto_scalarmult import ( ...@@ -23,6 +23,11 @@ from nacl.c.crypto_scalarmult import (
crypto_scalarmult_BYTES, crypto_scalarmult_SCALARBYTES, crypto_scalarmult_BYTES, crypto_scalarmult_SCALARBYTES,
crypto_scalarmult_base, crypto_scalarmult_base,
) )
from nacl.c.crypto_secretbox import (
crypto_secretbox_KEYBYTES, crypto_secretbox_NONCEBYTES,
crypto_secretbox_ZEROBYTES, crypto_secretbox_BOXZEROBYTES,
crypto_secretbox, crypto_secretbox_open,
)
from nacl.c.randombytes import randombytes from nacl.c.randombytes import randombytes
...@@ -44,5 +49,12 @@ __all__ = [ ...@@ -44,5 +49,12 @@ __all__ = [
"crypto_scalarmult_SCALARBYTES", "crypto_scalarmult_SCALARBYTES",
"crypto_scalarmult_base", "crypto_scalarmult_base",
"crypto_secretbox_KEYBYTES",
"crypto_secretbox_NONCEBYTES",
"crypto_secretbox_ZEROBYTES",
"crypto_secretbox_BOXZEROBYTES",
"crypto_secretbox",
"crypto_secretbox_open",
"randombytes", "randombytes",
] ]
# Copyright 2013 Donald Stufft and individual contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, division, print_function
from nacl import _lib as lib
from nacl.exceptions import CryptoError
crypto_secretbox_KEYBYTES = lib.crypto_secretbox_keybytes()
crypto_secretbox_NONCEBYTES = lib.crypto_secretbox_noncebytes()
crypto_secretbox_ZEROBYTES = lib.crypto_secretbox_zerobytes()
crypto_secretbox_BOXZEROBYTES = lib.crypto_secretbox_boxzerobytes()
def crypto_secretbox(key, message, nonce):
"""
Encrypts and returns the message ``message`` with the secret ``key`` and
the nonce ``nonce``.
:param key: bytes
:param message: bytes
:param nonce: bytes
:rtype: bytes
"""
if len(key) != crypto_secretbox_KEYBYTES:
raise ValueError("Invalid key")
if len(nonce) != crypto_secretbox_NONCEBYTES:
raise ValueError("Invalid nonce")
padded = b"\x00" * crypto_secretbox_ZEROBYTES + message
ciphertext = lib.ffi.new("unsigned char[]", len(padded))
if lib.crypto_secretbox(ciphertext, padded, len(padded), nonce, key) != 0:
raise CryptoError("Encryption failed")
ciphertext = lib.ffi.buffer(ciphertext, len(padded))
return ciphertext[crypto_secretbox_BOXZEROBYTES:]
def crypto_secretbox_open(key, ciphertext, nonce):
"""
Decrypt and returns the encrypted message ``ciphertext`` with the secret
``key`` and the nonce ``nonce``.
:param key: bytes
:param ciphertext: bytes
:param nonce: bytes
:rtype: bytes
"""
if len(key) != crypto_secretbox_KEYBYTES:
raise ValueError("Invalid key")
if len(nonce) != crypto_secretbox_NONCEBYTES:
raise ValueError("Invalid nonce")
padded = b"\x00" * crypto_secretbox_BOXZEROBYTES + ciphertext
plaintext = lib.ffi.new("unsigned char[]", len(padded))
if lib.crypto_secretbox_open(
plaintext, padded, len(padded), nonce, key) != 0:
raise CryptoError("Decryption failed. Ciphertext failed verification")
plaintext = lib.ffi.buffer(plaintext, len(padded))
return plaintext[crypto_secretbox_ZEROBYTES:]
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import division from __future__ import division
import nacl.c
from . import encoding from . import encoding
from .c import _lib as nacl
from .exceptions import CryptoError
from .utils import EncryptedMessage, StringFixer from .utils import EncryptedMessage, StringFixer
...@@ -40,8 +40,8 @@ class SecretBox(encoding.Encodable, StringFixer, object): ...@@ -40,8 +40,8 @@ class SecretBox(encoding.Encodable, StringFixer, object):
:cvar NONCE_SIZE: The size that the nonce is required to be. :cvar NONCE_SIZE: The size that the nonce is required to be.
""" """
KEY_SIZE = nacl.lib.crypto_secretbox_KEYBYTES KEY_SIZE = nacl.c.crypto_secretbox_KEYBYTES
NONCE_SIZE = nacl.lib.crypto_secretbox_NONCEBYTES NONCE_SIZE = nacl.c.crypto_secretbox_NONCEBYTES
def __init__(self, key, encoder=encoding.RawEncoder): def __init__(self, key, encoder=encoding.RawEncoder):
key = encoder.decode(key) key = encoder.decode(key)
...@@ -73,18 +73,9 @@ class SecretBox(encoding.Encodable, StringFixer, object): ...@@ -73,18 +73,9 @@ class SecretBox(encoding.Encodable, StringFixer, object):
""" """
if len(nonce) != self.NONCE_SIZE: if len(nonce) != self.NONCE_SIZE:
raise ValueError("The nonce must be exactly %s bytes long" % raise ValueError("The nonce must be exactly %s bytes long" %
nacl.lib.crypto_secretbox_NONCEBYTES) self.NONCE_SIZE)
padded = b"\x00" * nacl.lib.crypto_secretbox_ZEROBYTES + plaintext
ciphertext = nacl.ffi.new("unsigned char[]", len(padded))
if not nacl.lib.crypto_secretbox(
ciphertext, padded, len(padded), nonce, self._key,
):
raise CryptoError("Encryption failed")
box_zeros = nacl.lib.crypto_secretbox_BOXZEROBYTES ciphertext = nacl.c.crypto_secretbox(self._key, plaintext, nonce)
ciphertext = nacl.ffi.buffer(ciphertext, len(padded))[box_zeros:]
encoded_nonce = encoder.encode(nonce) encoded_nonce = encoder.encode(nonce)
encoded_ciphertext = encoder.encode(ciphertext) encoded_ciphertext = encoder.encode(ciphertext)
...@@ -116,18 +107,8 @@ class SecretBox(encoding.Encodable, StringFixer, object): ...@@ -116,18 +107,8 @@ class SecretBox(encoding.Encodable, StringFixer, object):
if len(nonce) != self.NONCE_SIZE: if len(nonce) != self.NONCE_SIZE:
raise ValueError("The nonce must be exactly %s bytes long" % raise ValueError("The nonce must be exactly %s bytes long" %
nacl.lib.crypto_secretbox_NONCEBYTES) self.NONCE_SIZE)
padded = b"\x00" * nacl.lib.crypto_secretbox_BOXZEROBYTES + ciphertext
plaintext = nacl.ffi.new("unsigned char[]", len(padded))
if not nacl.lib.crypto_secretbox_open(
plaintext, padded, len(padded), nonce, self._key,
):
raise CryptoError(
"Decryption failed. Ciphertext failed verification")
box_zeros = nacl.lib.crypto_secretbox_ZEROBYTES plaintext = nacl.c.crypto_secretbox_open(self._key, ciphertext, nonce)
plaintext = nacl.ffi.buffer(plaintext, len(padded))[box_zeros:]
return plaintext return plaintext
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment