copied from linux/crypto